# HG changeset patch # User Bram Moolenaar # Date 1369158634 -7200 # Node ID ebd94eabfd8013a605d8efc7df64a970531fd5a8 # Parent fe5605ef4d729305c08d58dbfec39e7f5aa9fe89 updated for version 7.3.996 Problem: Python: Can't check types of what is returned by bindeval(). Solution: Add vim.List, vim.Dictionary and vim.Function types. (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 @@ -11,9 +11,10 @@ 2. The vim module |python-vim| 3. Buffer objects |python-buffer| 4. Range objects |python-range| 5. Window objects |python-window| -6. pyeval(), py3eval() Vim functions |python-pyeval| -7. Dynamic loading |python-dynamic| -8. Python 3 |python3| +6. Tab page objects |python-tabpage| +7. pyeval(), py3eval() Vim functions |python-pyeval| +8. Dynamic loading |python-dynamic| +9. Python 3 |python3| {Vi does not have any of these commands} @@ -176,7 +177,7 @@ vim.bindeval(str) *python-bindeval* list or dictionary. Thus modifications to these objects imply modifications of the original. - Additionally, vimlist and vimdictionary type have read-write + Additionally, vim.List and vim.Dictionary type have read-write `.locked` attribute that returns Value Meaning ~ zero Variable is not locked @@ -189,14 +190,15 @@ vim.bindeval(str) *python-bindeval* case these locks are ignored by anything except |:let|: |extend()| does not care, neither does python interface). - Vimdictionary type also supports `.scope` attribute which is one of + vim.Dictionary type also supports `.scope` attribute which is one + of Value Meaning ~ zero Dictionary is not a scope one vim.VAR_DEF_SCOPE Function-local or global scope dictionary vim.VAR_SCOPE Other scope dictionary 2. if expression evaluates to a function reference, then it returns - callable vimfunction object. Use self keyword argument to assign + callable vim.Function object. Use self keyword argument to assign |self| object for dictionary functions. Note: this function has the same behavior as |lua-eval| (except that @@ -205,6 +207,10 @@ vim.bindeval(str) *python-bindeval* relying on outputs of vim.eval() being a copy of original or vim.eval("1") returning a string. + You can use "List", "Dictionary" and "Function" vim module attributes + to test whether object has given type. These types are currently not + subclassable, neither they contain constructors, so you can use them + only for checks like `isinstance(obj, vim.List)`. Error object of the "vim" module @@ -302,6 +308,9 @@ vim.options *python-options* buffer-local options and |python-window| objects to access to window-local options. + Type of this object is available via "Options" attribute of vim + module. + Output from Python *python-output* Vim displays all Python code output in the Vim message area. Normal output appears as information messages, and error output appears as @@ -371,6 +380,8 @@ Note that when adding a line it must not A trailing '\n' is allowed and ignored, so that you can do: > :py b.append(f.readlines()) +Buffer object type is available using "Buffer" attribute of vim module. + Examples (assume b is the current buffer) > :py print b.name # write the buffer file name :py b[0] = "hello!!!" # replace the top line @@ -412,6 +423,8 @@ The range object methods are: for Python's built-in list objects. r.append(list, nr) Idem, after line "nr" +Range object type is available using "Range" attribute of vim module. + Example (assume r is the current range): # Send all lines in a range to the default printer vim.command("%d,%dhardcopy!" % (r.start+1,r.end+1)) @@ -456,6 +469,8 @@ Window attributes are: The height attribute is writable only if the screen is split horizontally. The width attribute is writable only if the screen is split vertically. +Window object type is available using "Window" attribute of vim module. + ============================================================================== 6. Tab page objects *python-tabpage* @@ -474,14 +489,16 @@ Tab page attributes are: vars The tab page |t:| variables. window Current tabpage window. +TabPage object type is available using "TabPage" attribute of vim module. + ============================================================================== -6. pyeval() and py3eval() Vim functions *python-pyeval* +7. pyeval() and py3eval() Vim functions *python-pyeval* To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()| functions to evaluate Python expressions and pass their values to VimL. ============================================================================== -7. Dynamic loading *python-dynamic* +8. Dynamic loading *python-dynamic* On MS-Windows the Python library can be loaded dynamically. The |:version| output then includes |+python/dyn|. @@ -498,7 +515,7 @@ Currently the name is "python24.dll". T sure edit "gvim.exe" and search for "python\d*.dll\c". ============================================================================== -8. Python 3 *python3* +9. Python 3 *python3* *:py3* *:python3* The `:py3` and `:python3` commands work similar to `:python`. A simple check 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 @@ -4245,6 +4245,15 @@ static struct object_constant { {"windows", (PyObject *)(void *)&TheWindowList}, {"tabpages", (PyObject *)(void *)&TheTabPageList}, {"current", (PyObject *)(void *)&TheCurrent}, + + {"Buffer", (PyObject *)&BufferType}, + {"Range", (PyObject *)&RangeType}, + {"Window", (PyObject *)&WindowType}, + {"TabPage", (PyObject *)&TabPageType}, + {"Dictionary", (PyObject *)&DictionaryType}, + {"List", (PyObject *)&ListType}, + {"Function", (PyObject *)&FunctionType}, + {"Options", (PyObject *)&OptionsType}, }; typedef int (*object_adder)(PyObject *, const char *, PyObject *); diff --git a/src/testdir/test86.in b/src/testdir/test86.in --- a/src/testdir/test86.in +++ b/src/testdir/test86.in @@ -631,10 +631,26 @@ cb.append('Current buffer: ' + repr(vim. cb.append('Current line: ' + repr(vim.current.line)) for b in vim.buffers: if b is not cb: - vim.command('bwipeout! ' + b.number) + vim.command('bwipeout! ' + str(b.number)) EOF :tabonly! :only! +:" +:" Test types +py << EOF +for expr, attr in ( + ('vim.vars', 'Dictionary'), + ('vim.options', 'Options'), + ('vim.bindeval("{}")', 'Dictionary'), + ('vim.bindeval("[]")', 'List'), + ('vim.bindeval("function(\'tr\')")', 'Function'), + ('vim.current.buffer', 'Buffer'), + ('vim.current.range', 'Range'), + ('vim.current.window', 'Window'), + ('vim.current.tabpage', 'TabPage'), +): + cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) +EOF :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 @@ -333,7 +333,7 @@ Number of tabs: 4 Current tab pages: (1): 1 windows, current is Windows: - (1): displays buffer ; cursor is at (954, 0) + (1): displays buffer ; cursor is at (970, 0) (2): 1 windows, current is Windows: (1): displays buffer ; cursor is at (1, 0) @@ -359,3 +359,12 @@ Current tab page: Current window: Current buffer: Current line: 'Type error at assigning None to vim.current.buffer' +vim.vars:Dictionary:True +vim.options:Options:True +vim.bindeval("{}"):Dictionary:True +vim.bindeval("[]"):List:True +vim.bindeval("function('tr')"):Function:True +vim.current.buffer:Buffer:True +vim.current.range:Range:True +vim.current.window:Window:True +vim.current.tabpage:TabPage:True diff --git a/src/testdir/test87.in b/src/testdir/test87.in --- a/src/testdir/test87.in +++ b/src/testdir/test87.in @@ -622,6 +622,22 @@ for b in vim.buffers: EOF :tabonly! :only! +:" +:" Test types +py3 << EOF +for expr, attr in ( + ('vim.vars', 'Dictionary'), + ('vim.options', 'Options'), + ('vim.bindeval("{}")', 'Dictionary'), + ('vim.bindeval("[]")', 'List'), + ('vim.bindeval("function(\'tr\')")', 'Function'), + ('vim.current.buffer', 'Buffer'), + ('vim.current.range', 'Range'), + ('vim.current.window', 'Window'), + ('vim.current.tabpage', 'TabPage'), +): + cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) +EOF :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 @@ -322,7 +322,7 @@ Number of tabs: 4 Current tab pages: (1): 1 windows, current is Windows: - (1): displays buffer ; cursor is at (930, 0) + (1): displays buffer ; cursor is at (946, 0) (2): 1 windows, current is Windows: (1): displays buffer ; cursor is at (1, 0) @@ -348,3 +348,12 @@ Current tab page: Current window: Current buffer: Current line: 'Type error at assigning None to vim.current.buffer' +vim.vars:Dictionary:True +vim.options:Options:True +vim.bindeval("{}"):Dictionary:True +vim.bindeval("[]"):List:True +vim.bindeval("function('tr')"):Function:True +vim.current.buffer:Buffer:True +vim.current.range:Range:True +vim.current.window:Window:True +vim.current.tabpage:TabPage:True 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 */ /**/ + 996, +/**/ 995, /**/ 994,