diff options
author | Bram Moolenaar <Bram@vim.org> | 2006-04-20 22:17:20 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2006-04-20 22:17:20 +0000 |
commit | fc1421eb53b17aa58b01a9c07ba2007eb4a1aa4f (patch) | |
tree | aeddd441dc8dc7222c5c1acd2b0841712e833810 /runtime | |
parent | 8424a624ce1c38716deabd47f4da23f1e81614bd (diff) |
updated for version 7.0e04v7.0e04
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/autoload/htmlcomplete.vim | 91 | ||||
-rw-r--r-- | runtime/autoload/pythoncomplete.vim | 808 | ||||
-rw-r--r-- | runtime/autoload/rubycomplete.vim | 438 | ||||
-rw-r--r-- | runtime/autoload/xml/xhtml10s.vim | 4310 | ||||
-rw-r--r-- | runtime/autoload/xml/xhtml10t.vim | 461 | ||||
-rw-r--r-- | runtime/doc/insert.txt | 72 | ||||
-rw-r--r-- | runtime/doc/intro.txt | 4 | ||||
-rw-r--r-- | runtime/doc/map.txt | 17 | ||||
-rw-r--r-- | runtime/doc/options.txt | 3 | ||||
-rw-r--r-- | runtime/doc/spell.txt | 6 | ||||
-rw-r--r-- | runtime/doc/syntax.txt | 20 | ||||
-rw-r--r-- | runtime/doc/tags | 4 | ||||
-rw-r--r-- | runtime/doc/todo.txt | 11 | ||||
-rw-r--r-- | runtime/doc/version7.txt | 13 | ||||
-rw-r--r-- | runtime/spell/ca/ca_ES.diff | 2 | ||||
-rw-r--r-- | runtime/spell/es/es_ES.diff | 16 | ||||
-rw-r--r-- | runtime/syntax/bindzone.vim | 146 | ||||
-rw-r--r-- | runtime/syntax/crontab.vim | 42 | ||||
-rw-r--r-- | runtime/syntax/inform.vim | 6 | ||||
-rw-r--r-- | runtime/syntax/lua.vim | 596 |
20 files changed, 2177 insertions, 4889 deletions
diff --git a/runtime/autoload/htmlcomplete.vim b/runtime/autoload/htmlcomplete.vim index e307698a28..248426801e 100644 --- a/runtime/autoload/htmlcomplete.vim +++ b/runtime/autoload/htmlcomplete.vim @@ -1,7 +1,7 @@ " Vim completion script -" Language: HTML (XHTML 1.0 Strict by default) +" Language: HTML and XHTML " Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) -" Last Change: 2006 Apr 17 +" Last Change: 2006 Apr 20 function! htmlcomplete#CompleteTags(findstart, base) if a:findstart @@ -159,12 +159,12 @@ function! htmlcomplete#CompleteTags(findstart, base) if exists("b:entitiescompl") unlet! b:entitiescompl - if !exists("g:html_omni") + if !exists("b:html_omni") "runtime! autoload/xml/xhtml10s.vim call htmlcomplete#LoadData() endif - let entities = g:html_omni['vimxmlentities'] + let entities = b:html_omni['vimxmlentities'] if len(a:base) == 1 for m in entities @@ -462,8 +462,8 @@ function! htmlcomplete#CompleteTags(findstart, base) endfor endif else - if has_key(g:html_omni, tag) && has_key(g:html_omni[tag][1], attrname) - let values = g:html_omni[tag][1][attrname] + if has_key(b:html_omni, tag) && has_key(b:html_omni[tag][1], attrname) + let values = b:html_omni[tag][1][attrname] else return [] endif @@ -503,13 +503,13 @@ function! htmlcomplete#CompleteTags(findstart, base) let sbase = matchstr(context, '.*\ze\s.*') " Load data {{{ - if !exists("g:html_omni_gen") + if !exists("b:html_omni_gen") call htmlcomplete#LoadData() endif " }}} - if has_key(g:html_omni, tag) - let attrs = keys(g:html_omni[tag][1]) + if has_key(b:html_omni, tag) + let attrs = keys(b:html_omni[tag][1]) else return [] endif @@ -522,13 +522,13 @@ function! htmlcomplete#CompleteTags(findstart, base) endif endfor let menu = res + res2 - if has_key(g:html_omni, 'vimxmlattrinfo') + if has_key(b:html_omni, 'vimxmlattrinfo') let final_menu = [] for i in range(len(menu)) let item = menu[i] - if has_key(g:html_omni['vimxmlattrinfo'], item) - let m_menu = g:html_omni['vimxmlattrinfo'][item][0] - let m_info = g:html_omni['vimxmlattrinfo'][item][1] + if has_key(b:html_omni['vimxmlattrinfo'], item) + let m_menu = b:html_omni['vimxmlattrinfo'][item][0] + let m_info = b:html_omni['vimxmlattrinfo'][item][1] if m_menu !~ 'Bool' let item .= '="' endif @@ -558,7 +558,7 @@ function! htmlcomplete#CompleteTags(findstart, base) endif " }}} " Load data {{{ - if !exists("g:html_omni") + if !exists("b:html_omni") "runtime! autoload/xml/xhtml10s.vim call htmlcomplete#LoadData() endif @@ -568,16 +568,16 @@ function! htmlcomplete#CompleteTags(findstart, base) let opentag = tolower(xmlcomplete#GetLastOpenTag("b:unaryTagsStack")) " MM: TODO: GLOT works always the same but with some weird situation it " behaves as intended in HTML but screws in PHP - if opentag == '' || &ft == 'php' && !has_key(g:html_omni, opentag) + if opentag == '' || &ft == 'php' && !has_key(b:html_omni, opentag) " Hack for sometimes failing GetLastOpenTag. " As far as I tested fail isn't GLOT fault but problem " of invalid document - not properly closed tags and other mish-mash. " Also when document is empty. Return list of *all* tags. - let tags = keys(g:html_omni) + let tags = keys(b:html_omni) call filter(tags, 'v:val !~ "^vimxml"') else - if has_key(g:html_omni, opentag) - let tags = g:html_omni[opentag][0] + if has_key(b:html_omni, opentag) + let tags = b:html_omni[opentag][0] else return [] endif @@ -596,17 +596,20 @@ function! htmlcomplete#CompleteTags(findstart, base) endif endfor let menu = res + res2 - if has_key(g:html_omni, 'vimxmltaginfo') + if has_key(b:html_omni, 'vimxmltaginfo') let final_menu = [] for i in range(len(menu)) let item = menu[i] - if has_key(g:html_omni['vimxmltaginfo'], item) - let m_menu = g:html_omni['vimxmltaginfo'][item][0] - let m_info = g:html_omni['vimxmltaginfo'][item][1] + if has_key(b:html_omni['vimxmltaginfo'], item) + let m_menu = b:html_omni['vimxmltaginfo'][item][0] + let m_info = b:html_omni['vimxmltaginfo'][item][1] else let m_menu = '' let m_info = '' endif + if &ft == 'html' && exists("uppercase_tag") && uppercase_tag == 1 + let item = toupper(item) + endif let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}] endfor else @@ -619,25 +622,39 @@ function! htmlcomplete#CompleteTags(findstart, base) endfunction function! htmlcomplete#LoadData() " {{{ - if !exists("g:html_omni_flavor") - let g:html_omni_flavor = 'xhtml10s' + if !exists("b:html_omni_flavor") + if &ft == 'html' + let b:html_omni_flavor = 'html401t' + else + let b:html_omni_flavor = 'xhtml10s' + endif endif - exe 'runtime! autoload/xml/'.g:html_omni_flavor.'.vim' - " This one is necessary because we don't know if - " g:html_omni_flavor file exists and was sourced + " With that if we still have bloated memory but create new buffer + " variables only by linking to existing g:variable, not sourcing whole + " file. + if exists('g:xmldata_'.b:html_omni_flavor) + exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor + else + exe 'runtime! autoload/xml/'.b:html_omni_flavor.'.vim' + exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor + endif + " This repetition is necessary because we don't know if + " b:html_omni_flavor file exists and was sourced " Proper checking for files would require iterating through 'rtp' " and could introduce OS dependent mess. - if !exists("g:xmldata_".g:html_omni_flavor) - let g:html_omni_flavor = 'xhtml10s' - runtime! autoload/xml/xhtml10s.vim + if !exists("g:xmldata_".b:html_omni_flavor) + if &ft == 'html' + let b:html_omni_flavor = 'html401t' + else + let b:html_omni_flavor = 'xhtml10s' + endif + endif + if exists('g:xmldata_'.b:html_omni_flavor) + exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor + else + exe 'runtime! autoload/xml/'.b:html_omni_flavor.'.vim' + exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor endif - - exe 'let g:html_omni = g:xmldata_'.g:html_omni_flavor - - " Free some memory - exe 'unlet! g:xmldata_'.g:html_omni_flavor - - "call htmlcomplete#LoadData() endfunction " }}} " vim:set foldmethod=marker: diff --git a/runtime/autoload/pythoncomplete.vim b/runtime/autoload/pythoncomplete.vim index 8365d78a1d..ee217ed2ce 100644 --- a/runtime/autoload/pythoncomplete.vim +++ b/runtime/autoload/pythoncomplete.vim @@ -1,20 +1,16 @@ "pythoncomplete.vim - Omni Completion for python -" Maintainer: Aaron Griffin -" Version: 0.3 -" Last Updated: 23 January 2006 +" Maintainer: Aaron Griffin <aaronmgriffin@gmail.com> +" Version: 0.5 +" Last Updated: 19 April 2006 " -" v0.3 Changes: -" added top level def parsing -" for safety, call returns are not evaluated -" handful of parsing changes -" trailing ( and . characters -" argument completion on open parens -" stop parsing at current line - ++performance, local var resolution +" Yeah, I skipped a version number - 0.4 was never public. +" It was a bugfix version on top of 0.3. This is a complete +" rewrite. " -" TODO -" RExec subclass -" Code cleanup + make class -" use internal dict, not globals() +" TODO: +" User defined docstrings aren't handled right... +" 'info' item output can use some formatting work +" Add an "unsafe eval" mode, to allow for return type evaluation if !has('python') echo "Error: Required vim compiled with +python" @@ -23,12 +19,12 @@ endif function! pythoncomplete#Complete(findstart, base) "findstart = 1 when we need to get the text length - if a:findstart + if a:findstart == 1 let line = getline('.') let idx = col('.') while idx > 0 let idx -= 1 - let c = line[idx-1] + let c = line[idx] if c =~ '\w' continue elseif ! c =~ '\.' @@ -42,310 +38,530 @@ function! pythoncomplete#Complete(findstart, base) return idx "findstart = 0 when we need to return the list of completions else - execute "python get_completions('" . a:base . "')" + "vim no longer moves the cursor upon completion... fix that + let line = getline('.') + let idx = col('.') + let cword = '' + while idx > 0 + let idx -= 1 + let c = line[idx] + if c =~ '\w' || c =~ '\.' + let cword = c . cword + continue + elseif strlen(cword) > 0 || idx == 0 + break + endif + endwhile + execute "python vimcomplete('" . cword . "', '" . a:base . "')" return g:pythoncomplete_completions endif endfunction function! s:DefPython() python << PYTHONEOF -import vim, sys, types -import __builtin__ -import tokenize, keyword, cStringIO - -LOCALDEFS = \ - ['LOCALDEFS', 'clean_up','eval_source_code', \ - 'get_completions', '__builtin__', '__builtins__', \ - 'dbg', '__name__', 'vim', 'sys', 'parse_to_end', \ - 'parse_statement', 'tokenize', 'keyword', 'cStringIO', \ - 'debug_level', 'safe_eval', '_ctor', 'get_arguments', \ - 'strip_calls', 'types', 'parse_block'] - -def dbg(level,msg): - debug_level = 1 +import sys, tokenize, cStringIO, types +from token import NAME, DEDENT, NEWLINE, STRING + +debugstmts=[] +def dbg(s): debugstmts.append(s) +def showdbg(): + for d in debugstmts: print "DBG: %s " % d + +def vimcomplete(context,match): + global debugstmts + debugstmts = [] try: - debug_level = vim.eval("g:pythoncomplete_debug_level") - except: - pass - if level <= debug_level: print(msg) + import vim + def complsort(x,y): + return x['abbr'] > y['abbr'] + cmpl = Completer() + cmpl.evalsource('\n'.join(vim.current.buffer),vim.eval("line('.')")) + all = cmpl.get_completions(context,match) + all.sort(complsort) + dictstr = '[' + # have to do this for double quoting + for cmpl in all: + dictstr += '{' + for x in cmpl: dictstr += '"%s":"%s",' % (x,cmpl[x]) + dictstr += '"icase":0},' + if dictstr[-1] == ',': dictstr = dictstr[:-1] + dictstr += ']' + dbg("dict: %s" % dictstr) + vim.command("silent let g:pythoncomplete_completions = %s" % dictstr) + #dbg("Completion dict:\n%s" % all) + except vim.error: + dbg("VIM Error: %s" % vim.error) -def strip_calls(stmt): - parsed='' - level = 0 - for c in stmt: - if c in ['[','(']: - level += 1 - elif c in [')',']']: - level -= 1 - elif level == 0: - parsed += c - ##dbg(10,"stripped: %s" % parsed) - return parsed +class Completer(object): + def __init__(self): + self.compldict = {} + self.parser = PyParser() -def get_completions(base): - stmt = vim.eval('expand("<cWORD>")') - #dbg(1,"statement: %s - %s" % (stmt, base)) - stmt = stmt+base - eval_source_code() + def evalsource(self,text,line=0): + sc = self.parser.parse(text,line) + src = sc.get_code() + dbg("source: %s" % src) + try: exec(src) in self.compldict + except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1])) + for l in sc.locals: + try: exec(l) in self.compldict + except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l)) - try: - ridx = stmt.rfind('.') - if stmt[-1] == '(': - match = "" - stmt = strip_calls(stmt[:len(stmt)-1]) - all = get_arguments(eval(stmt)) - elif ridx == -1: - match = stmt - all = globals() + __builtin__.__dict__ - else: - match = stmt[ridx+1:] - stmt = strip_calls(stmt[:ridx]) - all = eval(stmt).__dict__ + def _cleanstr(self,doc): + return doc.replace('"',' ')\ + .replace("'",' ')\ + .replace('\n',' ')\ + .replace('\r',' ')\ + .replace('
',' ') - #dbg(15,"completions for: %s, match=%s" % (stmt,match)) - completions = [] - if type(all) == types.DictType: + def get_arguments(self,func_obj): + def _ctor(obj): + try: return class_ob.__init__.im_func + except AttributeError: + for base in class_ob.__bases__: + rc = _find_constructor(base) + if rc is not None: return rc + return None + + arg_offset = 1 + if type(func_obj) == types.ClassType: func_obj = _ctor(func_obj) + elif type(func_obj) == types.MethodType: func_obj = func_obj.im_func + else: arg_offset = 0 + + arg_text = ')' + if type(func_obj) in [types.FunctionType, types.LambdaType]: + try: + cd = func_obj.func_code + real_args = cd.co_varnames[arg_offset:cd.co_argcount] + defaults = func_obj.func_defaults or [] + defaults = [map(lambda name: "=%s" % name, defaults)] + defaults = [""] * (len(real_args)-len(defaults)) + defaults + items = map(lambda a,d: a+d, real_args, defaults) + if func_obj.func_code.co_flags & 0x4: + items.append("...") + if func_obj.func_code.co_flags & 0x8: + items.append("***") + arg_text = ", ".join(items) + ')' + + except: + dbg("completion: %s: %s" % (sys.exc_info()[0],sys.exc_info()[1])) + pass + if len(arg_text) == 0: + # The doc string sometimes contains the function signature + # this works for alot of C modules that are part of the + # standard library + doc = func_obj.__doc__ + if doc: + doc = doc.lstrip() + pos = doc.find('\n') + if pos > 0: + sigline = doc[:pos] + lidx = sigline.find('(') + ridx = sigline.find(')') + if lidx > 0 and ridx > 0: + arg_text = sigline[lidx+1:ridx] + ')' + return arg_text + + def get_completions(self,context,match): + dbg("get_completions('%s','%s')" % (context,match)) + stmt = '' + if context: stmt += str(context) + if match: stmt += str(match) + try: + result = None + all = {} + ridx = stmt.rfind('.') + if len(stmt) > 0 and stmt[-1] == '(': + #TODO + result = eval(_sanitize(stmt[:-1]), self.compldict) + doc = result.__doc__ + if doc == None: doc = '' + args = self.get_arguments(res) + return [{'word':self._cleanstr(args),'info':self._cleanstr(doc),'kind':'p'}] + elif ridx == -1: + match = stmt + all = self.compldict + else: + match = stmt[ridx+1:] + stmt = _sanitize(stmt[:ridx]) + result = eval(stmt, self.compldict) + all = dir(result) + + dbg("completing: stmt:%s" % stmt) + completions = [] + + try: maindoc = result.__doc__ + except: maindoc = ' ' + if maindoc == None: maindoc = ' ' for m in all: - if m.find('_') != 0 and m.find(match) == 0 and \ - m not in LOCALDEFS: - #dbg(25,"matched... %s, %s" % (m, m.find(match))) - typestr = str(all[m]) - if "function" in typestr: m += '(' - elif "method" in typestr: m += '(' - elif "module" in typestr: m += '.' - elif "class" in typestr: m += '(' - completions.append(m) - completions.sort() + if m == "_PyCmplNoType": continue #this is internal + try: + dbg('possible completion: %s' % m) + if m.find(match) == 0: + if result == None: inst = all[m] + else: inst = getattr(result,m) + try: doc = inst.__doc__ + except: doc = maindoc + typestr = str(inst) + if doc == None or doc == '': doc = maindoc + + wrd = m[len(match):] + c = {'word':wrd, 'abbr':m, 'info':self._cleanstr(doc),'kind':'m'} + if "function" in typestr: + c['word'] += '(' + c['abbr'] += '(' + self._cleanstr(self.get_arguments(inst)) + c['kind'] = 'f' + elif "method" in typestr: + c['word'] += '(' + c['abbr'] += '(' + self._cleanstr(self.get_arguments(inst)) + c['kind'] = 'f' + elif "module" in typestr: + c['word'] += '.' + c['kind'] = 'm' + elif "class" in typestr: + c['word'] += '(' + c['abbr'] += '(' + c['kind']='c' + completions.append(c) + except: + i = sys.exc_info() + dbg("inner completion: %s,%s [stmt='%s']" % (i[0],i[1],stmt)) + return completions + except: + i = sys.exc_info() + dbg("completion: %s,%s [stmt='%s']" % (i[0],i[1],stmt)) + return [] + +class Scope(object): + def __init__(self,name,indent): + self.subscopes = [] + self.docstr = '' + self.locals = [] + self.parent = None + self.name = name + self.indent = indent + + def add(self,sub): + #print 'push scope: [%s@%s]' % (sub.name,sub.indent) + sub.parent = self + self.subscopes.append(sub) + return sub + + def doc(self,str): + """ Clean up a docstring """ + d = str.replace('\n',' ') + d = d.replace('\t',' ') + while d.find(' ') > -1: d = d.replace(' ',' ') + while d[0] in '"\'\t ': d = d[1:] + while d[-1] in '"\'\t ': d = d[:-1] + self.docstr = d + + def local(self,loc): + if not self._hasvaralready(loc): + self.locals.append(loc) + + def copy_decl(self,indent=0): + """ Copy a scope's declaration only, at the specified indent level - not local variables """ + return Scope(self.name,indent) + + def _hasvaralready(self,test): + "Convienance function... keep out duplicates" + if test.find('=') > -1: + var = test.split('=')[0].strip() + for l in self.locals: + if l.find('=') > -1 and var == l.split('=')[0].strip(): + return True + return False + + def get_code(self): + # we need to start with this, to fix up broken completions + # hopefully this name is unique enough... + str = '"""'+self.docstr+'"""\n' + str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n' + for sub in self.subscopes: + str += sub.get_code() + #str += '\n'.join(self.locals)+'\n' + + return str + + def pop(self,indent): + #print 'pop scope: [%s] to [%s]' % (self.indent,indent) + outer = self + while outer.parent != None and outer.indent >= indent: + outer = outer.parent + return outer + + def currentindent(self): + #print 'parse current indent: %s' % self.indent + return ' '*self.indent + + def childindent(self): + #print 'parse child indent: [%s]' % (self.indent+1) + return ' '*(self.indent+1) + +class Class(Scope): + def __init__(self, name, supers, indent): + Scope.__init__(self,name,indent) + self.supers = supers + def copy_decl(self,indent=0): + c = Class(self.name,self.supers,indent) + for s in self.subscopes: + c.add(s.copy_decl(indent+1)) + return c + def get_code(self): + str = '%sclass %s' % (self.currentindent(),self.name) + if len(self.supers) > 0: str += '(%s)' % ','.join(self.supers) + str += ':\n' + if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n' + if len(self.subscopes) > 0: + for s in self.subscopes: str += s.get_code() else: - completions.append(all) - #dbg(10,"all completions: %s" % completions) - vim.command("let g:pythoncomplete_completions = %s" % completions) - except: - vim.command("let g:pythoncomplete_completions = []") - #dbg(1,"exception: %s" % sys.exc_info()[1]) - clean_up() - -def get_arguments(func_obj): - def _ctor(obj): - try: - return class_ob.__init__.im_func - except AttributeError: - for base in class_ob.__bases__: - rc = _find_constructor(base) - if rc is not None: return rc - return None - - arg_offset = 1 - if type(func_obj) == types.ClassType: func_obj = _ctor(func_obj) - elif type(func_obj) == types.MethodType: func_obj = func_obj.im_func - else: arg_offset = 0 - - #dbg(20,"%s, offset=%s" % (str(func_obj), arg_offset)) - - arg_text = '' - if type(func_obj) in [types.FunctionType, types.LambdaType]: + str += '%spass\n' % self.childindent() + return str + + +class Function(Scope): + def __init__(self, name, params, indent): + Scope.__init__(self,name,indent) + self.params = params + def copy_decl(self,indent=0): + return Function(self.name,self.params,indent) + def get_code(self): + str = "%sdef %s(%s):\n" % \ + (self.currentindent(),self.name,','.join(self.params)) + if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n' + str += "%spass\n" % self.childindent() + return str + +class PyParser: + def __init__(self): + self.top = Scope('global',0) + self.scope = self.top + + def _parsedotname(self,pre=None): + #returns (dottedname, nexttoken) + name = [] + if pre == None: + tokentype, token, indent = self.next() + if tokentype != NAME and token != '*': + return ('', token) + else: token = pre + name.append(token) + while True: + tokentype, token, indent = self.next() + if token != '.': break + tokentype, token, indent = self.next() + if tokentype != NAME: break + name.append(token) + return (".".join(name), token) + + def _parseimportlist(self): + imports = [] + while True: + name, token = self._parsedotname() + if not name: break + name2 = '' + if token == 'as': name2, token = self._parsedotname() + imports.append((name, name2)) + while token != "," and "\n" not in token: + tokentype, token, indent = self.next() + if token != ",": break + return imports + + def _parenparse(self): + name = '' + names = [] + level = 1 + while True: + tokentype, token, indent = self.next() + if token in (')', ',') and level == 1: + names.append(name) + name = '' + if token == '(': + level += 1 + elif token == ')': + level -= 1 + if level == 0: break + elif token == ',' and level == 1: + pass + else: + name += str(token) + return names + + def _parsefunction(self,indent): + self.scope=self.scope.pop(indent) + tokentype, fname, ind = self.next() + if tokentype != NAME: return None + + tokentype, open, ind = self.next() + if open != '(': return None + params=self._parenparse() + + tokentype, colon, ind = self.next() + if colon != ':': return None + + return Function(fname,params,indent) + + def _parseclass(self,indent): + self.scope=self.scope.pop(indent) + tokentype, cname, ind = self.next() + if tokentype != NAME: return None + + super = [] + tokentype, next, ind = self.next() + if next == '(': + super=self._parenparse() + elif next != ':': return None + + return Class(cname,super,indent) + + def _parseassignment(self): + assign='' + tokentype, token, indent = self.next() + if tokentype == tokenize.STRING or token == 'str': + return '""' + elif token == '[' or token == 'list': + return '[]' + elif token == '{' or token == 'dict': + return '{}' + elif tokentype == tokenize.NUMBER: + return '0' + elif token == 'open' or token == 'file': + return 'file' + elif token == 'None': + return '_PyCmplNoType()' + elif token == 'type': + return 'type(_PyCmplNoType)' #only for method resolution + else: + assign += token + level = 0 + while True: + tokentype, token, indent = self.next() + if token in ('(','{','['): + level += 1 + elif token in (']','}',')'): + level -= 1 + if level == 0: break + elif level == 0: + if token in (';','\n'): break + assign += token + return "%s" % assign + + def next(self): + type, token, (lineno, indent), end, self.parserline = self.gen.next() + if lineno == self.curline: + #print 'line found [%s] scope=%s' % (line.replace('\n',''),self.scope.name) + self.currentscope = self.scope + return (type, token, indent) + + def _adjustvisibility(self): + newscope = Scope('result',0) + scp = self.currentscope + while scp != None: + if type(scp) == Function: + slice = 0 + #Handle 'self' params + if scp.parent != None and type(scp.parent) == Class: + slice = 1 + p = scp.params[0] + i = p.find('=') + if i != -1: p = p[:i] + newscope.local('%s = %s' % (scp.params[0],scp.parent.name)) + for p in scp.params[slice:]: + i = p.find('=') + if i == -1: + newscope.local('%s = _PyCmplNoType()' % p) + else: + newscope.local('%s = %s' % (p[:i],_sanitize(p[i+1]))) + + for s in scp.subscopes: + ns = s.copy_decl(0) + newscope.add(ns) + for l in scp.locals: newscope.local(l) + scp = scp.parent + + self.currentscope = newscope + return self.currentscope + + #p.parse(vim.current.buffer[:],vim.eval("line('.')")) + def parse(self,text,curline=0): + self.curline = int(curline) + buf = cStringIO.StringIO(''.join(text) + '\n') + self.gen = tokenize.generate_tokens(buf.readline) + self.currentscope = self.scope + try: - cd = func_obj.func_code - real_args = cd.co_varnames[arg_offset:cd.co_argcount] - defaults = func_obj.func_defaults or [] - defaults = list(map(lambda name: "=%s" % name, defaults)) - defaults = [""] * (len(real_args)-len(defaults)) + defaults - items = map(lambda a,d: a+d, real_args, defaults) - if func_obj.func_code.co_flags & 0x4: - items.append("...") - if func_obj.func_code.co_flags & 0x8: - items.append("***") - arg_text = ", ".join(items) + ')' + freshscope=True + while True: + tokentype, token, indent = self.next() + #print 'main: token=[%s] indent=[%s]' % (token,indent) - except: - #dbg(1,"exception: %s" % sys.exc_info()[1]) + if tokentype == DEDENT: + self.scope = self.scope.pop(indent) + elif token == 'def': + func = self._parsefunction(indent) + if func == None: + print "function: syntax error..." + continue + freshscope = True + self.scope = self.scope.add(func) + elif token == 'class': + cls = self._parseclass(indent) + if cls == None: + print "class: syntax error..." + continue + freshscope = True + self.scope = self.scope.add(cls) + + elif token == 'import': + imports = self._parseimportlist() + for mod, alias in imports: + loc = "import %s" % mod + if len(alias) > 0: loc += " as %s" % alias + self.scope.local(loc) + freshscope = False + elif token == 'from': + mod, token = self._parsedotname() + if not mod or token != "import": + print "from: syntax error..." + continue + names = self._parseimportlist() + for name, alias in names: + loc = "from %s import %s" % (mod,name) + if len(alias) > 0: loc += " as %s" % alias + self.scope.local(loc) + freshscope = False + elif tokentype == STRING: + if freshscope: self.scope.doc(token) + elif tokentype == NAME: + name,token = self._parsedotname(token) + if token == '=': + stmt = self._parseassignment() + if stmt != None: + self.scope.local("%s = %s" % (name,stmt)) + freshscope = False + except StopIteration: #thrown on EOF pass - if len(arg_text) == 0: - # The doc string sometimes contains the function signature - # this works for alot of C modules that are part of the - # standard library - doc = getattr(func_obj, '__doc__', '') - if doc: - doc = doc.lstrip() - pos = doc.find('\n') - if pos > 0: - sigline = doc[:pos] - lidx = sigline.find('(') - ridx = sigline.find(')') - retidx = sigline.find('->') - ret = sigline[retidx+2:].strip() - if lidx > 0 and ridx > 0: - arg_text = sigline[lidx+1:ridx] + ')' - if len(ret) > 0: arg_text += ' #returns |