# HG changeset patch # User Bram Moolenaar # Date 1366805265 -7200 # Node ID f1eab4f77a6fe4b77508d86a68a6681195806607 # Parent 918eada6eda5ec3c63612daf529124bc5a39ebea updated for version 7.3.911 Problem: Python: Access to Vim variables is not so easy. Solution: Define vim.vars and vim.vvars. (ZyX) diff --git a/runtime/doc/if_pyth.txt b/runtime/doc/if_pyth.txt --- a/runtime/doc/if_pyth.txt +++ b/runtime/doc/if_pyth.txt @@ -237,6 +237,11 @@ vim.current *python-current* "current range". A range is a bit like a buffer, but with all access restricted to a subset of lines. See |python-range| for more details. +vim.vars *python-vars* +vim.vvars *python-vvars* + Dictionary-like objects holding dictionaries with global (|g:|) and + vim (|v:|) variables respectively. Identical to `vim.bindeval("g:")`, + but faster. Output from Python *python-output* Vim displays all Python code output in the Vim message area. Normal @@ -307,6 +312,7 @@ Examples (assume b is the current buffer :py n = len(b) # number of lines :py (row,col) = b.mark('a') # named mark :py r = b.range(1,5) # a sub-range of the buffer + :py b.vars["foo"] = "bar" # assign b:foo variable ============================================================================== 4. Range objects *python-range* @@ -354,6 +360,9 @@ Window attributes are: This is a tuple, (row,col). height (read-write) The window height, in rows width (read-write) The window width, in columns + vars (read-only) The window |w:| variables. Attribute is + unassignable, but you can change window + variables this way The height attribute is writable only if the screen is split horizontally. The width attribute is writable only if the screen is split vertically. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -113,12 +113,7 @@ static char *e_letwrong = N_("E734: Wron static char *e_nofunc = N_("E130: Unknown function: %s"); static char *e_illvar = N_("E461: Illegal variable name: %s"); -/* - * All user-defined global variables are stored in dictionary "globvardict". - * "globvars_var" is the variable that is used for "g:". - */ -static dict_T globvardict; -static dictitem_T globvars_var; +static dictitem_T globvars_var; /* variable used for g: */ #define globvarht globvardict.dv_hashtab /* @@ -370,12 +365,7 @@ static struct vimvar #define vv_list vv_di.di_tv.vval.v_list #define vv_tv vv_di.di_tv -/* - * The v: variables are stored in dictionary "vimvardict". - * "vimvars_var" is the variable that is used for the "l:" scope. - */ -static dict_T vimvardict; -static dictitem_T vimvars_var; +static dictitem_T vimvars_var; /* variable used for v: */ #define vimvarht vimvardict.dv_hashtab static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -180,6 +180,8 @@ EXTERN int emsg_skip INIT(= 0); /* d EXTERN int emsg_severe INIT(= FALSE); /* use message of next of several emsg() calls for throw */ EXTERN int did_endif INIT(= FALSE); /* just had ":endif" */ +EXTERN dict_T vimvardict; /* Dictionary with v: variables */ +EXTERN dict_T globvardict; /* Dictionary with g: variables */ #endif EXTERN int did_emsg; /* set by emsg() when the message is displayed or thrown */ diff --git a/src/if_py_both.h b/src/if_py_both.h --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -1532,8 +1532,10 @@ WindowAttr(WindowObject *this, char *nam else if (strcmp(name, "width") == 0) return Py_BuildValue("l", (long)(W_WIDTH(this->win))); #endif + else if (strcmp(name, "vars") == 0) + return DictionaryNew(this->win->w_vars); else if (strcmp(name,"__members__") == 0) - return Py_BuildValue("[sss]", "buffer", "cursor", "height"); + return Py_BuildValue("[ssss]", "buffer", "cursor", "height", "vars"); else return NULL; } @@ -2495,8 +2497,10 @@ BufferAttr(BufferObject *this, char *nam return Py_BuildValue("s", this->buf->b_ffname); else if (strcmp(name, "number") == 0) return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum); + else if (strcmp(name, "vars") == 0) + return DictionaryNew(this->buf->b_vars); else if (strcmp(name,"__members__") == 0) - return Py_BuildValue("[ss]", "name", "number"); + return Py_BuildValue("[sss]", "name", "number", "vars"); else return NULL; } diff --git a/src/if_python.c b/src/if_python.c --- a/src/if_python.c +++ b/src/if_python.c @@ -1330,6 +1330,7 @@ PythonMod_Init(void) { PyObject *mod; PyObject *dict; + PyObject *tmp; /* The special value is removed from sys.path in Python_Init(). */ static char *(argv[2]) = {"/must>not&exist/foo", NULL}; @@ -1353,6 +1354,12 @@ PythonMod_Init(void) PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferList); PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent); PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList); + tmp = DictionaryNew(&globvardict); + PyDict_SetItemString(dict, "vars", tmp); + Py_DECREF(tmp); + tmp = DictionaryNew(&vimvardict); + PyDict_SetItemString(dict, "vvars", tmp); + Py_DECREF(tmp); PyDict_SetItemString(dict, "VAR_LOCKED", PyInt_FromLong(VAR_LOCKED)); PyDict_SetItemString(dict, "VAR_FIXED", PyInt_FromLong(VAR_FIXED)); PyDict_SetItemString(dict, "VAR_SCOPE", PyInt_FromLong(VAR_SCOPE)); diff --git a/src/if_python3.c b/src/if_python3.c --- a/src/if_python3.c +++ b/src/if_python3.c @@ -1647,6 +1647,9 @@ Py3Init_vim(void) Py_INCREF((PyObject *)(void *)&TheWindowList); PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList); + PyModule_AddObject(mod, "vars", DictionaryNew(&globvardict)); + PyModule_AddObject(mod, "vvars", DictionaryNew(&vimvardict)); + #define ADD_INT_CONSTANT(name, value) \ tmp = PyLong_FromLong(value); \ Py_INCREF(tmp); \ diff --git a/src/testdir/test86.in b/src/testdir/test86.in --- a/src/testdir/test86.in +++ b/src/testdir/test86.in @@ -346,6 +346,19 @@ EOF :$put =string(pyeval('l')) :py l = ll[-10:10] :$put =string(pyeval('l')) +:" +:" Vars +:let g:foo = 'bac' +:let w:abc = 'def' +:let b:baz = 'bar' +:try +: throw "Abc" +:catch +: put =pyeval('vim.vvars[''exception'']') +:endtry +:put =pyeval('vim.vars[''foo'']') +:put =pyeval('vim.current.window.vars[''abc'']') +:put =pyeval('vim.current.buffer.vars[''baz'']') :endfun :" :call Test() diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok --- a/src/testdir/test86.ok +++ b/src/testdir/test86.ok @@ -76,3 +76,7 @@ vim: Vim(let):E859: [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5] +Abc +bac +def +bar diff --git a/src/testdir/test87.in b/src/testdir/test87.in --- a/src/testdir/test87.in +++ b/src/testdir/test87.in @@ -315,6 +315,19 @@ EOF :py3 trace_main() :py3 sys.settrace(None) :$put =string(l) +:" +:" Vars +:let g:foo = 'bac' +:let w:abc = 'def' +:let b:baz = 'bar' +:try +: throw "Abc" +:catch +: put =py3eval('vim.vvars[''exception'']') +:endtry +:put =py3eval('vim.vars[''foo'']') +:put =py3eval('vim.current.window.vars[''abc'']') +:put =py3eval('vim.current.buffer.vars[''baz'']') :endfun :" :call Test() diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok --- a/src/testdir/test87.ok +++ b/src/testdir/test87.ok @@ -65,3 +65,7 @@ undefined_name: Vim(let):Trace vim: Vim(let):E861: [1] [1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1] +Abc +bac +def +bar diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 911, +/**/ 910, /**/ 909,