Permalink
Browse files

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)
  • Loading branch information...
brammool committed Feb 17, 2017
1 parent 226c534 commit 79518e2ace5fce7b9c49060e462a6e935dba0a84
View
@@ -2099,6 +2099,7 @@ test_arglist \
test_cdo \
test_channel \
test_charsearch \
+ test_changedtick \
test_cmdline \
test_command_count \
test_crypt \
View
@@ -832,6 +832,7 @@ free_buffer(buf_T *buf)
free_buffer_stuff(buf, TRUE);
#ifdef FEAT_EVAL
unref_var_dict(buf->b_vars);
+ buf->b_changedtick = &buf->b_ct_val;
#endif
#ifdef FEAT_LUA
lua_buffer_free(buf);
@@ -872,6 +873,29 @@ free_buffer(buf_T *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.
*/
@@ -889,8 +913,14 @@ free_buffer_stuff(
#endif
}
#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
#ifdef FEAT_USR_CMDS
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);
#endif
+ init_changedtick(buf);
}
if (ffname != NULL)
View
@@ -1668,7 +1668,7 @@ ins_redraw(
#ifdef FEAT_AUTOCMD
/* Trigger TextChangedI if b_changedtick differs. */
if (ready && has_textchangedI()
- && last_changedtick != curbuf->b_changedtick
+ && last_changedtick != *curbuf->b_changedtick
# ifdef FEAT_INS_EXPAND
&& !pum_visible()
# endif
@@ -1677,7 +1677,7 @@ ins_redraw(
if (last_changedtick_buf == curbuf)
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
last_changedtick_buf = curbuf;
- last_changedtick = curbuf->b_changedtick;
+ last_changedtick = *curbuf->b_changedtick;
}
#endif
View
@@ -1451,14 +1451,8 @@ list_glob_vars(int *first)
static void
list_buf_vars(int *first)
{
- char_u numbuf[NUMBUFLEN];
-
list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
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;
}
-/*
- * 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
* 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 (!check_changedtick(lp->ll_name))
+ cc = *endp;
+ *endp = NUL;
+ if (op != NULL && *op != '=')
{
- cc = *endp;
- *endp = NUL;
- if (op != NULL && *op != '=')
- {
- typval_T tv;
+ typval_T tv;
- /* handle +=, -= and .= */
- di = NULL;
- if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
- &tv, &di, TRUE, FALSE) == OK)
- {
- if ((di == NULL
- || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
- && !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
- FALSE)))
- && tv_op(&tv, rettv, op) == OK)
- set_var(lp->ll_name, &tv, FALSE);
- clear_tv(&tv);
- }
+ /* handle +=, -= and .= */
+ di = NULL;
+ if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
+ &tv, &di, TRUE, FALSE) == OK)
+ {
+ if ((di == NULL
+ || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
+ && !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
+ FALSE)))
+ && tv_op(&tv, rettv, op) == OK)
+ set_var(lp->ll_name, &tv, FALSE);
+ 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
? lp->ll_tv->v_lock
@@ -2776,9 +2753,7 @@ do_unlet_var(
*name_end = NUL;
/* Normal name or expanded name. */
- if (check_changedtick(lp->ll_name))
- ret = FAIL;
- else if (do_unlet(lp->ll_name, forceit) == FAIL)
+ if (do_unlet(lp->ll_name, forceit) == FAIL)
ret = FAIL;
*name_end = cc;
}
@@ -2904,21 +2879,16 @@ do_lock_var(
*name_end = NUL;
/* Normal name or expanded name. */
- if (check_changedtick(lp->ll_name))
+ di = find_var(lp->ll_name, NULL, TRUE);
+ if (di == NULL)
ret = FAIL;
else
{
- di = find_var(lp->ll_name, NULL, TRUE);
- if (di == NULL)
- ret = FAIL;
+ if (lock)
+ di->di_flags |= DI_FLAGS_LOCK;
else
- {
- if (lock)
- di->di_flags |= DI_FLAGS_LOCK;
- else
- di->di_flags &= ~DI_FLAGS_LOCK;
- item_lock(&di->di_tv, deep, lock);
- }
+ di->di_flags &= ~DI_FLAGS_LOCK;
+ item_lock(&di->di_tv, deep, lock);
}
*name_end = cc;
}
@@ -3139,11 +3109,6 @@ get_user_var_name(expand_T *xp, int idx)
++hi;
return cat_prefix_varname('b', hi->hi_key);
}
- if (bdone == ht->ht_used)
- {
- ++bdone;
- return (char_u *)"b:changedtick";
- }
/* w: variables */
ht = &curwin->w_vars->dv_hashtab;
@@ -6815,36 +6780,22 @@ get_var_tv(
{
int ret = OK;
typval_T *tv = NULL;
- typval_T atv;
dictitem_T *v;
int cc;
/* truncate the name, so that we can use strcmp() */
cc = name[len];
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.
*/
- else
+ v = find_var(name, NULL, no_autoload);
+ if (v != NULL)
{
- v = find_var(name, NULL, no_autoload);
- if (v != NULL)
- {
- tv = &v->di_tv;
- if (dip != NULL)
- *dip = v;
- }
+ tv = &v->di_tv;
+ if (dip != NULL)
+ *dip = v;
}
if (tv == NULL)
View
@@ -2539,7 +2539,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
#ifdef FEAT_DIFF
linenr_T lnum = get_tv_lnum(argvars);
static linenr_T prev_lnum = 0;
- static int changedtick = 0;
+ static varnumber_T changedtick = 0;
static int fnum = 0;
static int change_start = 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 */
lnum = 0;
if (lnum != prev_lnum
- || changedtick != curbuf->b_changedtick
+ || changedtick != *curbuf->b_changedtick
|| fnum != curbuf->b_fnum)
{
/* 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
hlID = (hlf_T)0;
prev_lnum = lnum;
- changedtick = curbuf->b_changedtick;
+ changedtick = *curbuf->b_changedtick;
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, "listed", buf->b_p_bl, 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",
buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
NULL);
@@ -4190,12 +4190,6 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
/* buffer-local-option */
done = TRUE;
}
- else if (STRCMP(varname, "changedtick") == 0)
- {
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = curbuf->b_changedtick;
- done = TRUE;
- }
else
{
/* Look up the variable. */
@@ -6576,21 +6570,16 @@ f_islocked(typval_T *argvars, typval_T *rettv)
{
if (lv.ll_tv == NULL)
{
- if (check_changedtick(lv.ll_name))
- rettv->vval.v_number = 1; /* always locked */
- else
+ di = find_var(lv.ll_name, NULL, TRUE);
+ if (di != NULL)
{
- di = find_var(lv.ll_name, NULL, TRUE);
- if (di != NULL)
- {
- /* Consider a variable locked when:
- * 1. the variable itself is locked
- * 2. the value of the variable is locked.
- * 3. the List or Dict value is locked.
- */
- rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
- || tv_islocked(&di->di_tv));
- }
+ /* Consider a variable locked when:
+ * 1. the variable itself is locked
+ * 2. the value of the variable is locked.
+ * 3. the List or Dict value is locked.
+ */
+ rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
+ || tv_islocked(&di->di_tv));
}
}
else if (lv.ll_range)
@@ -11551,8 +11540,8 @@ f_submatch(typval_T *argvars, typval_T *rettv)
return;
if (no < 0 || no >= NSUBEXP)
{
- EMSGN(_("E935: invalid submatch number: %d"), no);
- return;
+ EMSGN(_("E935: invalid submatch number: %d"), no);
+ return;
}
if (argvars[1].v_type != VAR_UNKNOWN)
retList = (int)get_tv_number_chk(&argvars[1], &error);
View
@@ -626,7 +626,7 @@ do_exmode(
int save_msg_scroll;
int prev_msg_row;
linenr_T prev_line;
- int changedtick;
+ varnumber_T changedtick;
if (improved)
exmode_active = EXMODE_VIM;
@@ -660,7 +660,7 @@ do_exmode(
need_wait_return = FALSE;
ex_pressedreturn = FALSE;
ex_no_reprint = FALSE;
- changedtick = curbuf->b_changedtick;
+ changedtick = *curbuf->b_changedtick;
prev_msg_row = msg_row;
prev_line = curwin->w_cursor.lnum;
if (improved)
@@ -673,7 +673,7 @@ do_exmode(
lines_left = Rows - 1;
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)
EMSG(_(e_emptybuf));
View
@@ -4926,9 +4926,9 @@ buf_write(
#ifdef FEAT_AUTOCMD
/* buf->b_changedtick is always incremented in unchanged() but that
* 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->b_changedtick;
+ last_changedtick = *buf->b_changedtick;
#endif
u_unchanged(buf);
u_update_save_nr(buf);
Oops, something went wrong.

0 comments on commit 79518e2

Please sign in to comment.