updated for version 7.0180
diff --git a/runtime/autoload/pycomplete.vim b/runtime/autoload/pycomplete.vim
new file mode 100644
index 0000000..8cd5a5f
--- /dev/null
+++ b/runtime/autoload/pycomplete.vim
@@ -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: