updated for version 7.0180
This commit is contained in:
216
runtime/autoload/pycomplete.vim
Normal file
216
runtime/autoload/pycomplete.vim
Normal file
@ -0,0 +1,216 @@
|
||||
"pycomplete.vim - Omni Completion for python
|
||||
" Maintainer: Aaron Griffin
|
||||
" Version: 0.2
|
||||
" Last Updated: 5 January 2006
|
||||
"
|
||||
" TODO
|
||||
" * local variables *inside* class members
|
||||
|
||||
if !has('python')
|
||||
echo "Error: Required vim compiled with +python"
|
||||
finish
|
||||
endif
|
||||
|
||||
function! pycomplete#Complete(findstart, base)
|
||||
"findstart = 1 when we need to get the text length
|
||||
if a:findstart
|
||||
let line = getline('.')
|
||||
let idx = col('.')
|
||||
while idx > 0
|
||||
let idx -= 1
|
||||
let c = line[idx-1]
|
||||
if c =~ '\w'
|
||||
continue
|
||||
elseif ! c =~ '\.'
|
||||
idx = -1
|
||||
break
|
||||
else
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
return idx
|
||||
"findstart = 0 when we need to return the list of completions
|
||||
else
|
||||
execute "python get_completions('" . a:base . "')"
|
||||
return g:pycomplete_completions
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:DefPython()
|
||||
python << PYTHONEOF
|
||||
import vim
|
||||
import sys
|
||||
import __builtin__
|
||||
|
||||
LOCALDEFS = \
|
||||
['LOCALDEFS', 'clean_up','eval_source_code', \
|
||||
'get_completions', '__builtin__', '__builtins__', \
|
||||
'dbg', '__name__', 'vim', 'sys']
|
||||
#comment/uncomment one line at a time to enable/disable debugging
|
||||
def dbg(msg):
|
||||
pass
|
||||
# print(msg)
|
||||
|
||||
#it seems that by this point, vim has already stripped the base
|
||||
# matched in the findstart=1 section, so we will create the
|
||||
# statement from scratch
|
||||
def get_completions(base):
|
||||
stmt = vim.eval('expand("<cWORD>")')+base
|
||||
dbg("parsed statement => %s" % stmt)
|
||||
eval_source_code()
|
||||
try:
|
||||
dbg("eval: %s" % stmt)
|
||||
if len(stmt.split('.')) == 1:
|
||||
all = globals().keys() + dir(__builtin__)
|
||||
match = stmt
|
||||
else:
|
||||
rindex= stmt.rfind('.')
|
||||
all = dir(eval(stmt[:rindex]))
|
||||
match = stmt[rindex+1:]
|
||||
|
||||
completions = []
|
||||
dbg("match == %s" % match)
|
||||
for m in all:
|
||||
#TODO: remove private (_foo) functions?
|
||||
if m.find('__') != 0 and \
|
||||
m.find(match) == 0 and \
|
||||
m not in LOCALDEFS:
|
||||
dbg("matched... %s, %s" % (m, m.find(match)))
|
||||
completions.append(m)
|
||||
dbg("all completions: %s" % completions)
|
||||
vim.command("let g:pycomplete_completions = %s" % completions)
|
||||
except:
|
||||
dbg("exception: %s" % sys.exc_info()[1])
|
||||
vim.command("let g:pycomplete_completions = []")
|
||||
clean_up()
|
||||
|
||||
#yes, this is a quasi-functional python lexer
|
||||
def eval_source_code():
|
||||
import tokenize
|
||||
import keyword
|
||||
import StringIO
|
||||
s = StringIO.StringIO('\n'.join(vim.current.buffer[:]) + '\n')
|
||||
g = tokenize.generate_tokens(s.readline)
|
||||
|
||||
stmts = []
|
||||
lineNo = 0
|
||||
try:
|
||||
for type, str, begin, end, line in g:
|
||||
if begin[0] == lineNo:
|
||||
continue
|
||||
#junk
|
||||
elif type == tokenize.INDENT or \
|
||||
type == tokenize.DEDENT or \
|
||||
type == tokenize.ERRORTOKEN or \
|
||||
type == tokenize.ENDMARKER or \
|
||||
type == tokenize.NEWLINE:
|
||||
continue
|
||||
#import statement
|
||||
elif str == 'import':
|
||||
for type, str, begin, end, line in g:
|
||||
if str == ';' or type == tokenize.NEWLINE: break
|
||||
dbg("found [import %s]" % str)
|
||||
stmts.append("import %s" % str)
|
||||
#import from statement
|
||||
elif str == 'from':
|
||||
type, str, begin, end, line = g.next()
|
||||
mod = str
|
||||
|
||||
type, str, begin, end, line = g.next()
|
||||
if str != "import": break
|
||||
mem = ''
|
||||
for type, str, begin, end, line in g:
|
||||
if str == ';' or type == tokenize.NEWLINE: break
|
||||
mem += (str + ',')
|
||||
if len(mem) > 0:
|
||||
dbg("found [from %s import %s]" % (mod, mem[:-1]))
|
||||
stmts.append("from %s import %s" % (mod, mem[:-1]))
|
||||
#class declaration
|
||||
elif str == 'class':
|
||||
type, str, begin, end, line = g.next()
|
||||
classname = str
|
||||
dbg("found [class %s]" % classname)
|
||||
|
||||
level = 0
|
||||
members = []
|
||||
#we don't care about the meat of the members,
|
||||
# only the signatures, so we'll replace the bodies
|
||||
# with 'pass' for evaluation
|
||||
for type, str, begin, end, line in g:
|
||||
if type == tokenize.INDENT:
|
||||
level += 1
|
||||
elif type == tokenize.DEDENT:
|
||||
level -= 1
|
||||
if level == 0: break;
|
||||
elif str == 'def':
|
||||
#TODO: if name begins with '_', keep private
|
||||
memberstr = ''
|
||||
for type, str, begin, end, line in g:
|
||||
if str == ':': break
|
||||
memberstr += str
|
||||
dbg(" member [%s]" % memberstr)
|
||||
members.append(memberstr)
|
||||
#TODO parse self.blah = something lines
|
||||
#elif str == "self" && next && str == "." ...blah...
|
||||
classstr = 'class %s:' % classname
|
||||
for m in members:
|
||||
classstr += ("\n def %s:\n pass" % m)
|
||||
stmts.append("%s\n" % classstr)
|
||||
elif keyword.iskeyword(str) or str in globals():
|
||||
dbg("keyword = %s" % str)
|
||||
lineNo = begin[0]
|
||||
else:
|
||||
if line.find("=") == -1: continue
|
||||
var = str
|
||||
type, str, begin, end, line = g.next()
|
||||
dbg('next = %s' % str)
|
||||
if str != '=': continue
|
||||
|
||||
type, str, begin, end, line = g.next()
|
||||
if type == tokenize.NEWLINE:
|
||||
continue
|
||||
elif type == tokenize.STRING or str == 'str':
|
||||
stmts.append('%s = str' % var)
|
||||
elif str == '[' or str == 'list':
|
||||
stmts.append('%s= list' % var)
|
||||
elif str == '{' or str == 'dict':
|
||||
stmts.append('%s = dict' % var)
|
||||
elif type == tokenize.NUMBER:
|
||||
continue
|
||||
elif str == 'Set':
|
||||
stmts.append('%s = Set' % var)
|
||||
elif str == 'open' or str == 'file':
|
||||
stmts.append('%s = file' % var)
|
||||
else:
|
||||
inst = str
|
||||
for type, str, begin, end, line in g:
|
||||
if type == tokenize.NEWLINE:
|
||||
break
|
||||
inst += str
|
||||
if len(inst) > 0:
|
||||
dbg("found [%s = %s]" % (var, inst))
|
||||
stmts.append('%s = %s' % (var, inst))
|
||||
lineNo = begin[0]
|
||||
for s in stmts:
|
||||
try:
|
||||
dbg("evaluating: %s\n" % s)
|
||||
exec(s) in globals()
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
dbg("exception: %s" % sys.exc_info()[1])
|
||||
|
||||
def clean_up():
|
||||
for o in globals().keys():
|
||||
if o not in LOCALDEFS:
|
||||
try:
|
||||
exec('del %s' % o) in globals()
|
||||
except: pass
|
||||
|
||||
sys.path.extend(['.','..'])
|
||||
PYTHONEOF
|
||||
endfunction
|
||||
|
||||
call s:DefPython()
|
||||
" vim: set et ts=4:
|
||||
Reference in New Issue
Block a user