mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.0.0334: can't access b:changedtick from a dict reference
Problem: Can't access b:changedtick from a dict reference. Solution: Make changedtick a member of the b: dict. (inspired by neovim #6112)
This commit is contained in:
parent
226c534291
commit
79518e2ace
@ -2099,6 +2099,7 @@ test_arglist \
|
|||||||
test_cdo \
|
test_cdo \
|
||||||
test_channel \
|
test_channel \
|
||||||
test_charsearch \
|
test_charsearch \
|
||||||
|
test_changedtick \
|
||||||
test_cmdline \
|
test_cmdline \
|
||||||
test_command_count \
|
test_command_count \
|
||||||
test_crypt \
|
test_crypt \
|
||||||
|
35
src/buffer.c
35
src/buffer.c
@ -832,6 +832,7 @@ free_buffer(buf_T *buf)
|
|||||||
free_buffer_stuff(buf, TRUE);
|
free_buffer_stuff(buf, TRUE);
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
unref_var_dict(buf->b_vars);
|
unref_var_dict(buf->b_vars);
|
||||||
|
buf->b_changedtick = &buf->b_ct_val;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_LUA
|
#ifdef FEAT_LUA
|
||||||
lua_buffer_free(buf);
|
lua_buffer_free(buf);
|
||||||
@ -872,6 +873,29 @@ free_buffer(buf_T *buf)
|
|||||||
vim_free(buf);
|
vim_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes buf->b_changedtick.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_changedtick(buf_T *buf)
|
||||||
|
{
|
||||||
|
#ifdef FEAT_EVAL
|
||||||
|
dictitem_T *di = dictitem_alloc((char_u *)"changedtick");
|
||||||
|
|
||||||
|
if (di != NULL)
|
||||||
|
{
|
||||||
|
di->di_flags |= DI_FLAGS_LOCK | DI_FLAGS_FIX | DI_FLAGS_RO;
|
||||||
|
di->di_tv.v_type = VAR_NUMBER;
|
||||||
|
di->di_tv.v_lock = VAR_FIXED;
|
||||||
|
di->di_tv.vval.v_number = 0;
|
||||||
|
dict_add(buf->b_vars, di);
|
||||||
|
buf->b_changedtick = &di->di_tv.vval.v_number;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
buf->b_changedtick = &buf->b_ct_val;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free stuff in the buffer for ":bdel" and when wiping out the buffer.
|
* Free stuff in the buffer for ":bdel" and when wiping out the buffer.
|
||||||
*/
|
*/
|
||||||
@ -889,8 +913,14 @@ free_buffer_stuff(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
vars_clear(&buf->b_vars->dv_hashtab); /* free all internal variables */
|
{
|
||||||
hash_init(&buf->b_vars->dv_hashtab);
|
varnumber_T tick = *buf->b_changedtick;
|
||||||
|
|
||||||
|
vars_clear(&buf->b_vars->dv_hashtab); /* free all buffer variables */
|
||||||
|
hash_init(&buf->b_vars->dv_hashtab);
|
||||||
|
init_changedtick(buf);
|
||||||
|
*buf->b_changedtick = tick;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_USR_CMDS
|
#ifdef FEAT_USR_CMDS
|
||||||
uc_clear(&buf->b_ucmds); /* clear local user commands */
|
uc_clear(&buf->b_ucmds); /* clear local user commands */
|
||||||
@ -1979,6 +2009,7 @@ buflist_new(
|
|||||||
}
|
}
|
||||||
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
|
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
|
||||||
#endif
|
#endif
|
||||||
|
init_changedtick(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffname != NULL)
|
if (ffname != NULL)
|
||||||
|
@ -1668,7 +1668,7 @@ ins_redraw(
|
|||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* Trigger TextChangedI if b_changedtick differs. */
|
/* Trigger TextChangedI if b_changedtick differs. */
|
||||||
if (ready && has_textchangedI()
|
if (ready && has_textchangedI()
|
||||||
&& last_changedtick != curbuf->b_changedtick
|
&& last_changedtick != *curbuf->b_changedtick
|
||||||
# ifdef FEAT_INS_EXPAND
|
# ifdef FEAT_INS_EXPAND
|
||||||
&& !pum_visible()
|
&& !pum_visible()
|
||||||
# endif
|
# endif
|
||||||
@ -1677,7 +1677,7 @@ ins_redraw(
|
|||||||
if (last_changedtick_buf == curbuf)
|
if (last_changedtick_buf == curbuf)
|
||||||
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
|
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
|
||||||
last_changedtick_buf = curbuf;
|
last_changedtick_buf = curbuf;
|
||||||
last_changedtick = curbuf->b_changedtick;
|
last_changedtick = *curbuf->b_changedtick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
111
src/eval.c
111
src/eval.c
@ -1451,14 +1451,8 @@ list_glob_vars(int *first)
|
|||||||
static void
|
static void
|
||||||
list_buf_vars(int *first)
|
list_buf_vars(int *first)
|
||||||
{
|
{
|
||||||
char_u numbuf[NUMBUFLEN];
|
|
||||||
|
|
||||||
list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
|
list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
|
||||||
TRUE, first);
|
TRUE, first);
|
||||||
|
|
||||||
sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
|
|
||||||
list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
|
|
||||||
numbuf, first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1805,20 +1799,6 @@ ex_let_one(
|
|||||||
return arg_end;
|
return arg_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If "arg" is equal to "b:changedtick" give an error and return TRUE.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
check_changedtick(char_u *arg)
|
|
||||||
{
|
|
||||||
if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13]))
|
|
||||||
{
|
|
||||||
EMSG2(_(e_readonlyvar), arg);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get an lval: variable, Dict item or List item that can be assigned a value
|
* Get an lval: variable, Dict item or List item that can be assigned a value
|
||||||
* to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
|
* to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
|
||||||
@ -2208,32 +2188,29 @@ set_var_lval(
|
|||||||
|
|
||||||
if (lp->ll_tv == NULL)
|
if (lp->ll_tv == NULL)
|
||||||
{
|
{
|
||||||
if (!check_changedtick(lp->ll_name))
|
cc = *endp;
|
||||||
|
*endp = NUL;
|
||||||
|
if (op != NULL && *op != '=')
|
||||||
{
|
{
|
||||||
cc = *endp;
|
typval_T tv;
|
||||||
*endp = NUL;
|
|
||||||
if (op != NULL && *op != '=')
|
|
||||||
{
|
|
||||||
typval_T tv;
|
|
||||||
|
|
||||||
/* handle +=, -= and .= */
|
/* handle +=, -= and .= */
|
||||||
di = NULL;
|
di = NULL;
|
||||||
if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
|
if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
|
||||||
&tv, &di, TRUE, FALSE) == OK)
|
&tv, &di, TRUE, FALSE) == OK)
|
||||||
{
|
{
|
||||||
if ((di == NULL
|
if ((di == NULL
|
||||||
|| (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
|
|| (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
|
||||||
&& !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
|
&& !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
|
||||||
FALSE)))
|
FALSE)))
|
||||||
&& tv_op(&tv, rettv, op) == OK)
|
&& tv_op(&tv, rettv, op) == OK)
|
||||||
set_var(lp->ll_name, &tv, FALSE);
|
set_var(lp->ll_name, &tv, FALSE);
|
||||||
clear_tv(&tv);
|
clear_tv(&tv);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
set_var(lp->ll_name, rettv, copy);
|
|
||||||
*endp = cc;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
set_var(lp->ll_name, rettv, copy);
|
||||||
|
*endp = cc;
|
||||||
}
|
}
|
||||||
else if (tv_check_lock(lp->ll_newkey == NULL
|
else if (tv_check_lock(lp->ll_newkey == NULL
|
||||||
? lp->ll_tv->v_lock
|
? lp->ll_tv->v_lock
|
||||||
@ -2776,9 +2753,7 @@ do_unlet_var(
|
|||||||
*name_end = NUL;
|
*name_end = NUL;
|
||||||
|
|
||||||
/* Normal name or expanded name. */
|
/* Normal name or expanded name. */
|
||||||
if (check_changedtick(lp->ll_name))
|
if (do_unlet(lp->ll_name, forceit) == FAIL)
|
||||||
ret = FAIL;
|
|
||||||
else if (do_unlet(lp->ll_name, forceit) == FAIL)
|
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
*name_end = cc;
|
*name_end = cc;
|
||||||
}
|
}
|
||||||
@ -2904,21 +2879,16 @@ do_lock_var(
|
|||||||
*name_end = NUL;
|
*name_end = NUL;
|
||||||
|
|
||||||
/* Normal name or expanded name. */
|
/* Normal name or expanded name. */
|
||||||
if (check_changedtick(lp->ll_name))
|
di = find_var(lp->ll_name, NULL, TRUE);
|
||||||
|
if (di == NULL)
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
di = find_var(lp->ll_name, NULL, TRUE);
|
if (lock)
|
||||||
if (di == NULL)
|
di->di_flags |= DI_FLAGS_LOCK;
|
||||||
ret = FAIL;
|
|
||||||
else
|
else
|
||||||
{
|
di->di_flags &= ~DI_FLAGS_LOCK;
|
||||||
if (lock)
|
item_lock(&di->di_tv, deep, lock);
|
||||||
di->di_flags |= DI_FLAGS_LOCK;
|
|
||||||
else
|
|
||||||
di->di_flags &= ~DI_FLAGS_LOCK;
|
|
||||||
item_lock(&di->di_tv, deep, lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*name_end = cc;
|
*name_end = cc;
|
||||||
}
|
}
|
||||||
@ -3139,11 +3109,6 @@ get_user_var_name(expand_T *xp, int idx)
|
|||||||
++hi;
|
++hi;
|
||||||
return cat_prefix_varname('b', hi->hi_key);
|
return cat_prefix_varname('b', hi->hi_key);
|
||||||
}
|
}
|
||||||
if (bdone == ht->ht_used)
|
|
||||||
{
|
|
||||||
++bdone;
|
|
||||||
return (char_u *)"b:changedtick";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* w: variables */
|
/* w: variables */
|
||||||
ht = &curwin->w_vars->dv_hashtab;
|
ht = &curwin->w_vars->dv_hashtab;
|
||||||
@ -6815,7 +6780,6 @@ get_var_tv(
|
|||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
typval_T *tv = NULL;
|
typval_T *tv = NULL;
|
||||||
typval_T atv;
|
|
||||||
dictitem_T *v;
|
dictitem_T *v;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
@ -6823,28 +6787,15 @@ get_var_tv(
|
|||||||
cc = name[len];
|
cc = name[len];
|
||||||
name[len] = NUL;
|
name[len] = NUL;
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for "b:changedtick".
|
|
||||||
*/
|
|
||||||
if (STRCMP(name, "b:changedtick") == 0)
|
|
||||||
{
|
|
||||||
atv.v_type = VAR_NUMBER;
|
|
||||||
atv.vval.v_number = curbuf->b_changedtick;
|
|
||||||
tv = &atv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for user-defined variables.
|
* Check for user-defined variables.
|
||||||
*/
|
*/
|
||||||
else
|
v = find_var(name, NULL, no_autoload);
|
||||||
|
if (v != NULL)
|
||||||
{
|
{
|
||||||
v = find_var(name, NULL, no_autoload);
|
tv = &v->di_tv;
|
||||||
if (v != NULL)
|
if (dip != NULL)
|
||||||
{
|
*dip = v;
|
||||||
tv = &v->di_tv;
|
|
||||||
if (dip != NULL)
|
|
||||||
*dip = v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tv == NULL)
|
if (tv == NULL)
|
||||||
|
@ -2539,7 +2539,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
linenr_T lnum = get_tv_lnum(argvars);
|
linenr_T lnum = get_tv_lnum(argvars);
|
||||||
static linenr_T prev_lnum = 0;
|
static linenr_T prev_lnum = 0;
|
||||||
static int changedtick = 0;
|
static varnumber_T changedtick = 0;
|
||||||
static int fnum = 0;
|
static int fnum = 0;
|
||||||
static int change_start = 0;
|
static int change_start = 0;
|
||||||
static int change_end = 0;
|
static int change_end = 0;
|
||||||
@ -2550,7 +2550,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
if (lnum < 0) /* ignore type error in {lnum} arg */
|
if (lnum < 0) /* ignore type error in {lnum} arg */
|
||||||
lnum = 0;
|
lnum = 0;
|
||||||
if (lnum != prev_lnum
|
if (lnum != prev_lnum
|
||||||
|| changedtick != curbuf->b_changedtick
|
|| changedtick != *curbuf->b_changedtick
|
||||||
|| fnum != curbuf->b_fnum)
|
|| fnum != curbuf->b_fnum)
|
||||||
{
|
{
|
||||||
/* New line, buffer, change: need to get the values. */
|
/* New line, buffer, change: need to get the values. */
|
||||||
@ -2572,7 +2572,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
else
|
else
|
||||||
hlID = (hlf_T)0;
|
hlID = (hlf_T)0;
|
||||||
prev_lnum = lnum;
|
prev_lnum = lnum;
|
||||||
changedtick = curbuf->b_changedtick;
|
changedtick = *curbuf->b_changedtick;
|
||||||
fnum = curbuf->b_fnum;
|
fnum = curbuf->b_fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3957,7 +3957,7 @@ get_buffer_info(buf_T *buf)
|
|||||||
dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
|
dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
|
||||||
dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
|
dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
|
||||||
dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
|
dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
|
||||||
dict_add_nr_str(dict, "changedtick", buf->b_changedtick, NULL);
|
dict_add_nr_str(dict, "changedtick", *buf->b_changedtick, NULL);
|
||||||
dict_add_nr_str(dict, "hidden",
|
dict_add_nr_str(dict, "hidden",
|
||||||
buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
|
buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
|
||||||
NULL);
|
NULL);
|
||||||
@ -4190,12 +4190,6 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
|
|||||||
/* buffer-local-option */
|
/* buffer-local-option */
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
}
|
}
|
||||||
else if (STRCMP(varname, "changedtick") == 0)
|
|
||||||
{
|
|
||||||
rettv->v_type = VAR_NUMBER;
|
|
||||||
rettv->vval.v_number = curbuf->b_changedtick;
|
|
||||||
done = TRUE;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Look up the variable. */
|
/* Look up the variable. */
|
||||||
@ -6576,21 +6570,16 @@ f_islocked(typval_T *argvars, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
if (lv.ll_tv == NULL)
|
if (lv.ll_tv == NULL)
|
||||||
{
|
{
|
||||||
if (check_changedtick(lv.ll_name))
|
di = find_var(lv.ll_name, NULL, TRUE);
|
||||||
rettv->vval.v_number = 1; /* always locked */
|
if (di != NULL)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
di = find_var(lv.ll_name, NULL, TRUE);
|
/* Consider a variable locked when:
|
||||||
if (di != NULL)
|
* 1. the variable itself is locked
|
||||||
{
|
* 2. the value of the variable is locked.
|
||||||
/* Consider a variable locked when:
|
* 3. the List or Dict value is locked.
|
||||||
* 1. the variable itself is locked
|
*/
|
||||||
* 2. the value of the variable is locked.
|
rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
|
||||||
* 3. the List or Dict value is locked.
|
|| tv_islocked(&di->di_tv));
|
||||||
*/
|
|
||||||
rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
|
|
||||||
|| tv_islocked(&di->di_tv));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lv.ll_range)
|
else if (lv.ll_range)
|
||||||
@ -11551,8 +11540,8 @@ f_submatch(typval_T *argvars, typval_T *rettv)
|
|||||||
return;
|
return;
|
||||||
if (no < 0 || no >= NSUBEXP)
|
if (no < 0 || no >= NSUBEXP)
|
||||||
{
|
{
|
||||||
EMSGN(_("E935: invalid submatch number: %d"), no);
|
EMSGN(_("E935: invalid submatch number: %d"), no);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||||
retList = (int)get_tv_number_chk(&argvars[1], &error);
|
retList = (int)get_tv_number_chk(&argvars[1], &error);
|
||||||
|
@ -626,7 +626,7 @@ do_exmode(
|
|||||||
int save_msg_scroll;
|
int save_msg_scroll;
|
||||||
int prev_msg_row;
|
int prev_msg_row;
|
||||||
linenr_T prev_line;
|
linenr_T prev_line;
|
||||||
int changedtick;
|
varnumber_T changedtick;
|
||||||
|
|
||||||
if (improved)
|
if (improved)
|
||||||
exmode_active = EXMODE_VIM;
|
exmode_active = EXMODE_VIM;
|
||||||
@ -660,7 +660,7 @@ do_exmode(
|
|||||||
need_wait_return = FALSE;
|
need_wait_return = FALSE;
|
||||||
ex_pressedreturn = FALSE;
|
ex_pressedreturn = FALSE;
|
||||||
ex_no_reprint = FALSE;
|
ex_no_reprint = FALSE;
|
||||||
changedtick = curbuf->b_changedtick;
|
changedtick = *curbuf->b_changedtick;
|
||||||
prev_msg_row = msg_row;
|
prev_msg_row = msg_row;
|
||||||
prev_line = curwin->w_cursor.lnum;
|
prev_line = curwin->w_cursor.lnum;
|
||||||
if (improved)
|
if (improved)
|
||||||
@ -673,7 +673,7 @@ do_exmode(
|
|||||||
lines_left = Rows - 1;
|
lines_left = Rows - 1;
|
||||||
|
|
||||||
if ((prev_line != curwin->w_cursor.lnum
|
if ((prev_line != curwin->w_cursor.lnum
|
||||||
|| changedtick != curbuf->b_changedtick) && !ex_no_reprint)
|
|| changedtick != *curbuf->b_changedtick) && !ex_no_reprint)
|
||||||
{
|
{
|
||||||
if (curbuf->b_ml.ml_flags & ML_EMPTY)
|
if (curbuf->b_ml.ml_flags & ML_EMPTY)
|
||||||
EMSG(_(e_emptybuf));
|
EMSG(_(e_emptybuf));
|
||||||
|
@ -4926,9 +4926,9 @@ restore_backup:
|
|||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* buf->b_changedtick is always incremented in unchanged() but that
|
/* buf->b_changedtick is always incremented in unchanged() but that
|
||||||
* should not trigger a TextChanged event. */
|
* should not trigger a TextChanged event. */
|
||||||
if (last_changedtick + 1 == buf->b_changedtick
|
if (last_changedtick + 1 == *buf->b_changedtick
|
||||||
&& last_changedtick_buf == buf)
|
&& last_changedtick_buf == buf)
|
||||||
last_changedtick = buf->b_changedtick;
|
last_changedtick = *buf->b_changedtick;
|
||||||
#endif
|
#endif
|
||||||
u_unchanged(buf);
|
u_unchanged(buf);
|
||||||
u_update_save_nr(buf);
|
u_update_save_nr(buf);
|
||||||
|
@ -1088,7 +1088,7 @@ EXTERN pos_T last_cursormoved /* for CursorMoved event */
|
|||||||
= INIT_POS_T(0, 0, 0)
|
= INIT_POS_T(0, 0, 0)
|
||||||
# endif
|
# endif
|
||||||
;
|
;
|
||||||
EXTERN int last_changedtick INIT(= 0); /* for TextChanged event */
|
EXTERN varnumber_T last_changedtick INIT(= 0); /* for TextChanged event */
|
||||||
EXTERN buf_T *last_changedtick_buf INIT(= NULL);
|
EXTERN buf_T *last_changedtick_buf INIT(= NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1164,13 +1164,13 @@ main_loop(
|
|||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* Trigger TextChanged if b_changedtick differs. */
|
/* Trigger TextChanged if b_changedtick differs. */
|
||||||
if (!finish_op && has_textchanged()
|
if (!finish_op && has_textchanged()
|
||||||
&& last_changedtick != curbuf->b_changedtick)
|
&& last_changedtick != *curbuf->b_changedtick)
|
||||||
{
|
{
|
||||||
if (last_changedtick_buf == curbuf)
|
if (last_changedtick_buf == curbuf)
|
||||||
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
|
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
|
||||||
FALSE, curbuf);
|
FALSE, curbuf);
|
||||||
last_changedtick_buf = curbuf;
|
last_changedtick_buf = curbuf;
|
||||||
last_changedtick = curbuf->b_changedtick;
|
last_changedtick = *curbuf->b_changedtick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1388,11 +1388,11 @@ getout(int exitval)
|
|||||||
/* Autocmd must have close the buffer already, skip. */
|
/* Autocmd must have close the buffer already, skip. */
|
||||||
continue;
|
continue;
|
||||||
buf = wp->w_buffer;
|
buf = wp->w_buffer;
|
||||||
if (buf->b_changedtick != -1)
|
if (buf->b_ct_val != -1)
|
||||||
{
|
{
|
||||||
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
|
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
|
||||||
buf->b_fname, FALSE, buf);
|
buf->b_fname, FALSE, buf);
|
||||||
buf->b_changedtick = -1; /* note that we did it already */
|
buf->b_ct_val = -1; /* note that we did it already */
|
||||||
/* start all over, autocommands may mess up the lists */
|
/* start all over, autocommands may mess up the lists */
|
||||||
next_tp = first_tabpage;
|
next_tp = first_tabpage;
|
||||||
break;
|
break;
|
||||||
|
@ -1148,11 +1148,11 @@ ml_recover(void)
|
|||||||
len = (int)STRLEN(fname);
|
len = (int)STRLEN(fname);
|
||||||
if (len >= 4 &&
|
if (len >= 4 &&
|
||||||
#if defined(VMS)
|
#if defined(VMS)
|
||||||
STRNICMP(fname + len - 4, "_s" , 2)
|
STRNICMP(fname + len - 4, "_s", 2)
|
||||||
#else
|
#else
|
||||||
STRNICMP(fname + len - 4, ".s" , 2)
|
STRNICMP(fname + len - 4, ".s", 2)
|
||||||
#endif
|
#endif
|
||||||
== 0
|
== 0
|
||||||
&& vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
|
&& vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
|
||||||
&& ASCII_ISALPHA(fname[len - 1]))
|
&& ASCII_ISALPHA(fname[len - 1]))
|
||||||
{
|
{
|
||||||
@ -1649,7 +1649,7 @@ ml_recover(void)
|
|||||||
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
|
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
|
||||||
{
|
{
|
||||||
changed_int();
|
changed_int();
|
||||||
++curbuf->b_changedtick;
|
++*curbuf->b_changedtick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1663,7 +1663,7 @@ ml_recover(void)
|
|||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
changed_int();
|
changed_int();
|
||||||
++curbuf->b_changedtick;
|
++*curbuf->b_changedtick;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
src/misc1.c
10
src/misc1.c
@ -492,7 +492,7 @@ get_breakindent_win(
|
|||||||
static int prev_indent = 0; /* cached indent value */
|
static int prev_indent = 0; /* cached indent value */
|
||||||
static long prev_ts = 0L; /* cached tabstop value */
|
static long prev_ts = 0L; /* cached tabstop value */
|
||||||
static char_u *prev_line = NULL; /* cached pointer to line */
|
static char_u *prev_line = NULL; /* cached pointer to line */
|
||||||
static int prev_tick = 0; /* changedtick of cached value */
|
static varnumber_T prev_tick = 0; /* changedtick of cached value */
|
||||||
int bri = 0;
|
int bri = 0;
|
||||||
/* window width minus window margin space, i.e. what rests for text */
|
/* window width minus window margin space, i.e. what rests for text */
|
||||||
const int eff_wwidth = W_WIDTH(wp)
|
const int eff_wwidth = W_WIDTH(wp)
|
||||||
@ -502,11 +502,11 @@ get_breakindent_win(
|
|||||||
|
|
||||||
/* used cached indent, unless pointer or 'tabstop' changed */
|
/* used cached indent, unless pointer or 'tabstop' changed */
|
||||||
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
||||||
|| prev_tick != wp->w_buffer->b_changedtick)
|
|| prev_tick != *wp->w_buffer->b_changedtick)
|
||||||
{
|
{
|
||||||
prev_line = line;
|
prev_line = line;
|
||||||
prev_ts = wp->w_buffer->b_p_ts;
|
prev_ts = wp->w_buffer->b_p_ts;
|
||||||
prev_tick = wp->w_buffer->b_changedtick;
|
prev_tick = *wp->w_buffer->b_changedtick;
|
||||||
prev_indent = get_indent_str(line,
|
prev_indent = get_indent_str(line,
|
||||||
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
||||||
}
|
}
|
||||||
@ -2768,7 +2768,7 @@ changed(void)
|
|||||||
}
|
}
|
||||||
changed_int();
|
changed_int();
|
||||||
}
|
}
|
||||||
++curbuf->b_changedtick;
|
++*curbuf->b_changedtick;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3195,7 +3195,7 @@ unchanged(
|
|||||||
need_maketitle = TRUE; /* set window title later */
|
need_maketitle = TRUE; /* set window title later */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
++buf->b_changedtick;
|
++*buf->b_changedtick;
|
||||||
#ifdef FEAT_NETBEANS_INTG
|
#ifdef FEAT_NETBEANS_INTG
|
||||||
netbeans_unmodified(buf);
|
netbeans_unmodified(buf);
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,7 +25,6 @@ void *call_func_retlist(char_u *func, int argc, char_u **argv, int safe);
|
|||||||
int eval_foldexpr(char_u *arg, int *cp);
|
int eval_foldexpr(char_u *arg, int *cp);
|
||||||
void ex_let(exarg_T *eap);
|
void ex_let(exarg_T *eap);
|
||||||
void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
|
void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
|
||||||
int check_changedtick(char_u *arg);
|
|
||||||
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
|
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
|
||||||
void clear_lval(lval_T *lp);
|
void clear_lval(lval_T *lp);
|
||||||
void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip);
|
void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip);
|
||||||
|
@ -1916,7 +1916,9 @@ struct file_buffer
|
|||||||
|
|
||||||
int b_changed; /* 'modified': Set to TRUE if something in the
|
int b_changed; /* 'modified': Set to TRUE if something in the
|
||||||
file has been changed and not written out. */
|
file has been changed and not written out. */
|
||||||
int b_changedtick; /* incremented for each change, also for undo */
|
varnumber_T *b_changedtick; /* points into b:changedtick or b_ct_val;
|
||||||
|
incremented for each change, also for undo */
|
||||||
|
varnumber_T b_ct_val; /* fallback for b:changedtick */
|
||||||
|
|
||||||
int b_saving; /* Set to TRUE if we are in the middle of
|
int b_saving; /* Set to TRUE if we are in the middle of
|
||||||
saving the buffer. */
|
saving the buffer. */
|
||||||
|
@ -503,7 +503,7 @@ syntax_start(win_T *wp, linenr_T lnum)
|
|||||||
linenr_T parsed_lnum;
|
linenr_T parsed_lnum;
|
||||||
linenr_T first_stored;
|
linenr_T first_stored;
|
||||||
int dist;
|
int dist;
|
||||||
static int changedtick = 0; /* remember the last change ID */
|
static varnumber_T changedtick = 0; /* remember the last change ID */
|
||||||
|
|
||||||
#ifdef FEAT_CONCEAL
|
#ifdef FEAT_CONCEAL
|
||||||
current_sub_char = NUL;
|
current_sub_char = NUL;
|
||||||
@ -516,13 +516,13 @@ syntax_start(win_T *wp, linenr_T lnum)
|
|||||||
*/
|
*/
|
||||||
if (syn_block != wp->w_s
|
if (syn_block != wp->w_s
|
||||||
|| syn_buf != wp->w_buffer
|
|| syn_buf != wp->w_buffer
|
||||||
|| changedtick != syn_buf->b_changedtick)
|
|| changedtick != *syn_buf->b_changedtick)
|
||||||
{
|
{
|
||||||
invalidate_current_state();
|
invalidate_current_state();
|
||||||
syn_buf = wp->w_buffer;
|
syn_buf = wp->w_buffer;
|
||||||
syn_block = wp->w_s;
|
syn_block = wp->w_s;
|
||||||
}
|
}
|
||||||
changedtick = syn_buf->b_changedtick;
|
changedtick = *syn_buf->b_changedtick;
|
||||||
syn_win = wp;
|
syn_win = wp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar().
|
Tests for getwinvar(), gettabvar() and gettabwinvar().
|
||||||
vim: set ft=vim :
|
vim: set ft=vim :
|
||||||
|
|
||||||
STARTTEST
|
STARTTEST
|
||||||
@ -10,34 +10,7 @@ STARTTEST
|
|||||||
:let t:testvar='abcd'
|
:let t:testvar='abcd'
|
||||||
:$put =string(gettabvar(1,'testvar'))
|
:$put =string(gettabvar(1,'testvar'))
|
||||||
:$put =string(gettabvar(1,'testvar'))
|
:$put =string(gettabvar(1,'testvar'))
|
||||||
:" Test for getbufvar()
|
|
||||||
:let b:var_num = '1234'
|
|
||||||
:let def_num = '5678'
|
|
||||||
:$put =string(getbufvar(1, 'var_num'))
|
|
||||||
:$put =string(getbufvar(1, 'var_num', def_num))
|
|
||||||
:$put =string(getbufvar(1, ''))
|
|
||||||
:$put =string(getbufvar(1, '', def_num))
|
|
||||||
:unlet b:var_num
|
|
||||||
:$put =string(getbufvar(1, 'var_num', def_num))
|
|
||||||
:$put =string(getbufvar(1, ''))
|
|
||||||
:$put =string(getbufvar(1, '', def_num))
|
|
||||||
:$put =string(getbufvar(9, ''))
|
|
||||||
:$put =string(getbufvar(9, '', def_num))
|
|
||||||
:unlet def_num
|
|
||||||
:$put =string(getbufvar(1, '&autoindent'))
|
|
||||||
:$put =string(getbufvar(1, '&autoindent', 1))
|
|
||||||
:"
|
:"
|
||||||
:" Open new window with forced option values
|
|
||||||
:set fileformats=unix,dos
|
|
||||||
:new ++ff=dos ++bin ++enc=iso-8859-2
|
|
||||||
:let otherff = getbufvar(bufnr('%'), '&fileformat')
|
|
||||||
:let otherbin = getbufvar(bufnr('%'), '&bin')
|
|
||||||
:let otherfenc = getbufvar(bufnr('%'), '&fenc')
|
|
||||||
:close
|
|
||||||
:$put =otherff
|
|
||||||
:$put =string(otherbin)
|
|
||||||
:$put =otherfenc
|
|
||||||
:unlet otherff otherbin otherfenc
|
|
||||||
:" test for getwinvar()
|
:" test for getwinvar()
|
||||||
:let w:var_str = "Dance"
|
:let w:var_str = "Dance"
|
||||||
:let def_str = "Chance"
|
:let def_str = "Chance"
|
||||||
|
@ -1,20 +1,6 @@
|
|||||||
start:
|
start:
|
||||||
'abcd'
|
'abcd'
|
||||||
'abcd'
|
'abcd'
|
||||||
'1234'
|
|
||||||
'1234'
|
|
||||||
{'var_num': '1234'}
|
|
||||||
{'var_num': '1234'}
|
|
||||||
'5678'
|
|
||||||
{}
|
|
||||||
{}
|
|
||||||
''
|
|
||||||
'5678'
|
|
||||||
0
|
|
||||||
0
|
|
||||||
dos
|
|
||||||
1
|
|
||||||
iso-8859-2
|
|
||||||
'Dance'
|
'Dance'
|
||||||
'Dance'
|
'Dance'
|
||||||
{'var_str': 'Dance'}
|
{'var_str': 'Dance'}
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
source test_assign.vim
|
source test_assign.vim
|
||||||
source test_autocmd.vim
|
source test_autocmd.vim
|
||||||
|
source test_changedtick.vim
|
||||||
source test_cursor_func.vim
|
source test_cursor_func.vim
|
||||||
source test_delete.vim
|
source test_delete.vim
|
||||||
source test_execute_func.vim
|
|
||||||
source test_ex_undo.vim
|
source test_ex_undo.vim
|
||||||
|
source test_execute_func.vim
|
||||||
source test_expand.vim
|
source test_expand.vim
|
||||||
source test_expr.vim
|
source test_expr.vim
|
||||||
source test_expand_dllpath.vim
|
source test_expand_dllpath.vim
|
||||||
|
45
src/testdir/test_changedtick.vim
Normal file
45
src/testdir/test_changedtick.vim
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
" Tests for b:changedtick
|
||||||
|
|
||||||
|
func Test_changedtick_increments()
|
||||||
|
new
|
||||||
|
" New buffer has an empty line, tick starts at 2.
|
||||||
|
let expected = 2
|
||||||
|
call assert_equal(expected, b:changedtick)
|
||||||
|
call assert_equal(expected, b:['changedtick'])
|
||||||
|
call setline(1, 'hello')
|
||||||
|
let expected += 1
|
||||||
|
call assert_equal(expected, b:changedtick)
|
||||||
|
call assert_equal(expected, b:['changedtick'])
|
||||||
|
undo
|
||||||
|
" Somehow undo counts as two changes.
|
||||||
|
let expected += 2
|
||||||
|
call assert_equal(expected, b:changedtick)
|
||||||
|
call assert_equal(expected, b:['changedtick'])
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_changedtick_dict_entry()
|
||||||
|
let d = b:
|
||||||
|
call assert_equal(b:changedtick, d['changedtick'])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_changedtick_bdel()
|
||||||
|
new
|
||||||
|
let bnr = bufnr('%')
|
||||||
|
let v = b:changedtick
|
||||||
|
bdel
|
||||||
|
" Delete counts as a change too.
|
||||||
|
call assert_equal(v + 1, getbufvar(bnr, 'changedtick'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_changedtick_fixed()
|
||||||
|
call assert_fails('let b:changedtick = 4', 'E46')
|
||||||
|
call assert_fails('let b:["changedtick"] = 4', 'E46')
|
||||||
|
|
||||||
|
call assert_fails('unlet b:changedtick', 'E795')
|
||||||
|
call assert_fails('unlet b:["changedtick"]', 'E46')
|
||||||
|
|
||||||
|
let d = b:
|
||||||
|
call assert_fails('unlet d["changedtick"]', 'E46')
|
||||||
|
|
||||||
|
endfunc
|
@ -424,3 +424,45 @@ func! Test_mode()
|
|||||||
bwipe!
|
bwipe!
|
||||||
iunmap <F2>
|
iunmap <F2>
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_getbufvar()
|
||||||
|
let bnr = bufnr('%')
|
||||||
|
let b:var_num = '1234'
|
||||||
|
let def_num = '5678'
|
||||||
|
call assert_equal('1234', getbufvar(bnr, 'var_num'))
|
||||||
|
call assert_equal('1234', getbufvar(bnr, 'var_num', def_num))
|
||||||
|
|
||||||
|
let bd = getbufvar(bnr, '')
|
||||||
|
call assert_equal('1234', bd['var_num'])
|
||||||
|
call assert_true(exists("bd['changedtick']"))
|
||||||
|
call assert_equal(2, len(bd))
|
||||||
|
|
||||||
|
let bd2 = getbufvar(bnr, '', def_num)
|
||||||
|
call assert_equal(bd, bd2)
|
||||||
|
|
||||||
|
unlet b:var_num
|
||||||
|
call assert_equal(def_num, getbufvar(bnr, 'var_num', def_num))
|
||||||
|
call assert_equal('', getbufvar(bnr, 'var_num'))
|
||||||
|
|
||||||
|
let bd = getbufvar(bnr, '')
|
||||||
|
call assert_equal(1, len(bd))
|
||||||
|
let bd = getbufvar(bnr, '',def_num)
|
||||||
|
call assert_equal(1, len(bd))
|
||||||
|
|
||||||
|
call assert_equal('', getbufvar(9, ''))
|
||||||
|
call assert_equal(def_num, getbufvar(9, '', def_num))
|
||||||
|
unlet def_num
|
||||||
|
|
||||||
|
call assert_equal(0, getbufvar(1, '&autoindent'))
|
||||||
|
call assert_equal(0, getbufvar(1, '&autoindent', 1))
|
||||||
|
|
||||||
|
" Open new window with forced option values
|
||||||
|
set fileformats=unix,dos
|
||||||
|
new ++ff=dos ++bin ++enc=iso-8859-2
|
||||||
|
call assert_equal('dos', getbufvar(bufnr('%'), '&fileformat'))
|
||||||
|
call assert_equal(1, getbufvar(bufnr('%'), '&bin'))
|
||||||
|
call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc'))
|
||||||
|
close
|
||||||
|
|
||||||
|
set fileformats&
|
||||||
|
endfunc
|
||||||
|
@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
334,
|
||||||
/**/
|
/**/
|
||||||
333,
|
333,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user