mirror of
https://github.com/neovim/neovim.git
synced 2025-09-24 20:18:32 +00:00
eval: add v:event, which will contain data events want to propagate to their receivers.
Add helper functions dict_clear and dict_set_keys_readonly.
This commit is contained in:
@@ -1386,6 +1386,10 @@ v:errors Errors found by assert functions, such as |assert_true()|.
|
|||||||
< If v:errors is set to anything but a list it is made an empty
|
< If v:errors is set to anything but a list it is made an empty
|
||||||
list by the assert function.
|
list by the assert function.
|
||||||
|
|
||||||
|
*v:event* *event-variable*
|
||||||
|
v:event Dictionary of event data for the current |autocommand|. The
|
||||||
|
available keys differ per event type and are specified at the
|
||||||
|
documentation for each |event|.
|
||||||
*v:exception* *exception-variable*
|
*v:exception* *exception-variable*
|
||||||
v:exception The value of the exception most recently caught and not
|
v:exception The value of the exception most recently caught and not
|
||||||
finished. See also |v:throwpoint| and |throw-variables|.
|
finished. See also |v:throwpoint| and |throw-variables|.
|
||||||
|
@@ -378,6 +378,7 @@ static struct vimvar {
|
|||||||
{ VV_NAME("option_type", VAR_STRING), VV_RO },
|
{ VV_NAME("option_type", VAR_STRING), VV_RO },
|
||||||
{ VV_NAME("errors", VAR_LIST), 0 },
|
{ VV_NAME("errors", VAR_LIST), 0 },
|
||||||
{ VV_NAME("msgpack_types", VAR_DICT), VV_RO },
|
{ VV_NAME("msgpack_types", VAR_DICT), VV_RO },
|
||||||
|
{ VV_NAME("event", VAR_DICT), VV_RO },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* shorthand */
|
/* shorthand */
|
||||||
@@ -545,6 +546,10 @@ void eval_init(void)
|
|||||||
|
|
||||||
set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict);
|
set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict);
|
||||||
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
|
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
|
||||||
|
|
||||||
|
dict_T *v_event = dict_alloc();
|
||||||
|
v_event->dv_lock = VAR_FIXED;
|
||||||
|
set_vim_var_dict(VV_EVENT, v_event);
|
||||||
set_vim_var_list(VV_ERRORS, list_alloc());
|
set_vim_var_list(VV_ERRORS, list_alloc());
|
||||||
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
|
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
|
||||||
set_vim_var_nr(VV_HLSEARCH, 1L);
|
set_vim_var_nr(VV_HLSEARCH, 1L);
|
||||||
@@ -6017,6 +6022,27 @@ static void rettv_dict_alloc(typval_T *rettv)
|
|||||||
++d->dv_refcount;
|
++d->dv_refcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
|
||||||
|
///
|
||||||
|
/// @param d The Dictionary to clear
|
||||||
|
void dict_clear(dict_T *d)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
hash_lock(&d->dv_hashtab);
|
||||||
|
assert(d->dv_hashtab.ht_locked > 0);
|
||||||
|
|
||||||
|
size_t todo = d->dv_hashtab.ht_used;
|
||||||
|
for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) {
|
||||||
|
if (!HASHITEM_EMPTY(hi)) {
|
||||||
|
dictitem_free(HI2DI(hi));
|
||||||
|
hash_remove(&d->dv_hashtab, hi);
|
||||||
|
todo--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_unlock(&d->dv_hashtab);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unreference a Dictionary: decrement the reference count and free it when it
|
* Unreference a Dictionary: decrement the reference count and free it when it
|
||||||
@@ -6258,6 +6284,24 @@ int dict_add_list(dict_T *d, char *key, list_T *list)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set all existing keys in "dict" as read-only.
|
||||||
|
///
|
||||||
|
/// This does not protect against adding new keys to the Dictionary.
|
||||||
|
///
|
||||||
|
/// @param dict The dict whose keys should be frozen
|
||||||
|
void dict_set_keys_readonly(dict_T *dict)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
size_t todo = dict->dv_hashtab.ht_used;
|
||||||
|
for (hashitem_T *hi = dict->dv_hashtab.ht_array; todo > 0 ; hi++) {
|
||||||
|
if (HASHITEM_EMPTY(hi)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
todo--;
|
||||||
|
HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the number of items in a Dictionary.
|
* Get the number of items in a Dictionary.
|
||||||
*/
|
*/
|
||||||
@@ -18162,14 +18206,7 @@ void set_vim_var_dict(int idx, dict_T *val)
|
|||||||
if (val != NULL) {
|
if (val != NULL) {
|
||||||
++val->dv_refcount;
|
++val->dv_refcount;
|
||||||
// Set readonly
|
// Set readonly
|
||||||
size_t todo = val->dv_hashtab.ht_used;
|
dict_set_keys_readonly(val);
|
||||||
for (hashitem_T *hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) {
|
|
||||||
if (HASHITEM_EMPTY(hi)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
--todo;
|
|
||||||
HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -113,7 +113,8 @@ enum {
|
|||||||
VV_OPTION_TYPE,
|
VV_OPTION_TYPE,
|
||||||
VV_ERRORS,
|
VV_ERRORS,
|
||||||
VV_MSGPACK_TYPES,
|
VV_MSGPACK_TYPES,
|
||||||
VV_LEN, /* number of v: vars */
|
VV_EVENT,
|
||||||
|
VV_LEN, // number of v: vars
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Maximum number of function arguments
|
/// Maximum number of function arguments
|
||||||
|
15
test/functional/eval/vvar_event_spec.lua
Normal file
15
test/functional/eval/vvar_event_spec.lua
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
local helpers = require('test.functional.helpers')
|
||||||
|
local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
|
||||||
|
local command = helpers.command
|
||||||
|
describe('v:event', function()
|
||||||
|
before_each(clear)
|
||||||
|
it('is empty before any autocommand', function()
|
||||||
|
eq({}, eval('v:event'))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('is immutable', function()
|
||||||
|
eq(false, pcall(command, 'let v:event = {}'))
|
||||||
|
eq(false, pcall(command, 'let v:event.mykey = {}'))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
Reference in New Issue
Block a user