Mercurial > vim
view src/testdir/test86.in @ 20697:1260b27535b5 v8.2.0902
patch 8.2.0902: using searchcount() in 'statusline' causes an error
Commit: https://github.com/vim/vim/commit/442a85369f3eb9834dbab42add45f7c4106700f4
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jun 4 20:56:09 2020 +0200
patch 8.2.0902: using searchcount() in 'statusline' causes an error
Problem: Using searchcount() in 'statusline' causes an error.
Solution: Avoid saving/restoring the search patten recursively.
(closes #6194)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 04 Jun 2020 21:00:03 +0200 |
parents | 04ef2ccf2519 |
children |
line wrap: on
line source
Tests for various python features. vim: set ft=vim : NOTE: This will cause errors when run under valgrind. This would require recompiling Python with: ./configure --without-pymalloc See http://svn.python.org/view/python/trunk/Misc/README.valgrind?view=markup STARTTEST :so small.vim :set encoding=latin1 :set noswapfile :if !has('python') || !has('quickfix') | e! test.ok | wq! test.out | endif :lang C :fun Test() :py import vim :py cb = vim.current.buffer :let l = [] :py l=vim.bindeval('l') :py f=vim.bindeval('function("strlen")') :" Extending List directly with different types :py l.extend([1, "as'd", [1, 2, f, {'a': 1}]]) :$put =string(l) :$put =string(l[-1]) :try : $put =string(l[-4]) :catch : $put =v:exception[:13] :endtry :" List assignment :py l[0]=0 :$put =string(l) :py l[-2]=f :$put =string(l) :" :" Extending Dictionary directly with different types :let d = {} :fun d.f() : return 1 :endfun py << trim EOF d=vim.bindeval('d') d['1']='asd' d.update() # Must not do anything, including throwing errors d.update(b=[1, 2, f]) d.update((('-1', {'a': 1}),)) d.update({'0': -1}) dk = d.keys() dv = d.values() di = d.items() cmpfun = lambda a, b: cmp(repr(a), repr(b)) dk.sort(cmpfun) dv.sort(cmpfun) di.sort(cmpfun) EOF :$put =pyeval('d[''f''](self={})') :$put =pyeval('repr(dk)') :$put =substitute(pyeval('repr(dv)'),'0x\x\+','','g') :$put =substitute(pyeval('repr(di)'),'0x\x\+','','g') :for [key, Val] in sort(items(d)) : $put =string(key) . ' : ' . string(Val) : unlet key Val :endfor :py del dk :py del di :py del dv :" :" removing items with del :py del l[2] :$put =string(l) :let l = range(8) :py l=vim.bindeval('l') :try : py del l[:3] : py del l[1:] :catch : $put =v:exception :endtry :$put =string(l) :" :py del d['-1'] :py del d['f'] :$put =string(pyeval('d.get(''b'', 1)')) :$put =string(pyeval('d.pop(''b'')')) :$put =string(pyeval('d.get(''b'', 1)')) :$put =string(pyeval('d.pop(''1'', 2)')) :$put =string(pyeval('d.pop(''1'', 2)')) :$put =pyeval('repr(d.has_key(''0''))') :$put =pyeval('repr(d.has_key(''1''))') :$put =pyeval('repr(''0'' in d)') :$put =pyeval('repr(''1'' in d)') :$put =pyeval('repr(list(iter(d)))') :$put =string(d) :$put =pyeval('repr(d.popitem())') :$put =pyeval('repr(d.get(''0''))') :$put =pyeval('repr(list(iter(d)))') :" :" removing items out of range: silently skip items that don't exist :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :" The following two ranges delete nothing as they match empty list: :py del l[2:1] :$put =string(l) :py del l[2:2] :$put =string(l) :py del l[2:3] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[2:4] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[2:5] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[2:6] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :" The following two ranges delete nothing as they match empty list: :py del l[-1:2] :$put =string(l) :py del l[-2:2] :$put =string(l) :py del l[-3:2] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[-4:2] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[-5:2] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[-6:2] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[::2] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[3:0:-2] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py del l[2:4:-2] :$put =string(l) :" :" Slice assignment to a list :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[0:0]=['a'] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[1:2]=['b'] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[2:4]=['c'] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[4:4]=['d'] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[-1:2]=['e'] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[-10:2]=['f'] :$put =string(l) :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :py l[2:-10]=['g'] :$put =string(l) :let l = [] :py l=vim.bindeval('l') :py l[0:0]=['h'] :$put =string(l) :let l = range(8) :py l=vim.bindeval('l') :py l[2:6:2] = [10, 20] :$put =string(l) :let l = range(8) :py l=vim.bindeval('l') :py l[6:2:-2] = [10, 20] :$put =string(l) :let l = range(8) :py l=vim.bindeval('l') :py l[6:2] = () :$put =string(l) :let l = range(8) :py l=vim.bindeval('l') :py l[6:2:1] = () :$put =string(l) :let l = range(8) :py l=vim.bindeval('l') :py l[2:2:1] = () :$put =string(l) :" :" Locked variables :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :lockvar! l py << trim EOF def emsg(ei): return ei[0].__name__ + ':' + repr(ei[1].args) try: l[2]='i' except vim.error: cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) EOF :$put =string(l) :unlockvar! l :" :" Function calls py << trim EOF import sys def ee(expr, g=globals(), l=locals()): try: exec(expr, g, l) except: ei = sys.exc_info() msg = emsg(ei) msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') if expr.find('None') > -1: msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', 'TypeError:("\'NoneType\' object is not iterable",)') if expr.find('FailingNumber') > -1: msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', 'TypeError:("\'FailingNumber\' object is not iterable",)') if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: msg = msg.replace('(\'', '("').replace('\',)', '",)') # Some Python versions say can't, others cannot. if msg.find('can\'t') > -1: msg = msg.replace('can\'t', 'cannot') # Some Python versions use single quote, some double quote if msg.find('"cannot ') > -1: msg = msg.replace('"cannot ', '\'cannot ') if msg.find(' attributes"') > -1: msg = msg.replace(' attributes"', ' attributes\'') if expr == 'fd(self=[])': # HACK: PyMapping_Check changed meaning msg = msg.replace('AttributeError:(\'keys\',)', 'TypeError:(\'unable to convert list to vim dictionary\',)') vim.current.buffer.append(expr + ':' + msg) else: vim.current.buffer.append(expr + ':NOT FAILED') EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] :endfun :fun DictNew(...) dict : return ['DictNewStart']+a:000+['DictNewEnd', self] :endfun :let l=[function('New'), function('DictNew')] :py l=vim.bindeval('l') :py l.extend(list(l[0](1, 2, 3))) :$put =string(l) :py l.extend(list(l[1](1, 2, 3, self={'a': 'b'}))) :$put =string(l) :py l.extend([l[0].name]) :$put =string(l) :py ee('l[1](1, 2, 3)') :py f=l[0] :delfunction New :py ee('f(1, 2, 3)') :if has('float') : let l=[0.0] : py l=vim.bindeval('l') : py l.extend([0.0]) : $put =string(l) :else : $put ='[0.0, 0.0]' :endif :let messages=[] :delfunction DictNew py << trim EOF d=vim.bindeval('{}') m=vim.bindeval('messages') def em(expr, g=globals(), l=locals()): try: exec(expr, g, l) except: m.extend([sys.exc_type.__name__]) em('d["abc1"]') em('d["abc1"]="\\0"') em('d["abc1"]=vim') em('d[""]=1') em('d["a\\0b"]=1') em('d[u"a\\0b"]=1') em('d.pop("abc1")') em('d.popitem()') del em del m EOF :$put =messages :unlet messages :" locked and scope attributes :let d={} | let dl={} | lockvar dl :for s in split("d dl v: g:") : let name=tr(s, ':', 's') : execute 'py '.name.'=vim.bindeval("'.s.'")' : let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".pyeval(name.".".v:val)'), ';') : $put =toput :endfor :silent! let d.abc2=1 :silent! let dl.abc3=1 :py d.locked=True :py dl.locked=False :silent! let d.def=1 :silent! let dl.def=1 :put ='d:'.string(d) :put ='dl:'.string(dl) :unlet d dl : :let l=[] | let ll=[] | lockvar ll :for s in split("l ll") : let name=tr(s, ':', 's') : execute 'py '.name.'=vim.bindeval("'.s.'")' : let toput=s.' : locked:'.pyeval(name.'.locked') : $put =toput :endfor :silent! call extend(l, [0]) :silent! call extend(ll, [0]) :py l.locked=True :py ll.locked=False :silent! call extend(l, [1]) :silent! call extend(ll, [1]) :put ='l:'.string(l) :put ='ll:'.string(ll) :unlet l ll :" :" pyeval() :let l=pyeval('range(3)') :$put =string(l) :let d=pyeval('{"a": "b", "c": 1, "d": ["e"]}') :$put =sort(items(d)) :let v:errmsg = '' :$put ='pyeval(\"None\") = ' . pyeval('None') . v:errmsg :if has('float') : let f=pyeval('0.0') : $put =string(f) :else : $put ='0.0' :endif :" Invalid values: :for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim'] : try : let v=pyeval(e) : catch : let toput=e.":\t".v:exception[:13] : $put =toput : endtry :endfor :" :" threading :let l = [0] :py l=vim.bindeval('l') py << trim EOF import threading import time class T(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.t = 0 self.running = True def run(self): while self.running: self.t += 1 time.sleep(0.1) t = T() del T t.start() EOF :sleep 1 :py t.running = False :py t.join() :" Check if the background thread is working. Count should be 10, but on a :" busy system (AppVeyor) it can be much lower. :py l[0] = t.t > 4 :py del time :py del threading :py del t :$put =string(l) :" :" settrace :let l = [] :py l=vim.bindeval('l') py << trim EOF import sys def traceit(frame, event, arg): global l if event == "line": l.extend([frame.f_lineno]) return traceit def trace_main(): for i in range(5): pass EOF :py sys.settrace(traceit) :py trace_main() :py sys.settrace(None) :py del traceit :py del trace_main :$put =string(l) :" :" Slice :py ll = vim.bindeval('[0, 1, 2, 3, 4, 5]') :py l = ll[:4] :$put =string(pyeval('l')) :py l = ll[2:] :$put =string(pyeval('l')) :py l = ll[:-4] :$put =string(pyeval('l')) :py l = ll[-2:] :$put =string(pyeval('l')) :py l = ll[2:4] :$put =string(pyeval('l')) :py l = ll[4:2] :$put =string(pyeval('l')) :py l = ll[-4:-2] :$put =string(pyeval('l')) :py l = ll[-2:-4] :$put =string(pyeval('l')) :py l = ll[:] :$put =string(pyeval('l')) :py l = ll[0:6] :$put =string(pyeval('l')) :py l = ll[-10:10] :$put =string(pyeval('l')) :py l = ll[4:2:-1] :$put =string(pyeval('l')) :py l = ll[::2] :$put =string(pyeval('l')) :py l = ll[4:2:1] :$put =string(pyeval('l')) :py del l :" :" Vars :let g:foo = 'bac' :let w:abc3 = 'def' :let b:baz = 'bar' :let t:bar = 'jkl' :try : throw "Abc" :catch : put =pyeval('vim.vvars[''exception'']') :endtry :put =pyeval('vim.vars[''foo'']') :put =pyeval('vim.current.window.vars[''abc3'']') :put =pyeval('vim.current.buffer.vars[''baz'']') :put =pyeval('vim.current.tabpage.vars[''bar'']') :" :" Options :" paste: boolean, global :" previewheight number, global :" operatorfunc: string, global :" number: boolean, window-local :" numberwidth: number, window-local :" colorcolumn: string, window-local :" statusline: string, window-local/global :" autoindent: boolean, buffer-local :" shiftwidth: number, buffer-local :" omnifunc: string, buffer-local :" preserveindent: boolean, buffer-local/global :" path: string, buffer-local/global :let g:bufs=[bufnr('%')] :new :let g:bufs+=[bufnr('%')] :vnew :let g:bufs+=[bufnr('%')] :wincmd j :vnew :let g:bufs+=[bufnr('%')] :wincmd l :fun RecVars(opt) : let gval =string(eval('&g:'.a:opt)) : let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))')) : let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))')) : put =' G: '.gval : put =' W: '.wvals : put =' B: '.wvals :endfun py << trim EOF def e(s, g=globals(), l=locals()): try: exec(s, g, l) except: vim.command('return ' + repr(sys.exc_type.__name__)) def ev(s, g=globals(), l=locals()): try: return eval(s, g, l) except: vim.command('let exc=' + repr(sys.exc_type.__name__)) return 0 EOF :fun E(s) : python e(vim.eval('a:s')) :endfun :fun Ev(s) : let r=pyeval('ev(vim.eval("a:s"))') : if exists('exc') : throw exc : endif : return r :endfun :py gopts1=vim.options :py wopts1=vim.windows[2].options :py wopts2=vim.windows[0].options :py wopts3=vim.windows[1].options :py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options :py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options :py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options :$put ='wopts iters equal: '.pyeval('list(wopts1) == list(wopts2)') :$put ='bopts iters equal: '.pyeval('list(bopts1) == list(bopts2)') :py gset=set(iter(gopts1)) :py wset=set(iter(wopts1)) :py bset=set(iter(bopts1)) :set path=.,..,, :let lst=[] :let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] :let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]] :let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]] :let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]] :let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]] :let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]] :let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]] :let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]] :let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]] :let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]] :let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]] :let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]] :for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst : py oname=vim.eval('oname') : py oval1=vim.bindeval('oval1') : py oval2=vim.bindeval('oval2') : py oval3=vim.bindeval('oval3') : if invval is 0 || invval is 1 : py invval=bool(vim.bindeval('invval')) : else : py invval=vim.bindeval('invval') : endif : if bool : py oval1=bool(oval1) : py oval2=bool(oval2) : py oval3=bool(oval3) : endif : put ='>>> '.oname : $put =' g/w/b:'.pyeval('oname in gset').'/'.pyeval('oname in wset').'/'.pyeval('oname in bset') : $put =' g/w/b (in):'.pyeval('oname in gopts1').'/'.pyeval('oname in wopts1').'/'.pyeval('oname in bopts1') : for v in ['gopts1', 'wopts1', 'bopts1'] : try : put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') : catch : put =' p/'.v.'! '.v:exception : endtry : let r=E(v.'['''.oname.''']=invval') : if r isnot 0 : put =' inv: '.string(invval).'! '.r : endif : for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3']) : let val=substitute(vv, '^.opts', 'oval', '') : let r=E(vv.'['''.oname.''']='.val) : if r isnot 0 : put =' '.vv.'! '.r : endif : endfor : endfor : call RecVars(oname) : for v in ['wopts3', 'bopts3'] : let r=E('del '.v.'["'.oname.'"]') : if r isnot 0 : put =' del '.v.'! '.r : endif : endfor : call RecVars(oname) :endfor :delfunction RecVars :delfunction E :delfunction Ev :py del ev :py del e :only :for buf in g:bufs[1:] : execute 'bwipeout!' buf :endfor :py del gopts1 :py del wopts1 :py del wopts2 :py del wopts3 :py del bopts1 :py del bopts2 :py del bopts3 :py del oval1 :py del oval2 :py del oval3 :py del oname :py del invval :" :" Test buffer object :vnew :put ='First line' :put ='Second line' :put ='Third line' :1 delete _ :py b=vim.current.buffer :wincmd w :mark a :augroup BUFS : autocmd BufFilePost * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")')) : autocmd BufFilePre * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END py << trim EOF # Tests BufferAppend and BufferItem cb.append(b[0]) # Tests BufferSlice and BufferAssSlice cb.append('abc5') # Will be overwritten cb[-1:] = b[:-2] # Test BufferLength and BufferAssSlice cb.append('def') # Will not be overwritten cb[len(cb):] = b[:] # Test BufferAssItem and BufferMark cb.append('ghi') # Will be overwritten cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) # Test BufferRepr cb.append(repr(cb) + repr(b)) # Modify foreign buffer b.append('foo') b[0]='bar' b[0:0]=['baz'] vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) # Test assigning to name property import os old_name = cb.name cb.name = 'foo' cb.append(cb.name[-11:].replace(os.path.sep, '/')) b.name = 'bar' cb.append(b.name[-11:].replace(os.path.sep, '/')) cb.name = old_name cb.append(cb.name[-17:].replace(os.path.sep, '/')) del old_name # Test CheckBuffer for _b in vim.buffers: if _b is not cb: vim.command('bwipeout! ' + str(_b.number)) del _b cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'): try: exec(expr) except vim.error: pass else: # Usually a SEGV here # Should not happen in any case cb.append('No exception for ' + expr) vim.command('cd .') del b EOF :augroup BUFS : autocmd! :augroup END :augroup! BUFS :" :" Test vim.buffers object :set hidden :edit a :buffer # :edit b :buffer # :edit c :buffer # py << trim EOF try: from __builtin__ import next except ImportError: next = lambda o: o.next() # Check GCing iterator that was not fully exhausted i = iter(vim.buffers) cb.append('i:' + str(next(i))) # and also check creating more than one iterator at a time i2 = iter(vim.buffers) cb.append('i2:' + str(next(i2))) cb.append('i:' + str(next(i))) # The following should trigger GC and not cause any problems del i del i2 i3 = iter(vim.buffers) cb.append('i3:' + str(next(i3))) del i3 prevnum = 0 for b in vim.buffers: # Check buffer order if prevnum >= b.number: cb.append('!!! Buffer numbers not in strictly ascending order') # Check indexing: vim.buffers[number].number == number cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) prevnum = b.number del prevnum cb.append(str(len(vim.buffers))) bnums = list(map(lambda b: b.number, vim.buffers))[1:] # Test wiping out buffer with existing iterator i4 = iter(vim.buffers) cb.append('i4:' + str(next(i4))) vim.command('bwipeout! ' + str(bnums.pop(0))) try: next(i4) except vim.error: pass else: cb.append('!!!! No vim.error') i4 = iter(vim.buffers) vim.command('bwipeout! ' + str(bnums.pop(-1))) vim.command('bwipeout! ' + str(bnums.pop(-1))) cb.append('i4:' + str(next(i4))) try: next(i4) except StopIteration: cb.append('StopIteration') del i4 del bnums EOF :" :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects :tabnew 0 :tabnew 1 :vnew a.1 :tabnew 2 :vnew a.2 :vnew b.2 :vnew c.2 py << trim EOF cb.append('Number of tabs: ' + str(len(vim.tabpages))) cb.append('Current tab pages:') def W(w): if repr(w).find('(unknown)') != -1: return '<window object (unknown)>' else: return repr(w) start = len(cb) def Cursor(w): if w.buffer is cb: return repr((start - w.cursor[0], w.cursor[1])) else: return repr(w.cursor) for t in vim.tabpages: cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) cb.append(' Windows:') for w in t.windows: cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) # Other values depend on the size of the terminal, so they are checked partly: for attr in ('height', 'row', 'width', 'col'): try: aval = getattr(w, attr) if type(aval) is not long: raise TypeError if aval < 0: raise ValueError except Exception: cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__) del aval del attr w.cursor = (len(w.buffer), 0) del W del Cursor cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) if list(vim.windows) != list(vim.current.tabpage.windows): cb.append('!!!!!! Windows differ') EOF :" :" Test vim.current py << trim EOF def H(o): return repr(o) cb.append('Current tab page: ' + repr(vim.current.tabpage)) cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer)) del H # Assigning: fails try: vim.current.window = vim.tabpages[0].window except ValueError: cb.append('ValueError at assigning foreign tab window') for attr in ('window', 'tabpage', 'buffer'): try: setattr(vim.current, attr, None) except TypeError: cb.append('Type error at assigning None to vim.current.' + attr) del attr # Assigning: success vim.current.tabpage = vim.tabpages[-2] vim.current.buffer = cb vim.current.window = vim.windows[0] vim.current.window.cursor = (len(vim.current.buffer), 0) cb.append('Current tab page: ' + repr(vim.current.tabpage)) cb.append('Current window: ' + repr(vim.current.window)) cb.append('Current buffer: ' + repr(vim.current.buffer)) cb.append('Current line: ' + repr(vim.current.line)) ws = list(vim.windows) ts = list(vim.tabpages) for b in vim.buffers: if b is not cb: vim.command('bwipeout! ' + str(b.number)) del b cb.append('w.valid: ' + repr([w.valid for w in ws])) cb.append('t.valid: ' + repr([t.valid for t in ts])) del w del t del ts del ws EOF :tabonly! :only! :" :" Test types py << trim 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))) del expr del attr EOF :" :" Test __dir__() method py << trim EOF for name, o in ( ('current', vim.current), ('buffer', vim.current.buffer), ('window', vim.current.window), ('tabpage', vim.current.tabpage), ('range', vim.current.range), ('dictionary', vim.bindeval('{}')), ('list', vim.bindeval('[]')), ('function', vim.bindeval('function("tr")')), ('output', sys.stdout), ): cb.append(name + ':' + ','.join(dir(o))) del name del o EOF :" :" Test vim.*.__new__ :$put =string(pyeval('vim.Dictionary({})')) :$put =string(pyeval('vim.Dictionary(a=1)')) :$put =string(pyeval('vim.Dictionary(((''a'', 1),))')) :$put =string(pyeval('vim.List()')) :$put =string(pyeval('vim.List(iter(''abc7''))')) :$put =string(pyeval('vim.Function(''tr'')')) :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4])')) :$put =string(pyeval('vim.Function(''tr'', args=[])')) :$put =string(pyeval('vim.Function(''tr'', self={})')) :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={})')) :$put ='auto_rebind' :$put =string(pyeval('vim.Function(''tr'', auto_rebind=False)')) :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)')) :$put =string(pyeval('vim.Function(''tr'', args=[], auto_rebind=False)')) :$put =string(pyeval('vim.Function(''tr'', self={}, auto_rebind=False)')) :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)')) :" :" Test vim.Function :function Args(...) : return a:000 :endfunction :function SelfArgs(...) dict : return [a:000, self] :endfunction :" The following four lines should not crash :let Pt = function('tr', [[]], {'l': []}) :py Pt = vim.bindeval('Pt') :unlet Pt :py del Pt py << trim EOF def ecall(out_prefix, func, *args, **kwargs): line = out_prefix + ': ' try: ret = func(*args, **kwargs) except Exception: line += '!exception: ' + emsg(sys.exc_info()) else: line += '!result: ' + vim.Function('string')(ret) cb.append(line) a = vim.Function('Args') pa1 = vim.Function('Args', args=['abcArgsPA1']) pa2 = vim.Function('Args', args=[]) pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) cb.append('a: ' + repr(a)) cb.append('pa1: ' + repr(pa1)) cb.append('pa2: ' + repr(pa2)) cb.append('pa3: ' + repr(pa3)) cb.append('pa4: ' + repr(pa4)) sa = vim.Function('SelfArgs') psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) psa2 = vim.Function('SelfArgs', args=[]) psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) psa8 = vim.Function('SelfArgs', auto_rebind=False) psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) cb.append('sa: ' + repr(sa)) cb.append('psa1: ' + repr(psa1)) cb.append('psa2: ' + repr(psa2)) cb.append('psa3: ' + repr(psa3)) cb.append('psa4: ' + repr(psa4)) cb.append('psa5: ' + repr(psa5)) cb.append('psa6: ' + repr(psa6)) cb.append('psa7: ' + repr(psa7)) cb.append('psa8: ' + repr(psa8)) cb.append('psa9: ' + repr(psa9)) cb.append('psaA: ' + repr(psaA)) cb.append('psaB: ' + repr(psaB)) cb.append('psaC: ' + repr(psaC)) psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] psar.self['rec'] = psar psar.self['self'] = psar.self psar.self['args'] = psar.args try: cb.append('psar: ' + repr(psar)) except Exception: cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) EOF :$put ='s(a): '.string(pyeval('a')) :$put ='s(pa1): '.string(pyeval('pa1')) :$put ='s(pa2): '.string(pyeval('pa2')) :$put ='s(pa3): '.string(pyeval('pa3')) :$put ='s(pa4): '.string(pyeval('pa4')) :$put ='s(sa): '.string(pyeval('sa')) :$put ='s(psa1): '.string(pyeval('psa1')) :$put ='s(psa2): '.string(pyeval('psa2')) :$put ='s(psa3): '.string(pyeval('psa3')) :$put ='s(psa4): '.string(pyeval('psa4')) :$put ='s(psa5): '.string(pyeval('psa5')) :$put ='s(psa6): '.string(pyeval('psa6')) :$put ='s(psa7): '.string(pyeval('psa7')) :$put ='s(psa8): '.string(pyeval('psa8')) :$put ='s(psa9): '.string(pyeval('psa9')) :$put ='s(psaA): '.string(pyeval('psaA')) :$put ='s(psaB): '.string(pyeval('psaB')) :$put ='s(psaC): '.string(pyeval('psaC')) : :for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7', 'psa8', 'psa9', 'psaA', 'psaB', 'psaC'] : let d = {'f': pyeval(v)} : $put ='d.'.v.'(): '.string(d.f()) :endfor : :py ecall('a()', a, ) :py ecall('pa1()', pa1, ) :py ecall('pa2()', pa2, ) :py ecall('pa3()', pa3, ) :py ecall('pa4()', pa4, ) :py ecall('sa()', sa, ) :py ecall('psa1()', psa1, ) :py ecall('psa2()', psa2, ) :py ecall('psa3()', psa3, ) :py ecall('psa4()', psa4, ) : :py ecall('a(42, 43)', a, 42, 43) :py ecall('pa1(42, 43)', pa1, 42, 43) :py ecall('pa2(42, 43)', pa2, 42, 43) :py ecall('pa3(42, 43)', pa3, 42, 43) :py ecall('pa4(42, 43)', pa4, 42, 43) :py ecall('sa(42, 43)', sa, 42, 43) :py ecall('psa1(42, 43)', psa1, 42, 43) :py ecall('psa2(42, 43)', psa2, 42, 43) :py ecall('psa3(42, 43)', psa3, 42, 43) :py ecall('psa4(42, 43)', psa4, 42, 43) : :py ecall('a(42, self={"20": 1})', a, 42, self={'20': 1}) :py ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1}) :py ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1}) :py ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1}) :py ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1}) :py ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1}) :py ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1}) :py ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1}) :py ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1}) :py ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1}) : :py ecall('a(self={"20": 1})', a, self={'20': 1}) :py ecall('pa1(self={"20": 1})', pa1, self={'20': 1}) :py ecall('pa2(self={"20": 1})', pa2, self={'20': 1}) :py ecall('pa3(self={"20": 1})', pa3, self={'20': 1}) :py ecall('pa4(self={"20": 1})', pa4, self={'20': 1}) :py ecall('sa(self={"20": 1})', sa, self={'20': 1}) :py ecall('psa1(self={"20": 1})', psa1, self={'20': 1}) :py ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) :py ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) :py ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) py << trim EOF def s(v): if v is None: return repr(v) else: return vim.Function('string')(v) cb.append('a.args: ' + s(a.args)) cb.append('pa1.args: ' + s(pa1.args)) cb.append('pa2.args: ' + s(pa2.args)) cb.append('pa3.args: ' + s(pa3.args)) cb.append('pa4.args: ' + s(pa4.args)) cb.append('sa.args: ' + s(sa.args)) cb.append('psa1.args: ' + s(psa1.args)) cb.append('psa2.args: ' + s(psa2.args)) cb.append('psa3.args: ' + s(psa3.args)) cb.append('psa4.args: ' + s(psa4.args)) cb.append('a.self: ' + s(a.self)) cb.append('pa1.self: ' + s(pa1.self)) cb.append('pa2.self: ' + s(pa2.self)) cb.append('pa3.self: ' + s(pa3.self)) cb.append('pa4.self: ' + s(pa4.self)) cb.append('sa.self: ' + s(sa.self)) cb.append('psa1.self: ' + s(psa1.self)) cb.append('psa2.self: ' + s(psa2.self)) cb.append('psa3.self: ' + s(psa3.self)) cb.append('psa4.self: ' + s(psa4.self)) cb.append('a.name: ' + s(a.name)) cb.append('pa1.name: ' + s(pa1.name)) cb.append('pa2.name: ' + s(pa2.name)) cb.append('pa3.name: ' + s(pa3.name)) cb.append('pa4.name: ' + s(pa4.name)) cb.append('sa.name: ' + s(sa.name)) cb.append('psa1.name: ' + s(psa1.name)) cb.append('psa2.name: ' + s(psa2.name)) cb.append('psa3.name: ' + s(psa3.name)) cb.append('psa4.name: ' + s(psa4.name)) cb.append('a.auto_rebind: ' + s(a.auto_rebind)) cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) del s del a del pa1 del pa2 del pa3 del pa4 del sa del psa1 del psa2 del psa3 del psa4 del psa5 del psa6 del psa7 del psa8 del psa9 del psaA del psaB del psaC del psar del ecall EOF :" :" Test stdout/stderr :redir => messages :py sys.stdout.write('abc8') ; sys.stdout.write('def') :py sys.stderr.write('abc9') ; sys.stderr.write('def') :py sys.stdout.writelines(iter('abcA')) :py sys.stderr.writelines(iter('abcB')) :redir END :$put =string(substitute(messages, '\d\+', '', 'g')) :" Test subclassing :fun Put(...) : $put =string(a:000) : return a:000 :endfun py << trim EOF class DupDict(vim.Dictionary): def __setitem__(self, key, value): super(DupDict, self).__setitem__(key, value) super(DupDict, self).__setitem__('dup_' + key, value) dd = DupDict() dd['a'] = 'b' class DupList(vim.List): def __getitem__(self, idx): return [super(DupList, self).__getitem__(idx)] * 2 dl = DupList() dl2 = DupList(iter('abcC')) dl.extend(dl2[0]) class DupFun(vim.Function): def __call__(self, arg): return super(DupFun, self).__call__(arg, arg) df = DupFun('Put') EOF :$put =string(sort(keys(pyeval('dd')))) :$put =string(pyeval('dl')) :$put =string(pyeval('dl2')) :$put =string(pyeval('df(2)')) :$put =string(pyeval('dl') is# pyeval('dl')) :$put =string(pyeval('dd') is# pyeval('dd')) :$put =string(pyeval('df')) :delfunction Put py << trim del DupDict del DupList del DupFun del dd del dl del dl2 del df . :" :" Test chdir py << trim EOF import os fnamemodify = vim.Function('fnamemodify') cb.append(fnamemodify('.', ':p:h:t')) cb.append(vim.eval('@%')) os.chdir('..') path = fnamemodify('.', ':p:h:t') if path != 'src': # Running tests from a shadow directory, so move up another level # This will result in @% looking like shadow/testdir/test86.in, hence the # extra fnamemodify os.chdir('..') cb.append(fnamemodify('.', ':p:h:t')) cb.append(fnamemodify(vim.eval('@%'), ':s?^%s.??' % path).replace(os.path.sep, '/')) os.chdir(path) del path else: cb.append(fnamemodify('.', ':p:h:t')) cb.append(vim.eval('@%').replace(os.path.sep, '/')) os.chdir('testdir') cb.append(fnamemodify('.', ':p:h:t')) cb.append(vim.eval('@%')) del fnamemodify EOF :" :" Test errors :fun F() dict :endfun :fun D() :endfun py << trim EOF d = vim.Dictionary() ned = vim.Dictionary(foo='bar', baz='abcD') dl = vim.Dictionary(a=1) dl.locked = True l = vim.List() ll = vim.List('abcE') ll.locked = True nel = vim.List('abcO') f = vim.Function('string') fd = vim.Function('F') fdel = vim.Function('D') vim.command('delfunction D') def subexpr_test(expr, name, subexprs): cb.append('>>> Testing %s using %s' % (name, expr)) for subexpr in subexprs: ee(expr % subexpr) cb.append('<<< Finished') def stringtochars_test(expr): return subexpr_test(expr, 'StringToChars', ( '1', # Fail type checks 'u"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check '"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check )) class Mapping(object): def __init__(self, d): self.d = d def __getitem__(self, key): return self.d[key] def keys(self): return self.d.keys() def items(self): return self.d.items() def convertfrompyobject_test(expr, recurse=True): # pydict_to_tv stringtochars_test(expr % '{%s : 1}') if recurse: convertfrompyobject_test(expr % '{"abcF" : %s}', False) # pymap_to_tv stringtochars_test(expr % 'Mapping({%s : 1})') if recurse: convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) # pyseq_to_tv iter_test(expr) return subexpr_test(expr, 'ConvertFromPyObject', ( 'None', # Not conversible '{"": 1}', # Empty key not allowed '{u"": 1}', # Same, but with unicode object 'FailingMapping()', # 'FailingMappingKey()', # 'FailingNumber()', # )) def convertfrompymapping_test(expr): convertfrompyobject_test(expr) return subexpr_test(expr, 'ConvertFromPyMapping', ( '[]', )) def iter_test(expr): return subexpr_test(expr, '*Iter*', ( 'FailingIter()', 'FailingIterNext()', )) def number_test(expr, natural=False, unsigned=False): if natural: unsigned = True return subexpr_test(expr, 'NumberToLong', ( '[]', 'None', ) + (unsigned and ('-1',) or ()) + (natural and ('0',) or ())) class FailingTrue(object): def __nonzero__(self): raise NotImplementedError('bool') class FailingIter(object): def __iter__(self): raise NotImplementedError('iter') class FailingIterNext(object): def __iter__(self): return self def next(self): raise NotImplementedError('next') class FailingIterNextN(object): def __init__(self, n): self.n = n def __iter__(self): return self def next(self): if self.n: self.n -= 1 return 1 else: raise NotImplementedError('next N') class FailingMappingKey(object): def __getitem__(self, item): raise NotImplementedError('getitem:mappingkey') def keys(self): return list("abcH") class FailingMapping(object): def __getitem__(self): raise NotImplementedError('getitem:mapping') def keys(self): raise NotImplementedError('keys') class FailingList(list): def __getitem__(self, idx): if i == 2: raise NotImplementedError('getitem:list') else: return super(FailingList, self).__getitem__(idx) class NoArgsCall(object): def __call__(self): pass class FailingCall(object): def __call__(self, path): raise NotImplementedError('call') class FailingNumber(object): def __int__(self): raise NotImplementedError('int') cb.append("> Output") cb.append(">> OutputSetattr") ee('del sys.stdout.softspace') number_test('sys.stdout.softspace = %s', unsigned=True) number_test('sys.stderr.softspace = %s', unsigned=True) ee('assert sys.stdout.isatty()==False') ee('assert sys.stdout.seekable()==False') ee('sys.stdout.close()') ee('sys.stdout.flush()') ee('assert sys.stderr.isatty()==False') ee('assert sys.stderr.seekable()==False') ee('sys.stderr.close()') ee('sys.stderr.flush()') ee('sys.stdout.attr = None') cb.append(">> OutputWrite") ee('assert sys.stdout.writable()==True') ee('assert sys.stdout.readable()==False') ee('assert sys.stderr.writable()==True') ee('assert sys.stderr.readable()==False') ee('assert sys.stdout.closed()==False') ee('assert sys.stderr.closed()==False') ee('assert sys.stdout.errors=="strict"') ee('assert sys.stderr.errors=="strict"') ee('assert sys.stdout.encoding==sys.stderr.encoding') ee('sys.stdout.write(None)') cb.append(">> OutputWriteLines") ee('sys.stdout.writelines(None)') ee('sys.stdout.writelines([1])') iter_test('sys.stdout.writelines(%s)') cb.append("> VimCommand") stringtochars_test('vim.command(%s)') ee('vim.command("", 2)') #! Not checked: vim->python exceptions translating: checked later cb.append("> VimToPython") #! Not checked: everything: needs errors in internal python functions cb.append("> VimEval") stringtochars_test('vim.eval(%s)') ee('vim.eval("", FailingTrue())') #! Not checked: everything: needs errors in internal python functions cb.append("> VimEvalPy") stringtochars_test('vim.bindeval(%s)') ee('vim.eval("", 2)') #! Not checked: vim->python exceptions translating: checked later cb.append("> VimStrwidth") stringtochars_test('vim.strwidth(%s)') cb.append("> VimForeachRTP") ee('vim.foreach_rtp(None)') ee('vim.foreach_rtp(NoArgsCall())') ee('vim.foreach_rtp(FailingCall())') ee('vim.foreach_rtp(int, 2)') cb.append('> import') old_rtp = vim.options['rtp'] vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ee('import xxx_no_such_module_xxx') ee('import failing_import') ee('import failing') vim.options['rtp'] = old_rtp del old_rtp cb.append("> Options") cb.append(">> OptionsItem") ee('vim.options["abcQ"]') ee('vim.options[""]') stringtochars_test('vim.options[%s]') cb.append(">> OptionsContains") stringtochars_test('%s in vim.options') cb.append("> Dictionary") cb.append(">> DictionaryConstructor") ee('vim.Dictionary("abcI")') ##! Not checked: py_dict_alloc failure cb.append(">> DictionarySetattr") ee('del d.locked') ee('d.locked = FailingTrue()') ee('vim.vvars.locked = False') ee('d.scope = True') ee('d.xxx = True') cb.append(">> _DictionaryItem") ee('d.get("a", 2, 3)') stringtochars_test('d.get(%s)') ee('d.pop("a")') ee('dl.pop("a")') cb.append(">> DictionaryContains") ee('"" in d') ee('0 in d') cb.append(">> DictionaryIterNext") ee('for i in ned: ned["a"] = 1') del i cb.append(">> DictionaryAssItem") ee('dl["b"] = 1') stringtochars_test('d[%s] = 1') convertfrompyobject_test('d["a"] = %s') cb.append(">> DictionaryUpdate") cb.append(">>> kwargs") cb.append(">>> iter") ee('d.update(FailingMapping())') ee('d.update([FailingIterNext()])') ee('d.update([FailingIterNextN(1)])') iter_test('d.update(%s)') convertfrompyobject_test('d.update(%s)') stringtochars_test('d.update(((%s, 0),))') convertfrompyobject_test('d.update((("a", %s),))') cb.append(">> DictionaryPopItem") ee('d.popitem(1, 2)') cb.append(">> DictionaryHasKey") ee('d.has_key()') cb.append("> List") cb.append(">> ListConstructor") ee('vim.List(1, 2)') ee('vim.List(a=1)') iter_test('vim.List(%s)') convertfrompyobject_test('vim.List([%s])') cb.append(">> ListItem") ee('l[1000]') cb.append(">> ListAssItem") ee('ll[1] = 2') ee('l[1000] = 3') cb.append(">> ListAssSlice") ee('ll[1:100] = "abcJ"') iter_test('l[:] = %s') ee('nel[1:10:2] = "abcK"') cb.append(repr(tuple(nel))) ee('nel[1:10:2] = "a"') cb.append(repr(tuple(nel))) ee('nel[1:1:-1] = "a"') cb.append(repr(tuple(nel))) ee('nel[:] = FailingIterNextN(2)') cb.append(repr(tuple(nel))) convertfrompyobject_test('l[:] = [%s]') cb.append(">> ListConcatInPlace") iter_test('l.extend(%s)') convertfrompyobject_test('l.extend([%s])') cb.append(">> ListSetattr") ee('del l.locked') ee('l.locked = FailingTrue()') ee('l.xxx = True') cb.append("> Function") cb.append(">> FunctionConstructor") cb.append(">>> FunctionConstructor") ee('vim.Function("123")') ee('vim.Function("xxx_non_existent_function_xxx")') ee('vim.Function("xxx#non#existent#function#xxx")') ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') ee('vim.Function("xxx_non_existent_function_xxx3", self={})') ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') cb.append(">>> FunctionNew") ee('vim.Function("tr", self="abcFuncSelf")') ee('vim.Function("tr", args=427423)') ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') ee('vim.Function("tr", "")') cb.append(">> FunctionCall") convertfrompyobject_test('f(%s)') convertfrompymapping_test('fd(self=%s)') cb.append("> TabPage") cb.append(">> TabPageAttr") ee('vim.current.tabpage.xxx') cb.append("> TabList") cb.append(">> TabListItem") ee('vim.tabpages[1000]') cb.append("> Window") cb.append(">> WindowAttr") ee('vim.current.window.xxx') cb.append(">> WindowSetattr") ee('vim.current.window.buffer = 0') ee('vim.current.window.cursor = (100000000, 100000000)') ee('vim.current.window.cursor = True') number_test('vim.current.window.height = %s', unsigned=True) number_test('vim.current.window.width = %s', unsigned=True) ee('vim.current.window.xxxxxx = True') cb.append("> WinList") cb.append(">> WinListItem") ee('vim.windows[1000]') cb.append("> Buffer") cb.append(">> StringToLine (indirect)") ee('vim.current.buffer[0] = u"\\na"') ee('vim.current.buffer[0] = "\\na"') cb.append(">> SetBufferLine (indirect)") ee('vim.current.buffer[0] = True') cb.append(">> SetBufferLineList (indirect)") ee('vim.current.buffer[:] = True') ee('vim.current.buffer[:] = ["\\na", "bc"]') cb.append(">> InsertBufferLines (indirect)") ee('vim.current.buffer.append(None)') ee('vim.current.buffer.append(["\\na", "bc"])') ee('vim.current.buffer.append("\\nbc")') cb.append(">> RBItem") ee('vim.current.buffer[100000000]') cb.append(">> RBAsItem") ee('vim.current.buffer[100000000] = ""') cb.append(">> BufferAttr") ee('vim.current.buffer.xxx') cb.append(">> BufferSetattr") ee('vim.current.buffer.name = True') ee('vim.current.buffer.xxx = True') cb.append(">> BufferMark") ee('vim.current.buffer.mark(0)') ee('vim.current.buffer.mark("abcM")') ee('vim.current.buffer.mark("!")') cb.append(">> BufferRange") ee('vim.current.buffer.range(1, 2, 3)') cb.append("> BufMap") cb.append(">> BufMapItem") ee('vim.buffers[100000000]') number_test('vim.buffers[%s]', natural=True) cb.append("> Current") cb.append(">> CurrentGetattr") ee('vim.current.xxx') cb.append(">> CurrentSetattr") ee('vim.current.line = True') ee('vim.current.buffer = True') ee('vim.current.window = True') ee('vim.current.tabpage = True') ee('vim.current.xxx = True') del d del ned del dl del l del ll del nel del f del fd del fdel del subexpr_test del stringtochars_test del Mapping del convertfrompyobject_test del convertfrompymapping_test del iter_test del number_test del FailingTrue del FailingIter del FailingIterNext del FailingIterNextN del FailingMapping del FailingMappingKey del FailingList del NoArgsCall del FailingCall del FailingNumber EOF :delfunction F :" :" Test import py << trim EOF sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) sys.path.append(os.path.join(os.getcwd(), 'python_after')) vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') l = [] def callback(path): l.append(path[-len('/testdir'):].replace(os.path.sep, '/')) vim.foreach_rtp(callback) cb.append(repr(l)) del l def callback(path): return path[-len('/testdir'):].replace(os.path.sep, '/') cb.append(repr(vim.foreach_rtp(callback))) del callback from module import dir as d from modulex import ddir cb.append(d + ',' + ddir) import before cb.append(before.dir) import after cb.append(after.dir) import topmodule as tm import topmodule.submodule as tms import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss cb.append(tm.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) cb.append(tms.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) cb.append(tmsss.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) del before del after del d del ddir del tm del tms del tmsss EOF :" :" Test exceptions :fun Exe(e) : execute a:e :endfun py << trim EOF Exe = vim.bindeval('function("Exe")') ee('vim.command("throw \'abcN\'")') ee('Exe("throw \'def\'")') ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') ee('vim.eval("xxx_unknown_function_xxx()")') ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') del Exe EOF :delfunction Exe :" :" Regression: interrupting vim.command propagates to next vim.command py << trim EOF def test_keyboard_interrupt(): try: vim.command('while 1 | endwhile') except KeyboardInterrupt: cb.append('Caught KeyboardInterrupt') except Exception: cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) else: cb.append('!!!!!!!! No exception') try: vim.command('$ put =\'Running :put\'') except KeyboardInterrupt: cb.append('!!!!!!!! Caught KeyboardInterrupt') except Exception: cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) else: cb.append('No exception') EOF :debuggreedy :call inputsave() :call feedkeys("s\ns\ns\ns\nq\n") :redir => output :debug silent! py test_keyboard_interrupt() :redir END :0 debuggreedy :call inputrestore() :silent $put =output :unlet output :py del test_keyboard_interrupt :" :" Cleanup py << trim EOF del cb del ee del emsg del sys del os del vim EOF :endfun :" :fun RunTest() :let checkrefs = !empty($PYTHONDUMPREFS) :let start = getline(1, '$') :for i in range(checkrefs ? 10 : 1) : if i != 0 : %d _ : call setline(1, start) : endif : call Test() : if i == 0 : let result = getline(1, '$') : endif :endfor :if checkrefs : %d _ : call setline(1, result) :endif :endfun :" :call RunTest() :delfunction RunTest :delfunction Test :call garbagecollect(1) :" :/^start:/,$wq! test.out :" vim: et ts=4 isk-=\: :while getchar(0) isnot 0|endwhile ENDTEST start: