I have been wanting this function for over 3years now, as a simpler
workaround for the |todo| item:
8 ":let Func().foo = value" should work, also when "foo" doesn't exist.
The idea is that when Func() returns a dict(), you should be able to
set its "foo" key's value. With the set(), we can now achieve the same
and even more (if set() returns the original list or dictionary for
call chaining). E.g.,
call set(set(Func(), 'foo', 'foovalue'), 'bar', 'barvalue')
I was planning for an API for one of my plugins that returns
dictionaries, and using this API and assembling the objects becomes
unwieldy with all the temporary variables and assignments that are
required without such a function.
Here is a patch that adds this function. Bram, please accept this
patch into official source if you don't see any issues with it.
Index: runtime/doc/eval.txt
===================================================================
--- runtime/doc/eval.txt (revision 1622)
+++ runtime/doc/eval.txt (working copy)
@@ -1861,6 +1861,8 @@
server2client( {clientid}, {string})
Number send reply string
serverlist() String get a list of available servers
+set( {list}, {idx}, {item}) any set {item} in {list} at {idx}
+set( {dict}, {key}, {item}) any set {key} in {dict} to {item}
setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val}
setcmdpos( {pos}) Number set cursor position in command-line
setline( {lnum}, {line}) Number set line {lnum} to {line}
@@ -2946,6 +2948,24 @@
item is not available return {default}. Return zero when
{default} is omitted.
+set({list}, {idx}, {item}) *set()*
+ Set at {idx} in |List| {list} to specified {item}. You can't
+ extend the list using this function, so specifying a non
+ existing {idx} results in |E684| error.
+ Returns the {list} such that it can be used for method
+ chaining. Useful for setting indices returned by function
+ calls. >
+ :call set(GetHLColors(), HEADLINE_IDX, 'red')
+>
+set({dict}, {key}, {item})
+ Set the {key} in {dict} to specified {item}. When {key} is
+ non-existent, a new key is creaeted. When {key} is existing,
+ its value is overwritten with {item}.
+ Returns the {dict} such that it can be used for method
+ chaining. Useful for changing keys of dictionaries returned by
+ function calls. >
+ :call set(GetData(), 'maxlength', 100)
+>
*getbufline()*
getbufline({expr}, {lnum} [, {end}])
Return a |List| with the lines starting from {lnum} to {end}
Index: src/eval.c
===================================================================
--- src/eval.c (revision 1622)
+++ src/eval.c (working copy)
@@ -661,6 +661,7 @@
static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv));
static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv));
static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_set __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
@@ -7716,6 +7717,7 @@
#ifdef FEAT_FLOAT
{"round", 1, 1, f_round},
#endif
+ {"set", 3, 3, f_set},
{"search", 1, 4, f_search},
{"searchdecl", 1, 3, f_searchdecl},
{"searchpair", 3, 7, f_searchpair},
@@ -10444,6 +10446,59 @@
copy_tv(tv, rettv);
}
+/*
+ * "set()" function
+ */
+ static void
+f_set(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv;
+{
+ listitem_T *li;
+ list_T *l;
+ dictitem_T *di;
+ dict_T *d;
+ typval_T tmp;
+ char_u *key;
+
+ if (argvars[0].v_type == VAR_LIST)
+ {
+ if ((l = argvars[0].vval.v_list) != NULL)
+ {
+ int error = FALSE;
+
+ li = list_find(l, get_tv_number_chk(&argvars[1], &error));
+ if (li == NULL)
+ EMSGN(_(e_listidx), get_tv_number_chk(&argvars[1], &error));
+ else
+ {
+ copy_tv(&argvars[2], &li->li_tv);
+ }
+ }
+ copy_tv(&argvars[0], rettv);
+ }
+ else if (argvars[0].v_type == VAR_DICT)
+ {
+ if ((d = argvars[0].vval.v_dict) != NULL)
+ {
+ key = get_tv_string(&argvars[1]);
+ di = dict_find(d, key, -1);
+ if (di != NULL)
+ copy_tv(&argvars[2], &di->di_tv);
+ else
+ {
+ di = dictitem_alloc(key);
+ copy_tv(&argvars[2], &di->di_tv);
+ if (dict_add(d, di) == FAIL)
+ dictitem_free(di);
+ }
+ }
+ copy_tv(&argvars[0], rettv);
+ }
+ else
+ EMSG2(_(e_listdictarg), "get()");
+}
+
static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start,
linenr_T end, int retlist, typval_T *rettv));
/*
--
Thanks,
Hari
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---