mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 9.1.0548: it's not possible to get a unique id for some vars
Problem: it's not possible to get a unique id for some vars Solution: Add the id() Vim script function, which returns a unique identifier for object, dict, list, job, blob or channel variables (Ernie Rael) fixes: #14374 closes: #15145 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
73a810817b
commit
c8e158be0e
@@ -309,6 +309,7 @@ hlget([{name} [, {resolve}]]) List get highlight group attributes
|
|||||||
hlset({list}) Number set highlight group attributes
|
hlset({list}) Number set highlight group attributes
|
||||||
hostname() String name of the machine Vim is running on
|
hostname() String name of the machine Vim is running on
|
||||||
iconv({expr}, {from}, {to}) String convert encoding of {expr}
|
iconv({expr}, {from}, {to}) String convert encoding of {expr}
|
||||||
|
id({item}) String get address of item as a string
|
||||||
indent({lnum}) Number indent of line {lnum}
|
indent({lnum}) Number indent of line {lnum}
|
||||||
index({object}, {expr} [, {start} [, {ic}]])
|
index({object}, {expr} [, {start} [, {ic}]])
|
||||||
Number index in {object} where {expr} appears
|
Number index in {object} where {expr} appears
|
||||||
@@ -5618,6 +5619,34 @@ iconv({string}, {from}, {to}) *iconv()*
|
|||||||
Return type: |String|
|
Return type: |String|
|
||||||
|
|
||||||
|
|
||||||
|
id({item}) *id()*
|
||||||
|
The result is a unique String associated with the {item} and
|
||||||
|
not with the {item}'s contents. It is only valid while the
|
||||||
|
{item} exists and is referenced. It is valid only in the
|
||||||
|
instance of vim that produces the result. The whole idea is
|
||||||
|
that `id({item})` does not change if the contents of {item}
|
||||||
|
changes. This is useful as a `key` for creating an identity
|
||||||
|
dictionary, rather than one based on equals.
|
||||||
|
|
||||||
|
This operation does not reference {item} and there is no
|
||||||
|
function to convert the `id` to the {item}. It may be useful to
|
||||||
|
have a map of `id` to {item}. The following >
|
||||||
|
var referenceMap: dict<any>
|
||||||
|
var id = item->id()
|
||||||
|
referenceMap[id] = item
|
||||||
|
< prevents {item} from being garbage collected and provides a
|
||||||
|
way to get the {item} from the `id`.
|
||||||
|
|
||||||
|
{item} may be a List, Dictionary, Object, Job, Channel or
|
||||||
|
Blob. If the item is not a permitted type, or it is a null
|
||||||
|
value, then an empty String is returned.
|
||||||
|
|
||||||
|
Can also be used as a |method|: >
|
||||||
|
GetItem()->id()
|
||||||
|
<
|
||||||
|
Return type: |String|
|
||||||
|
|
||||||
|
|
||||||
indent({lnum}) *indent()*
|
indent({lnum}) *indent()*
|
||||||
The result is a Number, which is indent of line {lnum} in the
|
The result is a Number, which is indent of line {lnum} in the
|
||||||
current buffer. The indent is counted in spaces, the value
|
current buffer. The indent is counted in spaces, the value
|
||||||
|
@@ -8302,6 +8302,7 @@ iconise starting.txt /*iconise*
|
|||||||
iconize starting.txt /*iconize*
|
iconize starting.txt /*iconize*
|
||||||
iconv() builtin.txt /*iconv()*
|
iconv() builtin.txt /*iconv()*
|
||||||
iconv-dynamic mbyte.txt /*iconv-dynamic*
|
iconv-dynamic mbyte.txt /*iconv-dynamic*
|
||||||
|
id() builtin.txt /*id()*
|
||||||
ident-search tips.txt /*ident-search*
|
ident-search tips.txt /*ident-search*
|
||||||
idl-syntax syntax.txt /*idl-syntax*
|
idl-syntax syntax.txt /*idl-syntax*
|
||||||
idl.vim syntax.txt /*idl.vim*
|
idl.vim syntax.txt /*idl.vim*
|
||||||
|
@@ -1408,6 +1408,8 @@ Various: *various-functions*
|
|||||||
|
|
||||||
wordcount() get byte/word/char count of buffer
|
wordcount() get byte/word/char count of buffer
|
||||||
|
|
||||||
|
id() get unique string for item to use as a key
|
||||||
|
|
||||||
luaeval() evaluate |Lua| expression
|
luaeval() evaluate |Lua| expression
|
||||||
mzeval() evaluate |MzScheme| expression
|
mzeval() evaluate |MzScheme| expression
|
||||||
perleval() evaluate Perl expression (|+perl|)
|
perleval() evaluate Perl expression (|+perl|)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
*version9.txt* For Vim version 9.1. Last change: 2024 Jul 08
|
*version9.txt* For Vim version 9.1. Last change: 2024 Jul 09
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -41593,6 +41593,8 @@ Functions: ~
|
|||||||
|foreach()| apply function to List items
|
|foreach()| apply function to List items
|
||||||
|getregion()| get a region of text from a buffer
|
|getregion()| get a region of text from a buffer
|
||||||
|getregionpos()| get a list of positions for a region
|
|getregionpos()| get a list of positions for a region
|
||||||
|
|id()| get unique identifier for a Dict, List, Object,
|
||||||
|
Channel or Blob variable
|
||||||
|matchbufline()| all the matches of a pattern in a buffer
|
|matchbufline()| all the matches of a pattern in a buffer
|
||||||
|matchstrlist()| all the matches of a pattern in a List of strings
|
|matchstrlist()| all the matches of a pattern in a List of strings
|
||||||
|popup_setbuf()| switch to a different buffer in a popup
|
|popup_setbuf()| switch to a different buffer in a popup
|
||||||
|
@@ -82,6 +82,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_hlID(typval_T *argvars, typval_T *rettv);
|
static void f_hlID(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_hlexists(typval_T *argvars, typval_T *rettv);
|
static void f_hlexists(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_hostname(typval_T *argvars, typval_T *rettv);
|
static void f_hostname(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_id(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_index(typval_T *argvars, typval_T *rettv);
|
static void f_index(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_indexof(typval_T *argvars, typval_T *rettv);
|
static void f_indexof(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_input(typval_T *argvars, typval_T *rettv);
|
static void f_input(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -2207,6 +2208,8 @@ static funcentry_T global_functions[] =
|
|||||||
ret_string, f_hostname},
|
ret_string, f_hostname},
|
||||||
{"iconv", 3, 3, FEARG_1, arg3_string,
|
{"iconv", 3, 3, FEARG_1, arg3_string,
|
||||||
ret_string, f_iconv},
|
ret_string, f_iconv},
|
||||||
|
{"id", 1, 1, FEARG_1, NULL,
|
||||||
|
ret_string, f_id},
|
||||||
{"indent", 1, 1, FEARG_1, arg1_lnum,
|
{"indent", 1, 1, FEARG_1, arg1_lnum,
|
||||||
ret_number, f_indent},
|
ret_number, f_indent},
|
||||||
{"index", 2, 4, FEARG_1, arg24_index,
|
{"index", 2, 4, FEARG_1, arg24_index,
|
||||||
@@ -7516,6 +7519,40 @@ f_hostname(typval_T *argvars UNUSED, typval_T *rettv)
|
|||||||
rettv->vval.v_string = vim_strsave(hostname);
|
rettv->vval.v_string = vim_strsave(hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "id()" function
|
||||||
|
* Identity. Return address of item as a hex string, %p format.
|
||||||
|
* Currently only valid for object/container types.
|
||||||
|
* Return empty string if not an object.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_id(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u numbuf[NUMBUFLEN];
|
||||||
|
|
||||||
|
switch (argvars[0].v_type)
|
||||||
|
{
|
||||||
|
case VAR_LIST:
|
||||||
|
case VAR_DICT:
|
||||||
|
case VAR_OBJECT:
|
||||||
|
case VAR_JOB:
|
||||||
|
case VAR_CHANNEL:
|
||||||
|
case VAR_BLOB:
|
||||||
|
// Assume pointer value in typval_T vval union at common location.
|
||||||
|
if (argvars[0].vval.v_object != NULL)
|
||||||
|
vim_snprintf((char*)numbuf, sizeof(numbuf), "%p",
|
||||||
|
(void *)argvars[0].vval.v_object);
|
||||||
|
else
|
||||||
|
numbuf[0] = NUL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
numbuf[0] = NUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = vim_strsave(numbuf);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "index()" function
|
* "index()" function
|
||||||
*/
|
*/
|
||||||
|
@@ -1619,4 +1619,34 @@ func Test_deep_nested_listdict_compare()
|
|||||||
call v9.CheckLegacyAndVim9Success(lines)
|
call v9.CheckLegacyAndVim9Success(lines)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for using id()
|
||||||
|
def Test_id_with_dict()
|
||||||
|
# demonstate a way that "id(item)" differs from "string(item)"
|
||||||
|
var d1 = {one: 1}
|
||||||
|
var d2 = {one: 1}
|
||||||
|
var d3 = {one: 1}
|
||||||
|
var idDict: dict<any>
|
||||||
|
idDict[id(d1)] = d1
|
||||||
|
idDict[id(d2)] = d2
|
||||||
|
idDict[id(d3)] = d3
|
||||||
|
assert_equal(3, idDict->len())
|
||||||
|
|
||||||
|
var stringDict: dict<any>
|
||||||
|
stringDict[string(d1)] = d1
|
||||||
|
stringDict[string(d2)] = d2
|
||||||
|
stringDict[string(d3)] = d3
|
||||||
|
assert_equal(1, stringDict->len())
|
||||||
|
|
||||||
|
assert_equal('', id(3))
|
||||||
|
|
||||||
|
assert_equal('', id(null))
|
||||||
|
assert_equal('', id(null_blob))
|
||||||
|
assert_equal('', id(null_dict))
|
||||||
|
assert_equal('', id(null_function))
|
||||||
|
assert_equal('', id(null_list))
|
||||||
|
assert_equal('', id(null_partial))
|
||||||
|
assert_equal('', id(null_string))
|
||||||
|
assert_equal('', id(null_channel))
|
||||||
|
assert_equal('', id(null_job))
|
||||||
|
enddef
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -704,6 +704,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 */
|
||||||
|
/**/
|
||||||
|
548,
|
||||||
/**/
|
/**/
|
||||||
547,
|
547,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user