diff --git a/.vimrc b/.vimrc index a956fe7..8652cd6 100644 --- a/.vimrc +++ b/.vimrc @@ -156,7 +156,7 @@ nnoremap ff :call g:Jsbeautify():retab! let g:pydiction_location = '/home/gryf/.vim/after/ftplugin/pytdiction/complete-dict' "}}} "TagListToo {{{2 -let g:VerticalToolWindowSide = 'right' +let g:TaglistTooPosition = "right" nmap t :TlistToo "}}} "Tagbar {{{2 diff --git a/autoload/taglisttoo/__init__.py b/autoload/taglisttoo/__init__.py new file mode 100644 index 0000000..69e7739 --- /dev/null +++ b/autoload/taglisttoo/__init__.py @@ -0,0 +1,233 @@ +""" +Copyright (c) 2005 - 2011, Eric Van Dewoestine +All rights reserved. + +Redistribution and use of this software in source and binary forms, with +or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Eric Van Dewoestine nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission of + Eric Van Dewoestine. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +import os +import re +import subprocess +import tempfile +import vim + +def ctags(lang, types, filename): + ctags = vim.eval('g:Tlist_Ctags_Cmd') + + startupinfo = None + if os.name == 'nt': + startupinfo = subprocess.STARTUPINFO() + if hasattr(subprocess, '_subprocess'): + startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW + else: + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + + stdoutfile = tempfile.TemporaryFile() + stderrfile = tempfile.TemporaryFile() + try: + process = subprocess.Popen( + [ + ctags, + '-f', '-', + '--format=2', + '--excmd=pattern', + '--fields=nks', + '--sort=no', + '--language-force=%s' % lang, + '--%s-types=%s' % (lang, types), + filename, + ], + stdout=stdoutfile, + stderr=stderrfile, + stdin=subprocess.PIPE, + startupinfo=startupinfo, + ) + + retcode = process.wait() + if retcode != 0: + stderrfile.seek(0) + return (retcode, stderrfile.read()) + + stdoutfile.seek(0) + return (retcode, stdoutfile.read()) + + finally: + stdoutfile.close() + stderrfile.close() + +def jsctags(filename): + jsctags = vim.eval('g:Tlist_JSctags_Cmd') + + startupinfo = None + if os.name == 'nt': + startupinfo = subprocess.STARTUPINFO() + if hasattr(subprocess, '_subprocess'): + startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW + else: + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + + temp = tempfile.mkstemp()[1] + try: + process = subprocess.Popen( + [ + jsctags, + '-o', temp, + filename, + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + startupinfo=startupinfo, + ) + + retcode = process.wait() + if retcode != 0: + return (retcode, process.communicate()[1].strip()) + return (retcode, open(temp).read()) + finally: + os.unlink(temp) + +def parse(filename, patterns): + f = open(filename, 'r') + contents = f.read() + f.close() + + for i, info in enumerate(patterns): + flags = re.DOTALL | re.MULTILINE + if len(info) > 3: + if info[3] == 'i': + flags |= re.IGNORECASE + info = info[:3] + patterns[i] = info + + try: + info[1] = re.compile(info[1], flags) + except: + print 'Failed to parse pattern: %s' % info[1] + raise + + offsets = FileOffsets.compile(filename) + + results = [] + for ptype, regex, group in patterns: + for match in regex.finditer(contents): + start = match.start() + end = match.end() + line = offsets.offsetToLineColumn(start)[0] + col = 1 + + if group.isdigit(): + name = match.group(int(group)) + else: + matched = contents[start:end] + name = regex.sub(group, matched) + + first = offsets.getLineStart(line) + last = offsets.getLineEnd(offsets.offsetToLineColumn(end)[0]) + pattern = contents[first:last] + + # pattern cannot span lines + if '\n' in pattern: + lines = pattern.split('\n') + for i, l in enumerate(lines): + if name in l: + pattern = l + line += i + col = l.index(name) + 1 + break + + # still multiline, so just use the first one + if '\n' in pattern: + pattern = lines[0] + elif name in pattern: + col = pattern.index(name) + 1 + + # remove ctrl-Ms + pattern = pattern.replace('\r', '') + + results.append({ + 'type': ptype, + 'name': name, + 'pattern': '^%s$' % pattern, + 'line': line, + 'column': col, + }) + + return results + +class FileOffsets(object): + def __init__(self): + self.offsets = [] + + @staticmethod + def compile(filename): + offsets = FileOffsets() + offsets.compileOffsets(filename) + return offsets; + + def compileOffsets(self, filename): + f = file(filename, 'r') + try: + self.offsets.append(0); + + offset = 0; + for line in f: + offset += len(line) + self.offsets.append(offset) + finally: + f.close() + + def offsetToLineColumn(self, offset): + if offset <= 0: + return [1, 1] + + bot = -1 + top = len(self.offsets) - 1 + while (top - bot) > 1: + mid = (top + bot) / 2 + if self.offsets[mid] < offset: + bot = mid + else: + top = mid + + if self.offsets[top] > offset: + top -= 1 + + line = top + 1 + column = 1 + offset - self.offsets[top] + return [line, column] + + def getLineStart(self, line): + return self.offsets[line - 1] + + def getLineEnd(self, line): + if len(self.offsets) == line: + return self.offsets[len(self.offsets) - 1] + + return self.offsets[line] - 1; diff --git a/autoload/taglisttoo/__init__.pyc b/autoload/taglisttoo/__init__.pyc new file mode 100644 index 0000000..fe6e999 Binary files /dev/null and b/autoload/taglisttoo/__init__.pyc differ diff --git a/autoload/taglisttoo/lang/ant.vim b/autoload/taglisttoo/lang/ant.vim new file mode 100644 index 0000000..de14df3 --- /dev/null +++ b/autoload/taglisttoo/lang/ant.vim @@ -0,0 +1,48 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#ant#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['p', "]*)name\\s*=\\s*['\"](.*?)['\"]", 1], + \ ['i', "]*)file\\s*=\\s*['\"](.*?)['\"]", 1], + \ ['t', "]*)name\\s*=\\s*['\"](.*?)['\"]", 1], + \ ['r', "]*)name\\s*=\\s*['\"](.*?)['\"]", 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/dtd.vim b/autoload/taglisttoo/lang/dtd.vim new file mode 100644 index 0000000..21bd866 --- /dev/null +++ b/autoload/taglisttoo/lang/dtd.vim @@ -0,0 +1,45 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#dtd#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['e', '^\s*]*?name=['\"](.*?)['\"]", 1], + \ ['i', "<([a-z]*?)\\s+[^>]*?id=['\"](.*?)['\"]", '\1 \2'], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/htmldjango.vim b/autoload/taglisttoo/lang/htmldjango.vim new file mode 100644 index 0000000..bb67317 --- /dev/null +++ b/autoload/taglisttoo/lang/htmldjango.vim @@ -0,0 +1,47 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#htmldjango#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['a', "]*?name=['\"](.*?)['\"]", 1], + \ ['i', "<([a-z]*?)\\s+[^>]*?id=['\"](.*?)['\"]", '\1 \2'], + \ ['b', '\{%?\s*block\s+(\w+)', 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/htmljinja.vim b/autoload/taglisttoo/lang/htmljinja.vim new file mode 100644 index 0000000..f3948c4 --- /dev/null +++ b/autoload/taglisttoo/lang/htmljinja.vim @@ -0,0 +1,48 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#htmljinja#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['a', "]*?name=['\"](.*?)['\"]", 1], + \ ['i', "<([a-z]*?)\\s+[^>]*?id=['\"](.*?)['\"]", '\1 \2'], + \ ['b', '\{%?\s*block\s+(\w+)', 1], + \ ['m', '\{%-?\s*macro\s+(\w+)\s*\(', 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/java.vim b/autoload/taglisttoo/lang/java.vim new file mode 100644 index 0000000..ced1fe1 --- /dev/null +++ b/autoload/taglisttoo/lang/java.vim @@ -0,0 +1,90 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Format(types, tags) {{{ +function! taglisttoo#lang#java#Format(types, tags) + let formatter = taglisttoo#util#Formatter(a:tags) + call formatter.filename() + + let package = filter(copy(a:tags), 'v:val.type == "p"') + call formatter.format(a:types['p'], package, '') + + let classes = filter(copy(a:tags), 'v:val.type == "c"') + + " sort classes alphabetically except for the primary containing class. + if len(classes) > 1 && g:Tlist_Sort_Type == 'name' + let classes = [classes[0]] + sort(classes[1:], 'taglisttoo#util#SortTags') + endif + + for class in classes + call formatter.blank() + + let visibility = taglisttoo#util#GetVisibility(class) + call formatter.heading(a:types['c'], class, '') + + let fields = filter(copy(a:tags), + \ 'v:val.type == "f" && v:val.parent =~ "class:.*\\<" . class.name . "$"') + call formatter.format(a:types['f'], fields, "\t") + + let methods = filter(copy(a:tags), + \ 'v:val.type == "m" && v:val.parent =~ "class:.*\\<" . class.name . "$"') + call formatter.format(a:types['m'], methods, "\t") + endfor + + let interfaces = filter(copy(a:tags), 'v:val.type == "i"') + if g:Tlist_Sort_Type == 'name' + call sort(interfaces, 'taglisttoo#util#SortTags') + endif + for interface in interfaces + call formatter.blank() + + let visibility = taglisttoo#util#GetVisibility(interface) + call formatter.heading(a:types['i'], interface, '') + + let fields = filter(copy(a:tags), + \ 'v:val.type == "f" && v:val.parent =~ "interface:.*\\<" . interface.name . "$"') + call formatter.format(a:types['f'], fields, "\t") + + let methods = filter(copy(a:tags), + \ 'v:val.type == "m" && v:val.parent =~ "interface:.*\\<" . interface.name . "$"') + call formatter.format(a:types['m'], methods, "\t") + endfor + + return formatter +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/javascript.vim b/autoload/taglisttoo/lang/javascript.vim new file mode 100644 index 0000000..7d5f936 --- /dev/null +++ b/autoload/taglisttoo/lang/javascript.vim @@ -0,0 +1,303 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2011, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Global Variabls {{{ +if !exists('g:TaglistTooJSctags') + let g:TaglistTooJSctags = 1 +endif +" }}} + +function! taglisttoo#lang#javascript#Format(types, tags) " {{{ + if !g:TaglistTooJSctags || !exists('g:Tlist_JSctags_Cmd') + return s:FormatRegexResults(a:types, a:tags) + endif + return s:FormatJSctagsResults(a:types, a:tags) +endfunction " }}} + +function! s:FormatJSctagsResults(types, tags) " {{{ + let formatter = taglisttoo#util#Formatter(a:tags) + call formatter.filename() + + let functions = filter(copy(a:tags), 'v:val.type == "f" && v:val.namespace == ""') + if len(functions) > 0 + call formatter.blank() + call formatter.format(a:types['f'], functions, '') + endif + + let members = filter(copy(a:tags), 'v:val.name == "includeScript"') + + let objects = filter(copy(a:tags), 'v:val.jstype == "Object"') + for object in objects + if object.namespace != '' + let object.name = object.namespace . '.' . object.name + endif + + call formatter.blank() + call formatter.heading(a:types['o'], object, '') + + let members = filter(copy(a:tags), 'v:val.type == "f" && v:val.namespace == object.name') + call formatter.format(a:types['f'], members, "\t") + endfor + + return formatter +endfunction " }}} + +function! s:FormatRegexResults(types, tags) " {{{ + let pos = getpos('.') + + let formatter = taglisttoo#util#Formatter(a:tags) + call formatter.filename() + + let object_contents = [] + + let objects = filter(copy(a:tags), 'v:val.type == "o"') + let members = filter(copy(a:tags), 'v:val.type == "m"') + let functions = filter(copy(a:tags), + \ 'v:val.type == "f" && v:val.pattern =~ "\\"') + let object_bounds = {} + for object in objects + let object_start = object.line + call cursor(object_start, 1) + while search('{', 'W') && s:SkipComments() + " no op + endwhile + let object_end = searchpair('{', '', '}', 'W', 's:SkipComments()') + + let methods = [] + let indexes = [] + let index = 0 + for fct in members + if len(fct) > 3 + let fct_line = fct.line + if fct_line > object_start && fct_line < object_end + call add(methods, fct) + elseif fct_line > object_end + break + elseif fct_line < object_end + call add(indexes, index) + endif + endif + let index += 1 + endfor + call reverse(indexes) + for i in indexes + call remove(members, i) + endfor + + let indexes = [] + let index = 0 + for fct in functions + if len(fct) > 3 + let fct_line = fct.line + if fct_line > object_start && fct_line < object_end + call add(methods, fct) + call add(indexes, index) + elseif fct_line == object_start + call add(indexes, index) + elseif fct_line > object_end + break + endif + endif + let index += 1 + endfor + call reverse(indexes) + for i in indexes + call remove(functions, i) + endfor + + if len(methods) > 0 + let parent_object = s:GetParentObject( + \ object_contents, object_bounds, object_start, object_end) + " remove methods from the parent if necessary + if len(parent_object) + call filter(parent_object.methods, 'index(methods, v:val) == -1') + endif + let object_bounds[string(object)] = [object_start, object_end] + call add(object_contents, {'object': object, 'methods': methods}) + endif + endfor + + if len(functions) > 0 + call formatter.blank() + call formatter.format(a:types['f'], functions, '') + endif + + if g:Tlist_Sort_Type == 'name' + call sort(object_contents, function('s:ObjectComparator')) + endif + + for object_content in object_contents + call formatter.blank() + call formatter.heading(a:types['o'], object_content.object, '') + call formatter.format(a:types['f'], object_content.methods, "\t") + endfor + + call setpos('.', pos) + + return formatter +endfunction " }}} + +function! taglisttoo#lang#javascript#Parse(file, settings) " {{{ + if g:TaglistTooJSctags && !exists('g:Tlist_JSctags_Cmd') + if executable('jsctags') + let g:Tlist_JSctags_Cmd = 'jsctags' + elseif executable('javascripttags') + let g:Tlist_JSctags_Cmd = 'javascripttags' + endif + endif + + if !g:TaglistTooJSctags || !exists('g:Tlist_JSctags_Cmd') + return s:ParseRegex(a:file, a:settings) + endif + return s:ParseJSctags(a:file, a:settings) +endfunction " }}} + +function! s:ParseJSctags(file, settings) " {{{ +python << PYTHONEOF +retcode, result = taglisttoo.jsctags(vim.eval('a:file')) +vim.command('let retcode = %i' % retcode) +vim.command("let result = '%s'" % result.replace("'", "''")) +PYTHONEOF + + if retcode + call s:EchoError('jsctags failed with error code: ' . retcode) + return + endif + + if has('win32') || has('win64') || has('win32unix') + let result = substitute(result, "\\n", '\n', 'g') + endif + + let results = split(result, '\n') + while len(results) && results[0] =~ '^!_' + call remove(results, 0) + endwhile + + let types = keys(a:settings.tags) + let parsed_results = [] + for result in results + " some results use G;" (e.g. 1956G;") as the pattern... skip those + " for now since taglist expects actual patterns. + if result !~ '\t\/\^' + continue + endif + + let pre = substitute(result, '\(.\{-}\)\t\/\^.*', '\1', '') + let pattern = substitute(result, '.\{-}\(\/\^.*\/;"\).*', '\1', '') + let post = substitute(result, '.\{-}\/\^.*\/;"\t', '', '') + + let [name, filename] = split(pre, '\t') + let parts = split(post, '\t') + let [type, line_str] = parts[:1] + exec 'let line = ' . substitute(line_str, 'lineno:', '', '') + let pattern = substitute(pattern, '^/\(.*\)/;"$', '\1', '') + + let jstypes = filter(copy(parts), 'v:val =~ "^type:"') + let namespaces = filter(copy(parts), 'v:val =~ "^namespace:"') + + let jstype = len(jstypes) ? substitute(jstypes[0], '^type:', '', '') : '' + let ns = len(namespaces) ? substitute(namespaces[0], '^namespace:', '', '') : '' + + call add(parsed_results, { + \ 'type': type, + \ 'name': name, + \ 'pattern': pattern, + \ 'line': line, + \ 'namespace': ns, + \ 'jstype': jstype, + \ }) + endfor + + return parsed_results +endfunction " }}} + +function! s:ParseRegex(file, settings) " {{{ + let patterns = [] + " Match Objects/Classes + call add(patterns, ['o', '([A-Za-z0-9_.]+)\s*=\s*\{(\s*[^}]|$)', 1]) + + " prototype.js has Object.extend to extend existing objects. + call add(patterns, ['o', '(?:var\s+)?\b([A-Z][A-Za-z0-9_.]+)\s*=\s*Object\.extend\s*\(', 1]) + call add(patterns, ['o', '\bObject\.extend\s*\(\b([A-Z][A-Za-z0-9_.]+)\s*,\s*\{', 1]) + + " mootools uses 'new Class' + call add(patterns, ['o', '(?:var\s+)?\b([A-Z][A-Za-z0-9_.]+)\s*=\s*new\s+Class\s*\(', 1]) + + " firebug uses extend + call add(patterns, ['o', '(?:var\s+)?\b([A-Z][A-Za-z0-9_.]+)\s*=\s*extend\s*\(', 1]) + + " vimperator uses function MyClass () + call add(patterns, ['o', 'function\s+\b([A-Z][A-Za-z0-9_.]+)\s*\(', 1]) + " vimperator uses var = (function() + call add(patterns, ['o', '([A-Za-z0-9_.]+)\s*=\s*\(function\s*\(', 1]) + + " Match Functions + call add(patterns, ['f', '\bfunction\s+([a-zA-Z0-9_.\$]+?)\s*\(', 1]) + call add(patterns, ['f', '([a-zA-Z0-9_.\$]+?)\s*=\s*function\s*\(', 1]) + + " Match Members + call add(patterns, ['m', '\b([a-zA-Z0-9_.\$]+?)\s*:\s*function\s*\(', 1]) + return taglisttoo#util#Parse(a:file, patterns) +endfunction " }}} + +function s:ObjectComparator(o1, o2) " {{{ + let n1 = a:o1['object'].name + let n2 = a:o2['object'].name + return n1 == n2 ? 0 : n1 > n2 ? 1 : -1 +endfunction " }}} + +function s:SkipComments() " {{{ + let synname = synIDattr(synID(line('.'), col('.'), 1), "name") + return synname =~? '\(comment\|string\)' +endfunction " }}} + +function s:GetParentObject(objects, bounds, start, end) " {{{ + for key in keys(a:bounds) + let range = a:bounds[key] + if range[0] < a:start && range[1] > a:end + for object_content in a:objects + if string(object_content.object) == key + return object_content + endif + endfor + break + endif + endfor + return {} +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/jproperties.vim b/autoload/taglisttoo/lang/jproperties.vim new file mode 100644 index 0000000..cac96d8 --- /dev/null +++ b/autoload/taglisttoo/lang/jproperties.vim @@ -0,0 +1,43 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#jproperties#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [['p', '^\s*([^#]+?)\s*=', 1]]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/log4j.vim b/autoload/taglisttoo/lang/log4j.vim new file mode 100644 index 0000000..33a2ce0 --- /dev/null +++ b/autoload/taglisttoo/lang/log4j.vim @@ -0,0 +1,48 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#log4j#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['a', "]*?name=['\"](.*?)['\"]", 1], + \ ['c', "]*?name=['\"](.*?)['\"]", 1], + \ ['l', "]*?name=['\"](.*?)['\"]", 1], + \ ['r', "<(root)\\s*>", 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/php.vim b/autoload/taglisttoo/lang/php.vim new file mode 100644 index 0000000..8e8f6c2 --- /dev/null +++ b/autoload/taglisttoo/lang/php.vim @@ -0,0 +1,142 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Format(types, tags) {{{ +function! taglisttoo#lang#php#Format(types, tags) + let pos = getpos('.') + + let formatter = taglisttoo#util#Formatter(a:tags) + call formatter.filename() + + let top_functions = filter(copy(a:tags), 'v:val.type == "f"') + + let class_contents = [] + let classes = filter(copy(a:tags), 'v:val.type == "c"') + if g:Tlist_Sort_Type == 'name' + call sort(classes, 'taglisttoo#util#SortTags') + endif + for class in classes + let object_start = class.line + call cursor(object_start, 1) + call search('{', 'W') + let object_end = searchpair('{', '', '}', 'W') + + let functions = [] + let indexes = [] + let index = 0 + for fct in top_functions + if len(fct) > 3 + let fct_line = fct.line + if fct_line > object_start && fct_line < object_end + call add(functions, fct) + call add(indexes, index) + endif + endif + let index += 1 + endfor + call reverse(indexes) + for i in indexes + call remove(top_functions, i) + endfor + + call add(class_contents, {'class': class, 'functions': functions}) + endfor + + let interface_contents = [] + let interfaces = filter(copy(a:tags), 'v:val.type == "i"') + if g:Tlist_Sort_Type == 'name' + call sort(interfaces, 'taglisttoo#util#SortTags') + endif + for interface in interfaces + let object_start = interface.line + call cursor(object_start, 1) + call search('{', 'W') + let object_end = searchpair('{', '', '}', 'W') + + let functions = [] + let indexes = [] + let index = 0 + for fct in top_functions + if len(fct) > 3 + let fct_line = fct.line + if fct_line > object_start && fct_line < object_end + call add(functions, fct) + call add(indexes, index) + endif + endif + let index += 1 + endfor + call reverse(indexes) + for i in indexes + call remove(top_functions, i) + endfor + + call add(interface_contents, {'interface': interface, 'functions': functions}) + endfor + + if len(top_functions) > 0 + call formatter.blank() + call formatter.format(a:types['f'], top_functions, '') + endif + + for class_content in class_contents + call formatter.blank() + call formatter.heading(a:types['c'], class_content.class, '') + call formatter.format(a:types['f'], class_content.functions, "\t") + endfor + + for interface_content in interface_contents + call formatter.blank() + call formatter.heading(a:types['i'], interface_content.interface, '') + call formatter.format(a:types['f'], interface_content.functions, "\t") + endfor + + call setpos('.', pos) + + return formatter +endfunction " }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#php#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['f', '\bfunction\s+([a-zA-Z0-9_]+)\s*\(', 1], + \ ['c', '\bclass\s+([a-zA-Z0-9_]+)', 1], + \ ['i', '\binterface\s+([a-zA-Z0-9_]+)', 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/python.vim b/autoload/taglisttoo/lang/python.vim new file mode 100644 index 0000000..69287b8 --- /dev/null +++ b/autoload/taglisttoo/lang/python.vim @@ -0,0 +1,66 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Format(types, tags) {{{ +function! taglisttoo#lang#python#Format(types, tags) + let formatter = taglisttoo#util#Formatter(a:tags) + call formatter.filename() + + let functions = filter(copy(a:tags), 'v:val.type == "f"') + if len(functions) + call formatter.blank() + call formatter.format(a:types['f'], functions, '') + endif + + let classes = filter(copy(a:tags), 'v:val.type == "c"') + if g:Tlist_Sort_Type == 'name' + call sort(classes, 'taglisttoo#util#SortTags') + endif + + for class in classes + call formatter.blank() + call formatter.heading(a:types['c'], class, '') + + let members = filter(copy(a:tags), + \ 'v:val.type == "m" && v:val.parent == "class:" . class.name') + call formatter.format(a:types['m'], members, "\t") + endfor + + return formatter +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/rst.vim b/autoload/taglisttoo/lang/rst.vim new file mode 100644 index 0000000..96becc9 --- /dev/null +++ b/autoload/taglisttoo/lang/rst.vim @@ -0,0 +1,46 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#rst#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['a', '^\s*\.\.\s_((\\:|[^:])+):\s*\n', 1], + \ ['s', '^([^\n]+)\n[=^-]{4,}', 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/sql.vim b/autoload/taglisttoo/lang/sql.vim new file mode 100644 index 0000000..ce346cd --- /dev/null +++ b/autoload/taglisttoo/lang/sql.vim @@ -0,0 +1,57 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#sql#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['g', 'create\s+(?:group|role)\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['u', 'create\s+user\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['p', 'create\s+(?:tablespace|dbspace)\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['s', 'create\s+schema\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['t', 'create\s+(?:temporary\s+)?table\s+(?:if\s+not\s+exists\s+)?[`]?([a-zA-Z0-9_.]+)[`]?', 1, 'i'], + \ ['v', 'create\s+(?:or\s+replace\s+)?view\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['q', 'create\s+sequence\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['x', 'create\s+(?:or\s+replace\s+)?trigger\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['f', 'create\s+(?:or\s+replace\s+)?function\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['c', 'create\s+(?:or\s+replace\s+)?procedure\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ['r', "exec\\s+sp_addrole\\s+['\"]([a-zA-Z0-9_.]+)['\"]", 1, 'i'], + \ ['m', "exec\\s+sp_addlogin\\s+@loginname=['\"](.*?)['\"]", 1, 'i'], + \ ['z', 'alter\s+database.*add\s+filegroup\s+([a-zA-Z0-9_.]+)', 1, 'i'], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/lang/xsd.vim b/autoload/taglisttoo/lang/xsd.vim new file mode 100644 index 0000000..62b2310 --- /dev/null +++ b/autoload/taglisttoo/lang/xsd.vim @@ -0,0 +1,46 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Parse(file, settings) {{{ +function! taglisttoo#lang#xsd#Parse(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['e', "<(?:xs[d]?:)?element\\s+[^>]*?name=['\"](.*?)['\"]", 1], + \ ['t', "<(?:xs[d]?:)?complexType\\s+[^>]*?name=['\"](.*?)['\"]", 1], + \ ]) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/taglist.vim b/autoload/taglisttoo/taglist.vim new file mode 100644 index 0000000..162ffc5 --- /dev/null +++ b/autoload/taglisttoo/taglist.vim @@ -0,0 +1,1252 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2011, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +" Global Variables {{{ +let g:TagListToo = 1 +" }}} + +" Script Variables {{{ + let s:python_path = expand(":h:h") + + " used to prefer one window over another if a buffer is open in more than + " one window. + let s:taglisttoo_prevwinnr = 0 + + let s:taglisttoo_title = g:TagList_title +" }}} + +" Language Settings {{{ +let s:tlist_ant_settings = { + \ 'lang': 'ant', + \ 'parse': 'taglisttoo#lang#ant#Parse', + \ 'tags': { + \ 'p': 'project', + \ 'i': 'import', + \ 'r': 'property', + \ 't': 'target' + \ } + \ } + +" assembly language +let s:tlist_asm_settings = { + \ 'lang': 'asm', 'tags': { + \ 'd': 'define', + \ 'l': 'label', + \ 'm': 'macro', + \ 't': 'type' + \ } + \ } + +" aspperl language +let s:tlist_aspperl_settings = { + \ 'lang': 'asp', 'tags': { + \ 'f': 'function', + \ 's': 'sub', + \ 'v': 'variable' + \ } + \ } + +" aspvbs language +let s:tlist_aspvbs_settings = { + \ 'lang': 'asp', 'tags': { + \ 'f': 'function', + \ 's': 'sub', + \ 'v': 'variable' + \ } + \ } + +" awk language +let s:tlist_awk_settings = {'lang': 'awk', 'tags': {'f': 'function'}} + +" beta language +let s:tlist_beta_settings = { + \ 'lang': 'beta', 'tags': { + \ 'f': 'fragment', + \ 's': 'slot', + \ 'v': 'pattern' + \ } + \ } + +" c language +let s:tlist_c_settings = { + \ 'lang': 'c', 'tags': { + \ 'd': 'macro', + \ 'g': 'enum', + \ 's': 'struct', + \ 'u': 'union', + \ 't': 'typedef', + \ 'v': 'variable', + \ 'f': 'function' + \ } + \ } + +" c++ language +let s:tlist_cpp_settings = { + \ 'lang': 'c++', 'tags': { + \ 'n': 'namespace', + \ 'v': 'variable', + \ 'd': 'macro', + \ 't': 'typedef', + \ 'c': 'class', + \ 'g': 'enum', + \ 's': 'struct', + \ 'u': 'union', + \ 'f': 'function' + \ } + \ } + +" c# language +let s:tlist_cs_settings = { + \ 'lang': 'c#', 'tags': { + \ 'd': 'macro', + \ 't': 'typedef', + \ 'n': 'namespace', + \ 'c': 'class', + \ 'E': 'event', + \ 'g': 'enum', + \ 's': 'struct', + \ 'i': 'interface', + \ 'p': 'properties', + \ 'm': 'method' + \ } + \ } + +" cobol language +let s:tlist_cobol_settings = { + \ 'lang': 'cobol', 'tags': { + \ 'd': 'data', + \ 'f': 'file', + \ 'g': 'group', + \ 'p': 'paragraph', + \ 'P': 'program', + \ 's': 'section' + \ } + \ } + +let s:tlist_dtd_settings = { + \ 'lang': 'dtd', + \ 'parse': 'taglisttoo#lang#dtd#Parse', + \ 'tags': {'e': 'element'} + \ } + +" eiffel language +let s:tlist_eiffel_settings = { + \ 'lang': 'eiffel', 'tags': { + \ 'c': 'class', + \ 'f': 'feature' + \ } + \ } + +" erlang language +let s:tlist_erlang_settings = { + \ 'lang': 'erlang', 'tags': { + \ 'd': 'macro', + \ 'r': 'record', + \ 'm': 'module', + \ 'f': 'function' + \ } + \ } + +" expect (same as tcl) language +let s:tlist_expect_settings = { + \ 'lang': 'tcl', 'tags': { + \ 'c': 'class', + \ 'f': 'method', + \ 'p': 'procedure' + \ } + \ } + +" fortran language +let s:tlist_fortran_settings = { + \ 'lang': 'fortran', 'tags': { + \ 'p': 'program', + \ 'b': 'block data', + \ 'c': 'common', + \ 'e': 'entry', + \ 'i': 'interface', + \ 'k': 'type', + \ 'l': 'label', + \ 'm': 'module', + \ 'n': 'namelist', + \ 't': 'derived', + \ 'v': 'variable', + \ 'f': 'function', + \ 's': 'subroutine' + \ } + \ } + +let s:tlist_html_settings = { + \ 'lang': 'html', + \ 'parse': 'taglisttoo#lang#html#Parse', + \ 'tags': {'a': 'anchor', 'i': 'id', 'f': 'function'} + \ } + +let s:tlist_htmldjango_settings = { + \ 'lang': 'htmldjango', + \ 'parse': 'taglisttoo#lang#htmldjango#Parse', + \ 'tags': {'a': 'anchor', 'i': 'id', 'f': 'function', 'b': 'block'} + \ } + +let s:tlist_htmljinja_settings = { + \ 'lang': 'htmljinja', + \ 'parse': 'taglisttoo#lang#htmljinja#Parse', + \ 'tags': { + \ 'a': 'anchor', + \ 'i': 'id', + \ 'f': 'function', + \ 'm': 'macro', + \ 'b': 'block' + \ } + \ } + +" java language +let s:tlist_java_settings = { + \ 'lang': 'java', + \ 'format': 'taglisttoo#lang#java#Format', + \ 'tags': { + \ 'p': 'package', + \ 'c': 'class', + \ 'i': 'interface', + \ 'f': 'field', + \ 'm': 'method' + \ } + \ } + +let s:tlist_javascript_settings = { + \ 'lang': 'javascript', + \ 'format': 'taglisttoo#lang#javascript#Format', + \ 'parse': 'taglisttoo#lang#javascript#Parse', + \ 'tags': { + \ 'o': 'object', + \ 'm': 'member', + \ 'f': 'function', + \ } + \ } + +let s:tlist_jproperties_settings = { + \ 'lang': 'jproperties', + \ 'parse': 'taglisttoo#lang#jproperties#Parse', + \ 'tags': {'p': 'property'} + \ } + +" lisp language +let s:tlist_lisp_settings = {'lang': 'lisp', 'tags': {'f': 'function'}} + +let s:tlist_log4j_settings = { + \ 'lang': 'log4j', + \ 'parse': 'taglisttoo#lang#log4j#Parse', + \ 'tags': { + \ 'a': 'appender', + \ 'c': 'category', + \ 'l': 'logger', + \ 'r': 'root', + \ } + \ } + +" lua language +let s:tlist_lua_settings = {'lang': 'lua', 'tags': {'f': 'function'}} + +" makefiles +let s:tlist_make_settings = {'lang': 'make', 'tags': {'m': 'macro'}} + +" pascal language +let s:tlist_pascal_settings = { + \ 'lang': 'pascal', 'tags': { + \ 'f': 'function', + \ 'p': 'procedure' + \ } + \ } + +" perl language +let s:tlist_perl_settings = { + \ 'lang': 'perl', 'tags': { + \ 'c': 'constant', + \ 'l': 'label', + \ 'p': 'package', + \ 's': 'subroutine' + \ } + \ } + +" php language +let s:tlist_php_settings = { + \ 'lang': 'php', + \ 'format': 'taglisttoo#lang#php#Format', + \ 'parse': 'taglisttoo#lang#php#Parse', + \ 'tags': { + \ 'c': 'class', + \ 'd': 'constant', + \ 'v': 'variable', + \ 'f': 'function' + \ } + \ } + +" python language +let s:tlist_python_settings = { + \ 'lang': 'python', + \ 'format': 'taglisttoo#lang#python#Format', + \ 'tags': { + \ 'c': 'class', + \ 'm': 'member', + \ 'f': 'function' + \ } + \ } + +" rexx language +let s:tlist_rexx_settings = {'lang': 'rexx', 'tags': {'s': 'subroutine'}} + +let s:tlist_rst_settings = { + \ 'lang': 'rst', + \ 'parse': 'taglisttoo#lang#rst#Parse', + \ 'tags': {'s': 'section', 'a': 'anchor'} + \ } + +" ruby language +let s:tlist_ruby_settings = { + \ 'lang': 'ruby', 'tags': { + \ 'c': 'class', + \ 'f': 'method', + \ 'F': 'function', + \ 'm': 'singleton method' + \ } + \ } + +" scheme language +let s:tlist_scheme_settings = { + \ 'lang': 'scheme', 'tags': { + \ 's': 'set', + \ 'f': 'function' + \ } + \ } + +" shell language +let s:tlist_sh_settings = {'lang': 'sh', 'tags': {'f': 'function'}} + +" C shell language +let s:tlist_csh_settings = {'lang': 'sh', 'tags': {'f': 'function'}} + +" Z shell language +let s:tlist_zsh_settings = {'lang': 'sh', 'tags': {'f': 'function'}} + +" slang language +let s:tlist_slang_settings = { + \ 'lang': 'slang', 'tags': { + \ 'n': 'namespace', + \ 'f': 'function' + \ } + \ } + +" sml language +let s:tlist_sml_settings = { + \ 'lang': 'sml', 'tags': { + \ 'e': 'exception', + \ 'c': 'functor', + \ 's': 'signature', + \ 'r': 'structure', + \ 't': 'type', + \ 'v': 'value', + \ 'f': 'function' + \ } + \ } + +let s:tlist_sql_settings = { + \ 'lang': 'sql', + \ 'parse': 'taglisttoo#lang#sql#Parse', + \ 'tags': { + \ 'g': 'group / role', + \ 'r': 'role', + \ 'u': 'user', + \ 'm': 'user', + \ 'p': 'tablespace', + \ 'z': 'tablespace', + \ 's': 'schema', + \ 't': 'table', + \ 'v': 'view', + \ 'q': 'sequence', + \ 'x': 'trigger', + \ 'f': 'function', + \ 'c': 'procedure' + \ } + \ } + +" tcl language +let s:tlist_tcl_settings = { + \ 'lang': 'tcl', 'tags': { + \ 'c': 'class', + \ 'f': 'method', + \ 'm': 'method', + \ 'p': 'procedure' + \ } + \ } + +" vera language +let s:tlist_vera_settings = { + \ 'lang': 'vera', 'tags': { + \ 'c': 'class', + \ 'd': 'macro', + \ 'e': 'enumerator', + \ 'f': 'function', + \ 'g': 'enum', + \ 'm': 'member', + \ 'p': 'program', + \ 'P': 'prototype', + \ 't': 'task', + \ 'T': 'typedef', + \ 'v': 'variable', + \ 'x': 'externvar' + \ } + \ } + +"verilog language +let s:tlist_verilog_settings = { + \ 'lang': 'verilog', 'tags': { + \ 'm': 'module', + \ 'c': 'constant', + \ 'P': 'parameter', + \ 'e': 'event', + \ 'r': 'register', + \ 't': 'task', + \ 'w': 'write', + \ 'p': 'port', + \ 'v': 'variable', + \ 'f': 'function' + \ } + \ } + +" vim language +let s:tlist_vim_settings = { + \ 'lang': 'vim', 'tags': { + \ 'a': 'autocmds', + \ 'v': 'variable', + \ 'f': 'function' + \ } + \ } + +let s:tlist_xsd_settings = { + \ 'lang': 'xsd', + \ 'parse': 'taglisttoo#lang#xsd#Parse', + \ 'tags': {'e': 'elements', 't': 'types'} + \ } + +" yacc language +let s:tlist_yacc_settings = {'lang': 'yacc', 'tags': {'l': 'label'}} +" }}} + +function! taglisttoo#taglist#AutoOpen() " {{{ + let open_window = 0 + + let i = 1 + let buf_num = winbufnr(i) + while buf_num != -1 + let filename = fnamemodify(bufname(buf_num), ':p') + if !getbufvar(buf_num, '&diff') && + \ s:FileSupported(filename, getbufvar(buf_num, '&filetype')) + let open_window = 1 + break + endif + let i = i + 1 + let buf_num = winbufnr(i) + endwhile + + if open_window + call taglisttoo#taglist#Taglist() + endif +endfunction " }}} + +" Taglist([action]) {{{ +" action +" - not supplied (or -1): toggle +" - 1: open +" - 0: close +function! taglisttoo#taglist#Taglist(...) + if !exists('g:Tlist_Ctags_Cmd') + call s:EchoError('Unable to find a version of ctags installed.') + return + endif + + call s:Init() + + if bufname('%') == s:taglisttoo_title + call s:CloseTaglist() + return + endif + + let action = len(a:000) ? a:000[0] : -1 + + if action == -1 || action == 0 + let winnum = s:GetTagListWinnr() + if winnum != -1 + let prevbuf = bufnr('%') + exe winnum . 'wincmd w' + call s:CloseTaglist() + exec bufwinnr(prevbuf) . 'wincmd w' + return + endif + endif + + if action == -1 || action == 1 + call s:ProcessTags(1) + endif +endfunction " }}} + +" Restore() {{{ +" Restore the taglist, typically after loading from a session file. +function! taglisttoo#taglist#Restore() + if exists('t:taglistoo_restoring') + return + endif + let t:taglistoo_restoring = 1 + + " prevent auto open from firing after session is loaded. + augroup taglisttoo_autoopen + autocmd! + augroup END + + let winnum = s:GetTagListWinnr() + if winnum != -1 + TlistToo + TlistToo + unlet t:taglistoo_restoring + endif +endfunction " }}} + +function! s:Init() " {{{ +python << PYTHONEOF +import sys, vim +path = vim.eval('s:python_path') +if path not in sys.path: + sys.path.append(path) + import taglisttoo +PYTHONEOF +endfunction " }}} + +function! s:StartAutocmds() " {{{ + augroup taglisttoo + autocmd! * + autocmd! * * + autocmd BufUnload call s:Cleanup() + autocmd CursorHold * call s:ShowCurrentTag() + augroup END + + augroup taglisttoo_file + autocmd! * + autocmd! * * + autocmd CursorHold,CursorMoved call s:EchoTag() + autocmd BufEnter nested call s:CloseIfLastWindow() + autocmd BufEnter * + \ if s:GetTagListWinnr() != -1 | + \ call s:ProcessTags(0) | + \ endif + autocmd BufWritePost * + \ if s:GetTagListWinnr() != -1 | + \ call s:ProcessTags(1) | + \ endif + " bit of a hack to re-process tags if the filetype changes after the tags + " have been processed. + autocmd FileType * + \ if exists('b:ft') | + \ if b:ft != &ft | + \ if s:GetTagListWinnr() != -1 | + \ call s:ProcessTags(1) | + \ endif | + \ let b:ft = &ft | + \ endif | + \ else | + \ let b:ft = &ft | + \ endif + autocmd WinLeave * + \ if s:GetTagListWinnr() != -1 && &buftype == '' | + \ let s:taglisttoo_prevwinnr = winnr() | + \ endif + augroup END +endfunction " }}} + +function! s:CloseTaglist() " {{{ + close + call s:Cleanup() +endfunction " }}} + +function! s:Cleanup() " {{{ + let bufnr = s:GetTagListBufnr() + if bufnr != -1 + augroup taglisttoo_file + exec 'autocmd! * ' + augroup END + + augroup taglisttoo + exec 'autocmd! * ' + augroup END + endif + + " TODO: clear all b:taglisttoo_folds variables? +endfunction " }}} + +function! s:ProcessTags(on_open_or_write) " {{{ + " on insert completion prevent vim's jumping back and forth from the + " completion preview window from triggering a re-processing of tags + if pumvisible() + return + endif + + if winnr() == s:GetTagListWinnr() + return + endif + + " if we are entering a buffer whose taglist list is already loaded, then + " don't do anything. + if !a:on_open_or_write + let bufnr = s:GetTagListBufnr() + let filebuf = getbufvar(bufnr, 'taglisttoo_file_bufnr') + if filebuf == bufnr('%') + return + endif + endif + + let filename = expand('%:p') + if filename == '' || &buftype != '' + return + endif + let filewin = winnr() + + if s:FileSupported(expand('%:p'), &ft) + if exists('g:tlist_{&ft}_settings') + if type(g:tlist_{&ft}_settings) == 1 + let values = split(g:tlist_{&ft}_settings, ';') + let tag_settings = {} + for value in values[1:] + let [key, value] = split(value, ':') + let tag_settings[key] = value + endfor + let settings = { + \ 'lang': values[0], + \ 'tags': tag_settings, + \ } + else + let settings = g:tlist_{&ft}_settings + endif + else + let settings = s:tlist_{&ft}_settings + endif + + let file = substitute(expand('%:p'), '\', '/', 'g') + + " support generated file contents (like viewing a .class file via jad) + let tempfile = '' + if !filereadable(file) || &buftype == 'nofile' + let tempfile = g:EclimTempDir . '/' . fnamemodify(file, ':t') + if tolower(file) != tolower(tempfile) + let tempfile = escape(tempfile, ' ') + exec 'write! ' . tempfile + let file = tempfile + endif + endif + + try + if has_key(settings, 'parse') + let tags = s:Function(settings.parse)(file, settings) + else + let tags = s:Parse(file, settings) + endif + catch /E700/ + call s:EchoError('Unknown function: ' . settings.parse) + return + finally + if tempfile != '' + call delete(tempfile) + endif + endtry + + if type(tags) != 3 + return + endif + + call s:Window(settings, tags) + + " if the file buffer is no longer in the same window it was, then find its + " new location. Occurs when taglist first opens. + if winbufnr(filewin) != bufnr(filename) + let filewin = bufwinnr(filename) + endif + + if filewin != -1 + exec filewin . 'winc w' + endif + else + " if the file isn't supported, then don't open the taglist window if it + " isn't open already. + let winnum = s:GetTagListWinnr() + if winnum != -1 + call s:Window({'tags': {}}, []) + winc p + endif + endif + + call s:ShowCurrentTag() +endfunction " }}} + +function! s:Parse(filename, settings) " {{{ +python << PYTHONEOF +try: + settings = vim.eval('a:settings') + filename = vim.eval('a:filename') + lang = settings['lang'] + types = ''.join(settings['tags'].keys()) + + retcode, result = taglisttoo.ctags(lang, types, filename) + vim.command('let retcode = %i' % retcode) + vim.command("let result = '%s'" % result.replace("'", "''")) +except Exception as e: + vim.command("call s:EchoError('%s')" % str(e).replace("'", "''")) + vim.command('let retcode = -1') +PYTHONEOF + + if retcode + if retcode != -1 + call s:EchoError('taglist failed with error code: ' . retcode) + endif + return + endif + + if has('win32') || has('win64') || has('win32unix') + let result = substitute(result, "\\n", '\n', 'g') + endif + + let results = split(result, '\n') + while len(results) && results[0] =~ 'ctags.*: Warning:' + call remove(results, 0) + endwhile + + let types = keys(a:settings.tags) + let parsed_results = [] + for result in results + let pre = substitute(result, '\(.\{-}\)\t\/\^.*', '\1', '') + let pattern = substitute(result, '.\{-}\(\/\^.*\/;"\).*', '\1', '') + let post = substitute(result, '.\{-}\/\^.*\/;"\t', '', '') + + let [name, filename] = split(pre, '\t') + let parts = split(post, '\t') + let [type, line_str] = parts[:1] + exec 'let line = ' . substitute(line_str, 'line:', '', '') + let pattern = substitute(pattern, '^/\(.*\)/;"$', '\1', '') + let parent = len(parts) > 2 ? parts[2] : '' + + " ctags (mine at least) is not properly honoring ---kinds, so + " perform our own check here. + if index(types, type) != -1 + call add(parsed_results, { + \ 'type': type, + \ 'name': name, + \ 'pattern': pattern, + \ 'line': line, + \ 'parent': parent, + \ }) + endif + endfor + + return parsed_results +endfunction " }}} + +function! s:FormatDefault(types, tags) " {{{ + let formatter = taglisttoo#util#Formatter(a:tags) + call formatter.filename() + + for key in keys(a:types) + let values = filter(copy(a:tags), 'v:val.type == key') + if len(values) + call formatter.blank() + endif + call formatter.format(a:types[key], values, "") + endfor + + return formatter +endfunction " }}} + +function! s:FormatEmpty(types, tags) " {{{ + return taglisttoo#util#Formatter(a:tags) +endfunction " }}} + +function! s:GetTagInfo() " {{{ + if line('.') > len(b:taglisttoo_content[0]) + return [] + endif + + let index = b:taglisttoo_content[0][line('.') - 1] + if index == -1 + return [] + endif + + return b:taglisttoo_tags[index] +endfunction " }}} + +function! s:EchoError(message) " {{{ + echohl Error + echo a:message + echohl Normal +endfunction " }}} + +function! s:EchoTag() " {{{ + if g:TaglistTooTagEcho + let tag_info = s:GetTagInfo() + if len(tag_info) + echo 'tag: ' . tag_info.name + else + echo '' + endif + endif +endfunction " }}} + +function! s:FoldLevel(lnum) " {{{ + let indent = indent(a:lnum) + let next_line = nextnonblank(a:lnum + 1) + if next_line + let next_indent = indent(next_line) + if next_indent > indent + let indent = next_indent + endif + endif + let level = indent / &shiftwidth + return level +endfunction " }}} + +function! s:FoldClose() " {{{ + silent! foldclose + let line = foldclosed('.') + if line != -1 + let folds = s:GetFolds() + let path = s:GetFoldPath(line) + if len(path) + call add(folds, path) + call setbufvar(b:taglisttoo_file_bufnr, 'taglisttoo_folds', folds) + endif + endif +endfunction " }}} + +function! s:FoldOpen() " {{{ + let line = foldclosed('.') + if line != -1 + let folds = s:GetFolds() + let path = s:GetFoldPath(line) + let index = index(folds, path) + if index != -1 + call remove(folds, index) + call setbufvar(b:taglisttoo_file_bufnr, 'taglisttoo_folds', folds) + endif + endif + silent! foldopen +endfunction " }}} + +function! s:FoldOpenAll() " {{{ + call setbufvar(b:taglisttoo_file_bufnr, 'taglisttoo_folds', []) + setlocal foldlevel=99 +endfunction " }}} + +function! s:FoldToggle() " {{{ + if foldclosed('.') != -1 + call s:FoldOpen() + else + call s:FoldClose() + endif +endfunction " }}} + +function! s:FoldPath(path) " {{{ + call cursor(1, 1) + + let fold = 1 + let index = 0 + while index < len(a:path) + let fold = search('^\s*' . a:path[index] . '\s*$', 'cW') + if !fold + let folds = s:GetFolds() + let index = index(folds, a:path) + if index != -1 + call remove(folds, index) + call setbufvar(b:taglisttoo_file_bufnr, 'taglisttoo_folds', folds) + endif + break + endif + + " make sure we didn't hit a tag that looks like a label + let line = getline('.') + let col = len(line) - len(substitute(line, '^\s*', '', '')) + 1 + let syntax = synIDattr(synID(fold, col, 1), 'name') + if syntax != 'TagListKeyword' + call cursor(line('.') + 1, 1) + continue + endif + + let index += 1 + endwhile + + if fold + foldclose + endif +endfunction " }}} + +function! s:GetFolds() " {{{ + let folds = getbufvar(b:taglisttoo_file_bufnr, 'taglisttoo_folds') + if type(folds) != 3 " not a list + unlet folds | let folds = [] + endif + return folds +endfunction " }}} + +function! s:GetFoldPath(lnum) " {{{ + let path = [] + + let lnum = a:lnum + let indent = indent(lnum) + while lnum >= 1 + let line = getline(lnum) + let col = len(line) - len(substitute(line, '^\s*', '', '')) + 1 + let syntax = synIDattr(synID(lnum, col, 1), 'name') + if syntax == 'TagListKeyword' && (lnum == a:lnum || indent(lnum) < indent) + call insert(path, substitute(line, '\(^\s*\|\s*$\)', '', 'g')) + endif + let indent = indent(lnum) + if indent == 0 + break + endif + let lnum -= 1 + endwhile + + return path +endfunction " }}} + +function! s:JumpToTag() " {{{ + let tag_info = s:GetTagInfo() + if !len(tag_info) + return + endif + + " handle case of buffer open in multiple windows. + if s:taglisttoo_prevwinnr && + \ winbufnr(s:taglisttoo_prevwinnr) == b:taglisttoo_file_bufnr + noautocmd exec s:taglisttoo_prevwinnr . 'winc w' + else + noautocmd exec bufwinnr(b:taglisttoo_file_bufnr) . 'winc w' + endif + + let lnum = tag_info.line + let pattern = tag_info.pattern + + " account for any plugins which may remove trailing spaces from the file + let pattern = escape(pattern, '.~*[]') + let pattern = substitute(pattern, '\s\+\$$', '\\s*$', '') + + if getline(lnum) =~ pattern + mark ' + call cursor(lnum, 1) + call s:ShowCurrentTag() + else + let pos = getpos('.') + + call cursor(lnum, 1) + + let up = search(pattern, 'bcnW') + let down = search(pattern, 'cnW') + + " pattern found below recorded line + if !up && down + let line = down + + " pattern found above recorded line + elseif !down && up + let line = up + + " pattern found above and below recorded line + elseif up && down + " use the closest match to the recorded line + if (lnum - up) < (down - lnum) + let line = up + else + let line = down + endif + + " pattern not found. + else + let line = 0 + endif + + call setpos('.', pos) + if line + mark ' + call cursor(line, 1) + call s:ShowCurrentTag() + endif + endif +endfunction " }}} + +function! s:Window(settings, tags) " {{{ + let file_bufnr = bufnr('%') + let folds = exists('b:taglisttoo_folds') ? b:taglisttoo_folds : [] + + let winnum = s:GetTagListWinnr() + if winnum == -1 + if exists('g:VerticalToolWindowSide') && + \ g:VerticalToolWindowSide == g:TaglistTooPosition + call eclim#display#window#VerticalToolWindowOpen(s:taglisttoo_title, 10, 1) + else + let position = g:TaglistTooPosition == 'right' ? 'botright' : 'topleft' + silent exec + \ position . ' vertical ' . g:Tlist_WinWidth . + \ ' split ' . escape(s:taglisttoo_title, ' ') + endif + + let winnum = s:GetTagListWinnr() + exe winnum . 'wincmd w' + + setlocal filetype=taglist + setlocal buftype=nofile bufhidden=delete + setlocal noswapfile nobuflisted + setlocal expandtab shiftwidth=2 tabstop=2 + setlocal winfixwidth + setlocal nowrap nonumber + setlocal foldmethod=expr foldlevel=99 + setlocal foldexpr=s:FoldLevel(v:lnum) foldtext=getline(v:foldstart) + + syn match TagListFileName "^.*\%1l.*" + hi link TagListFileName Identifier + hi link TagListKeyword Statement + hi TagListCurrentTag term=bold,underline cterm=bold,underline gui=bold,underline + + nnoremap :call JumpToTag() + + " folding related mappings + nnoremap za :call FoldToggle() + nnoremap zA :call FoldToggle() + nnoremap zc :call FoldClose() + nnoremap zC :call FoldClose() + nnoremap zo :call FoldOpen() + nnoremap zO :call FoldOpen() + nnoremap zn :call FoldOpenAll() + nnoremap zR :call FoldOpenAll() + nnoremap zx + nnoremap zX + nnoremap zm + nnoremap zM + nnoremap zN + nnoremap zr + nnoremap zi + + call s:StartAutocmds() + + noautocmd wincmd p + " handle hopefully rare case where the previous window is not the file's + " window. + if file_bufnr != bufnr('%') + let file_winnr = bufwinnr(file_bufnr) + if file_winnr != -1 + exec 'noautocmd ' . file_winnr . 'wincmd w' + else + return + endif + endif + endif + + if has_key(a:settings, 'format') + let formatter = a:settings.format + elseif len(a:tags) + if g:Tlist_Sort_Type == 'name' + call sort(a:tags, 'taglisttoo#util#SortTags') + endif + let formatter = 's:FormatDefault' + else + let formatter = 's:FormatEmpty' + endif + + try + let format = s:Function(formatter)(a:settings.tags, a:tags) + catch /E700/ + call s:EchoError('Unknown function: ' . formatter) + return + endtry + let content = format.content + exe winnum . 'wincmd w' + + silent! syn clear TagListKeyword + for syn_cmd in format.syntax + exec syn_cmd + endfor + + let pos = [0, 1, 1, 0] + " if we are updating the taglist for the same file, then preserve the + " cursor position. + if len(content) > 0 && getline(1) == content[0] + let pos = getpos('.') + endif + + setlocal modifiable + silent 1,$delete _ + call append(1, content) + silent retab + silent 1,1delete _ + setlocal nomodifiable + + " restore any saved folds + for path in folds + call s:FoldPath(path) + endfor + + call setpos('.', pos) + + " if the entire taglist can fit in the window, then reposition the content + " just in case the previous contents result in the current contents being + " scrolled up a bit. + if len(content) < winheight(winnr()) + normal! zb + endif + + let b:taglisttoo_content = [format.lines, content] + let b:taglisttoo_tags = a:tags + let b:taglisttoo_file_bufnr = file_bufnr +endfunction " }}} + +function! s:ShowCurrentTag() " {{{ + if s:GetTagListWinnr() != -1 && s:FileSupported(expand('%:p'), &ft) + let bufnr = s:GetTagListBufnr() + let tags = getbufvar(bufnr, 'taglisttoo_tags') + if type(tags) != 3 " something went wrong + return + endif + let content = getbufvar(bufnr, 'taglisttoo_content') + + let clnum = line('.') + let tlnum = 0 + let tindex = -1 + + let index = 0 + for tag in tags + let lnum = tag.line + let diff = clnum - lnum + if diff >= 0 && (diff < (clnum - tlnum)) + let tlnum = lnum + let current = tag + let tindex = index + endif + let index += 1 + endfor + + if exists('current') + let cwinnum = winnr() + let twinnum = s:GetTagListWinnr() + + exec 'noautocmd ' . twinnum . 'winc w' + + let index = index(content[0], tindex) + 1 + syn clear TagListCurrentTag + exec 'syn match TagListCurrentTag "\S*\%' . index . 'l\S*"' + if index != line('.') + call cursor(index, 0) + call winline() + endif + + exec 'noautocmd ' . cwinnum . 'winc w' + endif + endif +endfunction " }}} + +function! s:FileSupported(filename, ftype) " {{{ + " Skip buffers with no names, buffers with filetype not set, and vimballs + if a:filename == '' || a:ftype == '' || expand('%:e') == 'vba' + return 0 + endif + + " Skip files which are not supported by exuberant ctags + " First check whether default settings for this filetype are available. + " If it is not available, then check whether user specified settings are + " available. If both are not available, then don't list the tags for this + " filetype + let var = 's:tlist_' . a:ftype . '_settings' + if !exists(var) + let var = 'g:tlist_' . a:ftype . '_settings' + if !exists(var) + return 0 + endif + endif + + " Skip files which are not readable or files which are not yet stored + " to the disk + if !filereadable(a:filename) + return 0 + endif + + return 1 +endfunction " }}} + +function! s:CloseIfLastWindow() " {{{ + if histget(':', -1) !~ '^bd' + let numtoolwindows = 0 + if winnr('$') == 1 + if tabpagenr('$') > 1 + tabclose + else + quitall + endif + endif + endif +endfunction " }}} + +function! s:GetTagListBufnr() " {{{ + let bufnrs = tabpagebuflist() + let bufnames = map(copy(bufnrs), 'bufname(v:val)') + let index = index(bufnames, s:taglisttoo_title) + if index != -1 + return bufnrs[index] + endif + return -1 +endfunction " }}} + +function! s:GetTagListWinnr() " {{{ + let bufnr = s:GetTagListBufnr() + if bufnr != -1 + return bufwinnr(bufnr) + endif + return -1 +endfunction " }}} + +function! s:Function(name) " {{{ + try + return function(a:name) + catch /E700/ + " not until somewhere betwee vim 7.2 and 7.3 did vim start automatically + " sourcing autoload files when attempting to get a funcref to an autoload + " function, so here is our own version. + exec 'runtime autoload/' . fnamemodify(substitute(a:name, '#', '/', 'g'), ':h') . '.vim' + return function(a:name) + endtry +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/autoload/taglisttoo/util.vim b/autoload/taglisttoo/util.vim new file mode 100644 index 0000000..3f4f5bc --- /dev/null +++ b/autoload/taglisttoo/util.vim @@ -0,0 +1,131 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" Copyright (c) 2005 - 2011, Eric Van Dewoestine +" All rights reserved. +" +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: +" +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. +" +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. +" +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +" }}} + +function! taglisttoo#util#Formatter(tags) " {{{ + let formatter = {'lines': [], 'content': [], 'syntax': [], 'tags': a:tags} + + function! formatter.filename() dict " {{{ + call add(self.content, expand('%:t')) + call add(self.lines, -1) + endfunction " }}} + + function! formatter.format(type, values, indent) dict " {{{ + if len(a:values) > 0 + if g:Tlist_Sort_Type == 'name' + call sort(a:values, 'taglisttoo#util#SortTags') + endif + + call self.heading(a:type, {}, a:indent) + + for value in a:values + let visibility = taglisttoo#util#GetVisibility(value) + call add(self.content, "\t" . a:indent . visibility . value.name) + call add(self.lines, index(self.tags, value)) + endfor + endif + endfunction " }}} + + function! formatter.heading(type, tag, indent) dict " {{{ + if len(a:tag) + call add(self.lines, index(self.tags, a:tag)) + call add(self.content, a:indent . a:type . ' ' . a:tag.name) + call add(self.syntax, + \ 'syn match TagListKeyword "^\s*' . a:type . '\%' . len(self.lines) . 'l"') + else + call add(self.lines, 'label') + call add(self.content, a:indent . a:type) + call add(self.syntax, 'syn match TagListKeyword "^.*\%' . len(self.lines) . 'l.*"') + endif + endfunction " }}} + + function! formatter.blank() dict " {{{ + call add(self.content, '') + call add(self.lines, -1) + endfunction " }}} + + return formatter +endfunction " }}} + +function! taglisttoo#util#GetVisibility(tag) " {{{ + let pattern = a:tag.pattern + if pattern =~ '\' + if pattern =~ '\' + return '*' + endif + return '+' + elseif pattern =~ '\' + return '#' + elseif pattern =~ '\' + return '-' + endif + return '' +endfunction " }}} + +function! taglisttoo#util#Parse(file, patterns) " {{{ +python << PYTHONEOF +filename = vim.eval('a:file') +patterns = vim.eval('a:patterns') +result = taglisttoo.parse(filename, patterns) +vim.command('let results = %s' % ('%r' % result).replace("\\'", "''")) +PYTHONEOF + + let tags = [] + if len(results) + for result in results + " filter false positives found in comments or strings + let lnum = result.line + let line = getline(lnum) + let col = len(line) - len(substitute(line, '^\s*', '', '')) + 1 + if synIDattr(synID(lnum, col, 1), 'name') =~? '\(comment\|string\)' || + \ synIDattr(synIDtrans(synID(lnum, col, 1)), 'name') =~? '\(comment\|string\)' + continue + endif + + call add(tags, result) + endfor + endif + + return tags +endfunction " }}} + +function! taglisttoo#util#SortTags(tag1, tag2) " {{{ + let name1 = tolower(a:tag1.name) + let name2 = tolower(a:tag2.name) + return name1 == name2 ? 0 : name1 > name2 ? 1 : -1 +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/doc/taglisttoo.txt b/doc/taglisttoo.txt new file mode 100644 index 0000000..70bf946 --- /dev/null +++ b/doc/taglisttoo.txt @@ -0,0 +1,265 @@ +*taglisttoo.txt* + +----------------------------------------------------------------------------- +TaglistToo *taglisttoo* *TaglistToo* + + Prerequisites |taglisttoo-prerequisites| + Overview |taglisttoo-overview| + Usage |taglisttoo-usage| + Configuration |taglisttoo-configuration| + Extending / Customizing |taglisttoo-customization| + Parsing New File Types |taglisttoo-parse| + Customizing taglist Contents |taglisttoo-format| + +----------------------------------------------------------------------------- +Prerequisites *taglisttoo-prerequisites* + +TaglistToo requires the following: + +1. Exuberant Ctags to be installed: http://ctags.sourceforge.net/ +2. Vim 7.x +3. Python support compiled into (g)vim + +----------------------------------------------------------------------------- +Overview *taglisttoo-overview* + +TaglistToo is a plugin which provides an outline of the current source file in +a separate window allowing you to quickly see the classes, methods, functions, +etc available and to jump to them quickly. This plugin is very similar to the +excellent taglist[1] plugin written by Yegappan Lakshmanan. The motivation +for creating an alternative to the hugely popular taglist plugin is that the +original was written prior to vim 7.0 and so was forced to use data structures +which are very difficult to work with to hold and display the tag information. +These data structures make it hard to customize taglist, so TaglistToo aims to +provide similar functionality but leveraging vim 7.0+ lists and dictionaries +to hold tag information and providing hooks allowing you to customize the +resulting taglist window's layout and to add support for new file types not +natively supported by ctags. + +[1] http://www.vim.org/scripts/script.php?script_id=273 + +Here is a list of enhancements vs unimplemented features from which to compare +TaglistToo to the original taglist.vim: + +Enhancements not found in the original taglist: + +- Supports an extension mechanism allowing the taglist display to be + customized by file type. +- Provides custom displays for a handful of languages (java, javascript, php, + python, etc.) which groups methods and variables by object/class for easier + viewing and navigation. +- Supports denoting tags based on their visibility (+public, -private, + *static, #protected). +- Provides the ability to add support for new file types not supported by + ctags. +- Echoing of the current tag while scrolling through the taglist window, which + is helpful if the tag name doesn't fit in the width of taglist window. + +Unimplemented features found in the original taglist: + +- Drop down list in gvim with the list of tags. +- Tag re-sorting +- Support for tags for more than one file in the taglist window. +- ... possibly others. + +Other than the feature differences the behavior of TaglistToo is very similar +to the original taglist. + +----------------------------------------------------------------------------- +Usage *taglisttoo-usage* + *:TlistToo* + +To open the taglist window simply run the command :TlistToo. As long as the +current file type is supported and exists on disk, the taglist window will +open and display an outline of the file. Executing :TlistToo again will close +the taglist window. + +Within the taglist window you can jump to a particular tag in the source file +by hitting on the tag. + +Folding of tags by heading is also supported using a subset of vim's standard +folding key bindings (Note: unlike the standard key bindings, none of these +are recursive): + + za, zA When on a fold, toggle whether it is open or closed. + zc, zC Close a fold. + zo, zO Open a fold. + zn, zR Open all folds. + +----------------------------------------------------------------------------- +Configuration *taglisttoo-configuration* + +In an attempt to make your transition from the original taglist to TaglistToo +as easy as possible, TaglistToo supports a some of the same configuration +variables: + +- *g:Tlist_Ctags_Cmd* - Sets the location or your ctags executable (if not + set, TaglistToo will try to find either exuberant-ctags or ctags on your + path). +- *g:Tlist_Auto_Open* (Default: 0) - When non-zero, the taglist will auto open + at vim startup if the file type is supported. +- *g:Tlist_WinWidth* (Default: 30) - Sets the width of the taglist window. +- *g:Tlist_Sort_Type* (Default: 'name') - Determines how the tags should be + sorted in the taglist window. When set to 'name', the tags will be sorted + alphabetically, but when set to 'order' the tags will be sorted by their + occurrence in the source file. +- *g:TagList_title* (Default: '[TagList]') - Sets the name of the taglist + window. +- g:Tlist_Use_Right_Window - Preferably you should set the + |g:TaglistTooPosition| variable, but for compatibility with the original + taglist, if this variable is set to a non-0 value then + |g:TaglistTooPosition| will be set to 'right'. + +Some TaglistToo specific variables: + +- *g:TaglistTooEnabled* (Default: 1) - When set to 0 this disables loading of + TaglistToo. +- *g:TaglistTooPosition* (Default: 'left') - This determines whether the + taglist window will be opened on the left or right side of vim. Supported + values include 'left' and 'right'. +- *g:TaglistTooTagEcho* (Default: 1) - When set to a non 0 value, when moving + the cursor in the taglist window, the name of the tag under the cursor will + be echoed to the vim command line. + +----------------------------------------------------------------------------- +Extending / Customizing *taglisttoo-customization* + +For compatibility with the original taglist, TagListToo supports the same +g:tlist_{ft}_settings variables including the string format: > + + let g:tlist_mylang_settings = 'mylang;t:mytype;f:myfield' +> + +However, since vim 7 and above has support for lists and dictionaries, the +above setting can be expressed for TaglistToo as follows: > + + let g:tlist_mylang_settings = { + \ 'lang': 'mylang', + \ 'tags': { + \ 't': 'mytype', + \ 'f': 'myfield', + \ } + \ } +> + +The one character keys in the 'tags' dictionary are what will be passed to +ctags ---types argument, and the value for those keys is the text to be +displayed in the taglist window. + +Parsing New File Types: *taglisttoo-parse* + +The default method for which TaglistToo obtains the list of tags for a given +source file is to use ctags. If you want to add a new language which isn't +supported by ctags by default you generally have a couple options: + +1. You can define a new language via regular expression patterns in your + .ctags file using the langdef, langmap, and --regex- options. +2. You can write a C extension to ctags. + +The first approach, while fairly simple, is a bit limiting. The most +frustrating limitation is that the file to be parse is processed one line at a +time, which prevents you from identifying tags that span two or more lines. + +For example, given the following web.xml file, you would not be able to +distinguish between the first block which is a servlet definition, and the +second which is a servlet mapping, because you would need to process the parent +tag, not just the servlet-name tag: > + + + MyServlet + org.foo.MyServlet + + + + MyServlet + /my-servlet + +> + +The second approach, is much more flexible, but writing a language processor in +C may not be a feasible solution for various reasons (unfamiliarity with C, +portability, etc.). + +Taking into account these concerns, TaglistToo provides the means to add new +languages by allowing you to configure a vim script function to be executed to +obtain the tags. In this function you can process the file however you would +like, but TaglistToo provides a simple utility function allowing you to supply +a list of tag types, python compatible regular expressions, and the +replacement text or group used to obtain the tag name. + +Here is an example function which processes the web.xml file described above: > + + function! ParseWebXml(file, settings) + return taglisttoo#util#Parse(a:file, [ + \ ['s', '\s*\s*(.*?)\s*', 1], + \ ['m', '\s*\s*(.*?)\s*', 1], + \ ]) + endfunction +> + +There are a couple things to note about how these regular expressions are +evaluated: + +1. When compiling the regular expression the DOTALL and MULTILINE flags are + always set. +2. The regular expressions are executed against the whole file at once. +3. If you would like to have the IGNORECASE flag set as well, simply add a + 'i' as a fourth value to each list where you'd like that flag enabled. +4. The third value in each list specifies what replacement value should be + used to extract the tag name from the matched text. If the value is an int, + it is interpreted as the group number from the regular expression. If the + value is a string, then a separate substitution is executed with that + value. So if you had two groups you wanted to combine, you could supply + '\1 \2' for the third value in the supplied list. + +Now that you have a function which processes the file, you simply need to +configure the taglist settings for the webxml file type: > + + let g:tlist_webxml_settings = { + \ 'lang': 'webxml', + \ 'parse': 'ParseWebXml', + \ 'tags': { + \ 's': 'servlet', + \ 'm': 'servlet-mapping' + \ } + \ } +> + +Notice the new 'parse' key introduced here which tells TaglistToo to use that +function instead of the default one. + +Note: This example introduces a new file type, webxml, which doesn't exist by +default in vim, so if you want to test this out on a real web.xml file you'll +need to manually set the file type (:set ft=webxml). + +Customizing taglist contents: *taglisttoo-format* + +In addition to parsing new file types, you can also customize the taglist +format for new or existing file types. To do so you simply tell TaglistToo to +use a different format function. Here is an example using TagListToo's python +settings: > + + let g:tlist_python_settings = { + \ 'lang': 'python', + \ 'format': 'taglisttoo#lang#python#Format', + \ 'tags': { + \ 'c': 'class', + \ 'm': 'member', + \ 'f': 'function' + \ } + \ } +> + +Instead of using the default format, TaglistToo will invoke the +taglisttoo#lang#python#Format function which in this case will group members +and functions by the class they are defined in and any global functions will +be displayed at the top of the taglist window. + +Unfortunately, implementing a function which customizes the taglist layout is +not as straight forward and writing one which parses a new file type. If you +wish to write one of these format functions, currently you are best off +copying one of the format functions defined in one of the +autoload/taglisttoo/lang/.vim files and customizing it to your needs. +Hopefully future versions of TaglistToo will make writing these easier. + +vim:tw=78:ft=help:norl: diff --git a/doc/tags b/doc/tags index fda6dfe..f5c8d5b 100644 --- a/doc/tags +++ b/doc/tags @@ -81,6 +81,7 @@ :SendBlogArticle vimblogger_ft.txt /*:SendBlogArticle* :Tags: vimblogger_ft.txt /*:Tags:* :Title: vimblogger_ft.txt /*:Title:* +:TlistToo taglisttoo.txt /*:TlistToo* :VCSAdd vcscommand.txt /*:VCSAdd* :VCSAnnotate vcscommand.txt /*:VCSAnnotate* :VCSBlame vcscommand.txt /*:VCSBlame* @@ -185,6 +186,7 @@ ShowMarksClearMark showmarks.txt /*ShowMarksClearMark* ShowMarksOn showmarks.txt /*ShowMarksOn* ShowMarksPlaceMark showmarks.txt /*ShowMarksPlaceMark* ShowMarksToggle showmarks.txt /*ShowMarksToggle* +TaglistToo taglisttoo.txt /*TaglistToo* VCSCommandCVSDiffOpt vcscommand.txt /*VCSCommandCVSDiffOpt* VCSCommandCVSExec vcscommand.txt /*VCSCommandCVSExec* VCSCommandCommitOnWrite vcscommand.txt /*VCSCommandCommitOnWrite* @@ -294,6 +296,14 @@ fuf-usage fuf.txt /*fuf-usage* fuf-vimrc-example fuf.txt /*fuf-vimrc-example* fuf.txt fuf.txt /*fuf.txt* fuzzyfinder fuf.txt /*fuzzyfinder* +g:TagList_title taglisttoo.txt /*g:TagList_title* +g:TaglistTooEnabled taglisttoo.txt /*g:TaglistTooEnabled* +g:TaglistTooPosition taglisttoo.txt /*g:TaglistTooPosition* +g:TaglistTooTagEcho taglisttoo.txt /*g:TaglistTooTagEcho* +g:Tlist_Auto_Open taglisttoo.txt /*g:Tlist_Auto_Open* +g:Tlist_Ctags_Cmd taglisttoo.txt /*g:Tlist_Ctags_Cmd* +g:Tlist_Sort_Type taglisttoo.txt /*g:Tlist_Sort_Type* +g:Tlist_WinWidth taglisttoo.txt /*g:Tlist_WinWidth* g:blogger_browser vimblogger_ft.txt /*g:blogger_browser* g:blogger_confirm_del vimblogger_ft.txt /*g:blogger_confirm_del* g:blogger_draft vimblogger_ft.txt /*g:blogger_draft* @@ -920,6 +930,15 @@ tagbar-requirements tagbar.txt /*tagbar-requirements* tagbar-todo tagbar.txt /*tagbar-todo* tagbar-usage tagbar.txt /*tagbar-usage* tagbar.txt tagbar.txt /*tagbar.txt* +taglisttoo taglisttoo.txt /*taglisttoo* +taglisttoo-configuration taglisttoo.txt /*taglisttoo-configuration* +taglisttoo-customization taglisttoo.txt /*taglisttoo-customization* +taglisttoo-format taglisttoo.txt /*taglisttoo-format* +taglisttoo-overview taglisttoo.txt /*taglisttoo-overview* +taglisttoo-parse taglisttoo.txt /*taglisttoo-parse* +taglisttoo-prerequisites taglisttoo.txt /*taglisttoo-prerequisites* +taglisttoo-usage taglisttoo.txt /*taglisttoo-usage* +taglisttoo.txt taglisttoo.txt /*taglisttoo.txt* vS surround.txt /*vS* v_m mark.txt /*v_m* v_r mark.txt /*v_r* diff --git a/plugin/buffers.vim b/plugin/buffers.vim index 2201a32..2cafd0b 100644 --- a/plugin/buffers.vim +++ b/plugin/buffers.vim @@ -3,7 +3,7 @@ " Description: vim plugin that provides buffers helpers. Almost all of parts " are taken from Eclim project " Maintainer: Roman 'gryf' Dobosz -" Last Change: 2010-08-28 +" Last Change: 2011-07-16 " License: This program is free software: you can redistribute it and/or " modify it under the terms of the GNU General Public License as " published by the Free Software Foundation, either version 3 of @@ -18,7 +18,7 @@ " License along with this program. If not, see " . " ============================================================================ -let s:Eclim_ver = '1.6.0' +let s:Eclim_ver = '1.7.1' " Eclim: {{{1 " files: @@ -98,10 +98,6 @@ endif if !exists('g:EclimBuffersDefaultAction') let g:EclimBuffersDefaultAction = 'edit' endif -if !exists('g:EclimOnlyExclude') - let g:EclimOnlyExclude = - \ '\(NERD_tree_*\|__Tag_List__\|command-line\)' -endif " }}} " Buffers() eclim/autoload/eclim/common/buffers.vim {{{2 @@ -140,7 +136,6 @@ function! s:Buffers() endfor call TempWindow('[buffers]', lines) - let b:eclim_buffers = buffers setlocal modifiable noreadonly call append(line('$'), ['', '" use ? to view help']) @@ -162,6 +157,7 @@ function! s:Buffers() nnoremap S :call BufferOpen2('split') nnoremap T :call BufferOpen('tablast \| tabnew') nnoremap D :call BufferDelete() + nnoremap R :Buffers " assign to buffer var to get around weird vim issue passing list containing " a string w/ a '<' in it on execution of mapping. @@ -171,6 +167,7 @@ function! s:Buffers() \ 'S - open in a new split window', \ 'T - open in a new tab', \ 'D - delete the buffer', + \ 'R - refresh the buffer list', \ ] nnoremap ? \ :call BufferHelp(b:buffers_help, 'vertical', 40) @@ -209,7 +206,19 @@ function! s:BufferDelete() setlocal readonly let buffer = b:eclim_buffers[index] call remove(b:eclim_buffers, index) - exec 'bd ' . buffer.bufnr + + let winnr = bufwinnr(buffer.bufnr) + if winnr != -1 + " if active in a window, go to the window to delete the buffer since that + " keeps eclim's prevention of closing the last non-utility window working + " properly. + let curwin = winnr() + exec winnr . 'winc w' + bdelete + exec curwin . 'winc w' + else + exec 'bd ' . buffer.bufnr + endif endfunction " }}} " s:BufferEntryToLine(buffer, filelength) eclim/autoload/eclim/common/buffers.vim {{{2 @@ -307,7 +316,7 @@ function! GoToBufferWindow(buf) let winnr = bufwinnr(a:buf) else let name = EscapeBufferName(a:buf) - let winnr = bufwinnr(bufnr('^' . name)) + let winnr = bufwinnr(bufnr('^' . name . '$')) endif if winnr != -1 exec winnr . "winc w" @@ -383,17 +392,20 @@ function! TempWindow(name, lines, ...) let name = EscapeBufferName(a:name) if bufwinnr(name) == -1 - silent! noautocmd exec "botright 10sview " . escape(a:name, ' ') - let b:eclim_temp_window = 1 - + silent! noautocmd exec "botright 10sview " . escape(a:name, ' []') setlocal nowrap setlocal winfixheight setlocal noswapfile setlocal nobuflisted setlocal buftype=nofile setlocal bufhidden=delete + silent doautocmd WinEnter else - exec bufwinnr(name) . "winc w" + let temp_winnr = bufwinnr(name) + if temp_winnr != winnr() + exec temp_winnr . 'winc w' + silent doautocmd WinEnter + endif endif setlocal modifiable @@ -460,11 +472,16 @@ function! BufferHelp(lines, orientation, size) endif silent! noautocmd exec a:size . orient . "new " . escape(name, ' ') - let b:eclim_temp_window = 1 - setlocal nowrap winfixheight + if a:orientation == 'vertical' + setlocal winfixwidth + else + setlocal winfixheight + endif + setlocal nowrap setlocal noswapfile nobuflisted nonumber setlocal buftype=nofile bufhidden=delete nnoremap ? :bd + nnoremap q :bd setlocal modifiable noreadonly silent 1,$delete _ diff --git a/plugin/taglisttoo.vim b/plugin/taglisttoo.vim index 8125ed5..e641418 100644 --- a/plugin/taglisttoo.vim +++ b/plugin/taglisttoo.vim @@ -1,55 +1,52 @@ " Author: Eric Van Dewoestine " -" Description: {{{ -" see http://eclim.org/vim/taglist.html +" License: {{{ +" Copyright (c) 2005 - 2010, Eric Van Dewoestine +" All rights reserved. " -" License: +" Redistribution and use of this software in source and binary forms, with +" or without modification, are permitted provided that the following +" conditions are met: " -" Copyright (C) 2005 - 2010 Eric Van Dewoestine +" * Redistributions of source code must retain the above +" copyright notice, this list of conditions and the +" following disclaimer. " -" This program is free software: you can redistribute it and/or modify -" it under the terms of the GNU General Public License as published by -" the Free Software Foundation, either version 3 of the License, or -" (at your option) any later version. +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the +" following disclaimer in the documentation and/or other +" materials provided with the distribution. " -" This program is distributed in the hope that it will be useful, -" but WITHOUT ANY WARRANTY; without even the implied warranty of -" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -" GNU General Public License for more details. -" -" You should have received a copy of the GNU General Public License -" along with this program. If not, see . +" * Neither the name of Eric Van Dewoestine nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission of +" Eric Van Dewoestine. " +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. " }}} -" eclim version: 1.6.0 if exists('g:taglisttoo_loaded') || - \ (exists('g:taglisttoo_disabled') && g:taglisttoo_disabled) + \ (exists('g:TaglistTooEnabled') && !g:TaglistTooEnabled) || + \ !has('python') finish endif let g:taglisttoo_loaded = 1 +" try to disable taglist.vim +let g:loaded_taglist = 1 + " Global Variables {{{ -if !exists("g:TaglistEnabled") - let g:TaglistEnabled = 1 -endif - -" always set the taglist title since eclim references it in a few places. -if !exists('g:TagList_title') - let g:TagList_title = "__Tag_List__" -endif - -if !g:TaglistEnabled - finish -endif - -" disable if user has taglist installed on windows since we can't hook into -" taglist to fix the windows path separators to be java compatible. -if exists('loaded_taglist') && (has('win32') || has('win64') || has('win32unix')) - finish -endif - if !exists('g:Tlist_Ctags_Cmd') if executable('exuberant-ctags') let g:Tlist_Ctags_Cmd = 'exuberant-ctags' @@ -64,1886 +61,67 @@ endif " no ctags found, no need to continue. if !exists('g:Tlist_Ctags_Cmd') + echohl WarningMsg | echom 'ctags not found' | echohl Normal finish endif -let g:Tlist_Ctags_Cmd_Ctags = g:Tlist_Ctags_Cmd - -" don't conflict with original taglist if that is what the user is using. -if !exists('loaded_taglist') - " Automatically open the taglist window on Vim startup - if !exists('g:Tlist_Auto_Open') - let g:Tlist_Auto_Open = 0 - endif - - if g:Tlist_Auto_Open && !exists('g:Tlist_Temp_Disable') - augroup taglisttoo_autoopen - autocmd! - autocmd VimEnter * nested call s:AutoOpen() - augroup END - - " Auto open on new tabs as well. - if v:version >= 700 - autocmd taglisttoo_autoopen BufWinEnter * - \ if tabpagenr() > 1 && - \ !exists('t:Tlist_Auto_Opened') && - \ !exists('g:SessionLoad') | - \ call s:AutoOpen() | - \ let t:Tlist_Auto_Opened = 1 | - \ endif - endif - endif - - augroup taglisttoo_file_session - autocmd! - autocmd SessionLoadPost * call s:Restore() - augroup END +if !exists('g:Tlist_Auto_Open') + let g:Tlist_Auto_Open = 0 endif + +if !exists("g:TaglistTooPosition") + if exists('Tlist_Use_Right_Window') && Tlist_Use_Right_Window + let g:TaglistTooPosition = 'right' + else + let g:TaglistTooPosition = 'left' + endif +endif + +if !exists('g:TagList_title') + let g:TagList_title = "[TagList]" +endif + +if !exists('g:Tlist_WinWidth') + let g:Tlist_WinWidth = 30 +endif + +if !exists('g:Tlist_Sort_Type') + let g:Tlist_Sort_Type = 'name' +endif + +if !exists('g:TaglistTooTagEcho') + let g:TaglistTooTagEcho = 1 +endif + +if g:Tlist_Auto_Open && !exists('g:Tlist_Temp_Disable') + augroup taglisttoo_autoopen + autocmd! + autocmd VimEnter * nested call taglisttoo#taglist#AutoOpen() + augroup END + + " Auto open on new tabs as well. + if v:version >= 700 + autocmd taglisttoo_autoopen BufWinEnter * + \ if tabpagenr() > 1 && + \ !exists('t:Tlist_Auto_Opened') && + \ !exists('g:SessionLoad') | + \ call taglisttoo#taglist#AutoOpen() | + \ let t:Tlist_Auto_Opened = 1 | + \ endif + endif +endif + +augroup taglisttoo_file_session + autocmd! + autocmd SessionLoadPost * call taglisttoo#taglist#Restore() +augroup END + " }}} " Command Declarations {{{ -if !exists(":Tlist") && !exists(":TlistToo") - "command TlistToo :call s:Taglist() - "I want to have possibility to explicit close the taglist by passing bang to - "the command. gryf - command! -bang -nargs=? TlistToo :call s:Taglist(-1) - "And also have a command for explicit close - command! TlistTooOpen :call s:Taglist(1) +if !exists(":TlistToo") + command TlistToo :call taglisttoo#taglist#Taglist() endif " }}} -" Util: {{{1 - -" Script Variables eclim/autoload/eclim/util.vim {{{2 - let s:buffer_write_closing_commands = '^\s*\(' . - \ 'wq\|xa\|' . - \ '\d*w[nN]\|\d*wp\|' . - \ 'ZZ' . - \ '\)' - - let s:bourne_shells = ['sh', 'bash', 'dash', 'ksh', 'zsh'] - let s:c_shells = ['csh', 'tcsh'] - - let s:show_current_error_displaying = 0 -" }}} - -" DelayedCommand(command, [delay]) eclim/autoload/eclim/util.vim {{{2 -" Executes a delayed command. Useful in cases where one would expect an -" autocommand event (WinEnter, etc) to fire, but doesn't, or you need a -" command to execute after other autocommands have finished. -" Note: Nesting is not supported. A delayed command cannot be invoke off -" another delayed command. -function! DelayedCommand(command, ...) - let uid = fnamemodify(tempname(), ':t:r') - if &updatetime > 1 - exec 'let g:eclim_updatetime_save' . uid . ' = &updatetime' - endif - exec 'let g:eclim_delayed_command' . uid . ' = a:command' - let &updatetime = len(a:000) ? a:000[0] : 1 - exec 'augroup delayed_command' . uid - exec 'autocmd CursorHold * ' . - \ ' if exists("g:eclim_updatetime_save' . uid . '") | ' . - \ ' let &updatetime = g:eclim_updatetime_save' . uid . ' | ' . - \ ' unlet g:eclim_updatetime_save' . uid . ' | ' . - \ ' endif | ' . - \ ' exec g:eclim_delayed_command' . uid . ' | ' . - \ ' unlet g:eclim_delayed_command' . uid . ' | ' . - \ ' autocmd! delayed_command' . uid - exec 'augroup END' -endfunction " }}} - -" EchoTrace(message, [time_elapsed]) eclim/autoload/eclim/util.vim {{{2 -function! EchoTrace(message, ...) - if a:0 > 0 - call s:EchoLevel('(' . a:1 . 's) ' . a:message, 6, g:EclimTraceHighlight) - else - call s:EchoLevel(a:message, 6, g:EclimTraceHighlight) - endif -endfunction " }}} - -" EchoError(message) eclim/autoload/eclim/util.vim {{{2 -function! EchoError(message) - call s:EchoLevel(a:message, 2, g:EclimErrorHighlight) -endfunction " }}} - -" s:EchoLevel(message) eclim/autoload/eclim/util.vim {{{2 -" Echos the supplied message at the supplied level with the specified -" highlight. -function! s:EchoLevel(message, level, highlight) - " only echo if the result is not 0, which signals that ExecuteEclim failed. - if a:message != "0" && g:EclimLogLevel >= a:level - exec "echohl " . a:highlight - redraw - for line in split(a:message, '\n') - echom line - endfor - echohl None - endif -endfunction " }}} - -" EscapeBufferName(name) eclim/autoload/eclim/util.vim {{{2 -" Escapes the supplied buffer name so that it can be safely used by buf* -" functions. -function! EscapeBufferName(name) - let name = a:name - " escaping the space in cygwin could lead to the dos path error message that - " cygwin throws when a dos path is referenced. - if !has('win32unix') - let name = escape(a:name, ' ') - endif - return substitute(name, '\(.\{-}\)\[\(.\{-}\)\]\(.\{-}\)', '\1[[]\2[]]\3', 'g') -endfunction " }}} - -" ExecWithoutAutocmds(cmd, [events]) eclim/autoload/eclim/util.vim {{{2 -" Execute a command after disabling all autocommands (borrowed from taglist.vim) -function! ExecWithoutAutocmds(cmd, ...) - let save_opt = &eventignore - let events = len(a:000) == 0 ? 'all' : a:000[0] - exec 'set eventignore=' . events - try - exec a:cmd - finally - let &eventignore = save_opt - endtry -endfunction " }}} - -" GetLineError(line) eclim/autoload/eclim/util.vim {{{2 -" Gets the error (or message) for the supplie line number if one. -function! GetLineError(line) - let line = line('.') - let col = col('.') - - let errornum = 0 - let errorcol = 0 - let index = 0 - - let locerrors = getloclist(0) - let qferrors = getqflist() - let bufname = expand('%') - let lastline = line('$') - for error in qferrors + locerrors - let index += 1 - if bufname(error.bufnr) == bufname && - \ (error.lnum == line || (error.lnum > lastline && line == lastline)) - if errornum == 0 || (col >= error.col && error.col != errorcol) - let errornum = index - let errorcol = error.col - endif - endif - endfor - - if errornum > 0 - let src = 'qf' - let cnt = len(qferrors) - let errors = qferrors - if errornum > cnt - let errornum -= cnt - let src = 'loc' - let cnt = len(locerrors) - let errors = locerrors - endif - - let message = src . ' - (' . errornum . ' of ' . cnt . '): ' - \ . substitute(errors[errornum - 1].text, '^\s\+', '', '') - return message - endif - return '' -endfunction " }}} - -" GoToBufferWindow(buf) eclim/autoload/eclim/util.vim {{{2 -" Focuses the window containing the supplied buffer name or buffer number. -" Returns 1 if the window was found, 0 otherwise. -function! GoToBufferWindow(buf) - if type(a:buf) == 0 - let winnr = bufwinnr(a:buf) - else - let name = EscapeBufferName(a:buf) - let winnr = bufwinnr(bufnr('^' . name)) - endif - if winnr != -1 - exec winnr . "winc w" - call DelayedCommand('doautocmd WinEnter') - return 1 - endif - return 0 -endfunction " }}} - -" GoToBufferWindowRegister(buf) eclim/autoload/eclim/util.vim {{{2 -" Registers the autocmd for returning the user to the supplied buffer when the -" current buffer is closed. -function! GoToBufferWindowRegister(buf) - exec 'autocmd BufWinLeave ' . - \ 'call GoToBufferWindow("' . escape(a:buf, '\') . '") | ' . - \ 'doautocmd BufEnter' -endfunction " }}} - -" System(cmd, [exec]) eclim/autoload/eclim/util.vim {{{2 -" Executes system() accounting for possibly disruptive vim options. -function! System(cmd, ...) - let saveshell = &shell - let saveshellcmdflag = &shellcmdflag - let saveshellpipe = &shellpipe - let saveshellquote = &shellquote - let saveshellredir = &shellredir - let saveshellslash = &shellslash - let saveshelltemp = &shelltemp - let saveshellxquote = &shellxquote - - if has("win32") || has("win64") - set shell=cmd.exe - set shellcmdflag=/c - set shellpipe=>%s\ 2>&1 - set shellquote= - set shellredir=>%s\ 2>&1 - set noshellslash - set shelltemp - set shellxquote= - else - if executable('/bin/bash') - set shell=/bin/bash - else - set shell=/bin/sh - endif - set shell=/bin/sh - set shellcmdflag=-c - set shellpipe=2>&1\|\ tee - set shellquote= - set shellredir=>%s\ 2>&1 - set noshellslash - set shelltemp - set shellxquote= - endif - - if len(a:000) > 0 && a:000[0] - let result = '' - let begin = localtime() - try - exec a:cmd - finally - call EchoTrace('exec: ' . a:cmd, localtime() - begin) - endtry - else - let begin = localtime() - try - let result = system(a:cmd) - finally - call EchoTrace('system: ' . a:cmd, localtime() - begin) - endtry - endif - - let &shell = saveshell - let &shellcmdflag = saveshellcmdflag - let &shellquote = saveshellquote - let &shellslash = saveshellslash - let &shelltemp = saveshelltemp - let &shellxquote = saveshellxquote - - " If a System call is executed at startup, it appears to interfere with - " vim's setting of 'shellpipe' and 'shellredir' to their shell specific - " values. So, if we detect that the values we are restoring look like - " uninitialized defaults, then attempt to mimic vim's documented - " (:h 'shellpipe' :h 'shellredir') logic for setting the proper values based - " on the shell. - " Note: still doesn't handle more obscure shells - if saveshellredir == '>' - if index(s:bourne_shells, fnamemodify(&shell, ':t')) != -1 - set shellpipe=2>&1\|\ tee - set shellredir=>%s\ 2>&1 - elseif index(s:c_shells, fnamemodify(&shell, ':t')) != -1 - set shellpipe=\|&\ tee - set shellredir=>& - else - let &shellpipe = saveshellpipe - let &shellredir = saveshellredir - endif - else - let &shellpipe = saveshellpipe - let &shellredir = saveshellredir - endif - - return result -endfunction " }}} - -" End Util: }}} - -" TagListToo: {{{1 - -" Global Variables eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -let g:TagListToo = 1 - -" Tag listing sort type - 'name' or 'order' -if !exists('Tlist_Sort_Type') - let Tlist_Sort_Type = 'order' -endif - -" }}} - -" Script Variables eclim/autoload/eclim/taglist/taglisttoo.vim {{{ - let s:taglisttoo_ignore = g:TagList_title . '\|ProjectTree' - - " used to prefer one window over another if a buffer is open in more than - " one window. - let s:taglisttoo_prevwinnr = 0 -" }}} - -" Language Settings eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -" assembly language -let s:tlist_def_asm_settings = { - \ 'lang': 'asm', 'tags': { - \ 'd': 'define', - \ 'l': 'label', - \ 'm': 'macro', - \ 't': 'type' - \ } - \ } - -" aspperl language -let s:tlist_def_aspperl_settings = { - \ 'lang': 'asp', 'tags': { - \ 'f': 'function', - \ 's': 'sub', - \ 'v': 'variable' - \ } - \ } - -" aspvbs language -let s:tlist_def_aspvbs_settings = { - \ 'lang': 'asp', 'tags': { - \ 'f': 'function', - \ 's': 'sub', - \ 'v': 'variable' - \ } - \ } - -" awk language -let s:tlist_def_awk_settings = {'lang': 'awk', 'tags': {'f': 'function'}} - -" beta language -let s:tlist_def_beta_settings = { - \ 'lang': 'beta', 'tags': { - \ 'f': 'fragment', - \ 's': 'slot', - \ 'v': 'pattern' - \ } - \ } - -" c language -let s:tlist_def_c_settings = { - \ 'lang': 'c', 'tags': { - \ 'd': 'macro', - \ 'g': 'enum', - \ 's': 'struct', - \ 'u': 'union', - \ 't': 'typedef', - \ 'v': 'variable', - \ 'f': 'function' - \ } - \ } - -" c++ language -let s:tlist_def_cpp_settings = { - \ 'lang': 'c++', 'tags': { - \ 'n': 'namespace', - \ 'v': 'variable', - \ 'd': 'macro', - \ 't': 'typedef', - \ 'c': 'class', - \ 'g': 'enum', - \ 's': 'struct', - \ 'u': 'union', - \ 'f': 'function' - \ } - \ } - -" c# language -let s:tlist_def_cs_settings = { - \ 'lang': 'c#', 'tags': { - \ 'd': 'macro', - \ 't': 'typedef', - \ 'n': 'namespace', - \ 'c': 'class', - \ 'E': 'event', - \ 'g': 'enum', - \ 's': 'struct', - \ 'i': 'interface', - \ 'p': 'properties', - \ 'm': 'method' - \ } - \ } - -" cobol language -let s:tlist_def_cobol_settings = { - \ 'lang': 'cobol', 'tags': { - \ 'd': 'data', - \ 'f': 'file', - \ 'g': 'group', - \ 'p': 'paragraph', - \ 'P': 'program', - \ 's': 'section' - \ } - \ } - -" eiffel language -let s:tlist_def_eiffel_settings = { - \ 'lang': 'eiffel', 'tags': { - \ 'c': 'class', - \ 'f': 'feature' - \ } - \ } - -" erlang language -let s:tlist_def_erlang_settings = { - \ 'lang': 'erlang', 'tags': { - \ 'd': 'macro', - \ 'r': 'record', - \ 'm': 'module', - \ 'f': 'function' - \ } - \ } - -" expect (same as tcl) language -let s:tlist_def_expect_settings = { - \ 'lang': 'tcl', 'tags': { - \ 'c': 'class', - \ 'f': 'method', - \ 'p': 'procedure' - \ } - \ } - -" fortran language -let s:tlist_def_fortran_settings = { - \ 'lang': 'fortran', 'tags': { - \ 'p': 'program', - \ 'b': 'block data', - \ 'c': 'common', - \ 'e': 'entry', - \ 'i': 'interface', - \ 'k': 'type', - \ 'l': 'label', - \ 'm': 'module', - \ 'n': 'namelist', - \ 't': 'derived', - \ 'v': 'variable', - \ 'f': 'function', - \ 's': 'subroutine' - \ } - \ } - -" HTML language -let s:tlist_def_html_settings = { - \ 'lang': 'html', 'tags': { - \ 'a': 'anchor', - \ 'f': 'javascript function' - \ } - \ } - -" java language -let s:tlist_format_java = 'FormatJava' -let s:tlist_def_java_settings = { - \ 'lang': 'java', 'tags': { - \ 'p': 'package', - \ 'c': 'class', - \ 'i': 'interface', - \ 'f': 'field', - \ 'm': 'method' - \ } - \ } - -let s:tlist_format_javascript = 'FormatJavascript' -let s:tlist_def_javascript_settings = { - \ 'lang': 'javascript', 'tags': { - \ 'o': 'object', - \ 'm': 'member', - \ 'f': 'function', - \ } - \ } - -" lisp language -let s:tlist_def_lisp_settings = {'lang': 'lisp', 'tags': {'f': 'function'}} - -" lua language -let s:tlist_def_lua_settings = {'lang': 'lua', 'tags': {'f': 'function'}} - -" makefiles -let s:tlist_def_make_settings = {'lang': 'make', 'tags': {'m': 'macro'}} - -" pascal language -let s:tlist_def_pascal_settings = { - \ 'lang': 'pascal', 'tags': { - \ 'f': 'function', - \ 'p': 'procedure' - \ } - \ } - -" perl language -let s:tlist_def_perl_settings = { - \ 'lang': 'perl', 'tags': { - \ 'c': 'constant', - \ 'l': 'label', - \ 'p': 'package', - \ 's': 'subroutine' - \ } - \ } - -" php language -let s:tlist_format_php = 'FormatPhp' -let s:tlist_def_php_settings = { - \ 'lang': 'php', 'tags': { - \ 'c': 'class', - \ 'd': 'constant', - \ 'v': 'variable', - \ 'f': 'function' - \ } - \ } - -" python language -let s:tlist_format_python = 'FormatPython' -let s:tlist_def_python_settings = { - \ 'lang': 'python', 'tags': { - \ 'c': 'class', - \ 'm': 'member', - \ 'f': 'function' - \ } - \ } - -" rexx language -let s:tlist_def_rexx_settings = {'lang': 'rexx', 'tags': {'s': 'subroutine'}} - -" ruby language -let s:tlist_def_ruby_settings = { - \ 'lang': 'ruby', 'tags': { - \ 'c': 'class', - \ 'f': 'method', - \ 'F': 'function', - \ 'm': 'singleton method' - \ } - \ } - -" scheme language -let s:tlist_def_scheme_settings = { - \ 'lang': 'scheme', 'tags': { - \ 's': 'set', - \ 'f': 'function' - \ } - \ } - -" shell language -let s:tlist_def_sh_settings = {'lang': 'sh', 'tags': {'f': 'function'}} - -" C shell language -let s:tlist_def_csh_settings = {'lang': 'sh', 'tags': {'f': 'function'}} - -" Z shell language -let s:tlist_def_zsh_settings = {'lang': 'sh', 'tags': {'f': 'function'}} - -" slang language -let s:tlist_def_slang_settings = { - \ 'lang': 'slang', 'tags': { - \ 'n': 'namespace', - \ 'f': 'function' - \ } - \ } - -" sml language -let s:tlist_def_sml_settings = { - \ 'lang': 'sml', 'tags': { - \ 'e': 'exception', - \ 'c': 'functor', - \ 's': 'signature', - \ 'r': 'structure', - \ 't': 'type', - \ 'v': 'value', - \ 'f': 'function' - \ } - \ } - -" sql language -let s:tlist_def_sql_settings = { - \ 'lang': 'sql', 'tags': { - \ 'c': 'cursor', - \ 'F': 'field', - \ 'P': 'package', - \ 'r': 'record', - \ 's': 'subtype', - \ 't': 'table', - \ 'T': 'trigger', - \ 'v': 'variable', - \ 'f': 'function', - \ 'p': 'procedure' - \ } - \ } - -" tcl language -let s:tlist_def_tcl_settings = { - \ 'lang': 'tcl', 'tags': { - \ 'c': 'class', - \ 'f': 'method', - \ 'm': 'method', - \ 'p': 'procedure' - \ } - \ } - -" vera language -let s:tlist_def_vera_settings = { - \ 'lang': 'vera', 'tags': { - \ 'c': 'class', - \ 'd': 'macro', - \ 'e': 'enumerator', - \ 'f': 'function', - \ 'g': 'enum', - \ 'm': 'member', - \ 'p': 'program', - \ 'P': 'prototype', - \ 't': 'task', - \ 'T': 'typedef', - \ 'v': 'variable', - \ 'x': 'externvar' - \ } - \ } - -"verilog language -let s:tlist_def_verilog_settings = { - \ 'lang': 'verilog', 'tags': { - \ 'm': 'module', - \ 'c': 'constant', - \ 'P': 'parameter', - \ 'e': 'event', - \ 'r': 'register', - \ 't': 'task', - \ 'w': 'write', - \ 'p': 'port', - \ 'v': 'variable', - \ 'f': 'function' - \ } - \ } - -" vim language -let s:tlist_def_vim_settings = { - \ 'lang': 'vim', 'tags': { - \ 'a': 'autocmds', - \ 'v': 'variable', - \ 'f': 'function' - \ } - \ } - -" yacc language -let s:tlist_def_yacc_settings = {'lang': 'yacc', 'tags': {'l': 'label'}} -" }}} - -" AutoOpen() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:AutoOpen() - let open_window = 0 - - let i = 1 - let buf_num = winbufnr(i) - while buf_num != -1 - let filename = fnamemodify(bufname(buf_num), ':p') - if !getbufvar(buf_num, '&diff') && - \ s:FileSupported(filename, getbufvar(buf_num, '&filetype')) - let open_window = 1 - break - endif - let i = i + 1 - let buf_num = winbufnr(i) - endwhile - - if open_window - call s:TaglistToo() - endif -endfunction " }}} - -" Taglist([action]) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -" action -" - not supplied (or -1): toggle -" - 1: open -" - 0: close -function! s:Taglist(...) - if !exists('g:Tlist_Ctags_Cmd') - call EchoError('Unable to find a version of ctags installed.') - return - endif - - if bufname('%') == g:TagList_title - call s:CloseTaglist() - return - endif - - let action = len(a:000) ? a:000[0] : -1 - - if action == -1 || action == 0 - let winnum = bufwinnr(g:TagList_title) - if winnum != -1 - let prevbuf = bufnr('%') - exe winnum . 'wincmd w' - call s:CloseTaglist() - exec bufwinnr(prevbuf) . 'wincmd w' - return - endif - endif - - if action == -1 || action == 1 - call s:ProcessTags(1) - call s:StartAutocmds() - - augroup taglisttoo - autocmd! - autocmd BufUnload __Tag_List__ call s:Cleanup() - autocmd CursorHold * call s:ShowCurrentTag() - augroup END - endif -endfunction " }}} - -" Restore() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -" Restore the taglist, typically after loading from a session file. -function! s:Restore() - if exists('t:taglistoo_restoring') - return - endif - let t:taglistoo_restoring = 1 - - " prevent auto open from firing after session is loaded. - augroup taglisttoo_autoopen - autocmd! - augroup END - - call DelayedCommand( - \ 'let winnum = bufwinnr(g:TagList_title) | ' . - \ 'if winnum != -1 | ' . - \ ' exec "TlistToo" | ' . - \ ' exec "TlistToo" | ' . - \ ' unlet t:taglistoo_restoring | ' . - \ 'endif') -endfunction " }}} - -" s:StartAutocmds() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:StartAutocmds() - augroup taglisttoo_file - autocmd! - autocmd BufEnter * - \ if bufwinnr(g:TagList_title) != -1 | - \ call s:ProcessTags(0) | - \ endif - autocmd BufWritePost * - \ if bufwinnr(g:TagList_title) != -1 | - \ call s:ProcessTags(1) | - \ endif - " bit of a hack to re-process tags if the filetype changes after the tags - " have been processed. - autocmd FileType * - \ if exists('b:ft') | - \ if b:ft != &ft | - \ if bufwinnr(g:TagList_title) != -1 | - \ call s:ProcessTags(1) | - \ endif | - \ endif | - \ else | - \ let b:ft = &ft | - \ endif - autocmd WinLeave * - \ if bufwinnr(g:TagList_title) != -1 | - \ let s:taglisttoo_prevwinnr = winnr() | - \ endif - augroup END -endfunction " }}} - -" s:StopAutocmds() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:StopAutocmds() - augroup taglisttoo_file - autocmd! - augroup END -endfunction " }}} - -" s:CloseTaglist() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:CloseTaglist() - close - call s:Cleanup() -endfunction " }}} - -" s:Cleanup() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:Cleanup() - augroup taglisttoo_file - autocmd! - augroup END - - augroup taglisttoo - autocmd! - augroup END -endfunction " }}} - -" s:ProcessTags(on_open_or_write) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:ProcessTags(on_open_or_write) - " on insert completion prevent vim's jumping back and forth from the - " completion preview window from triggering a re-processing of tags - if pumvisible() - return - endif - - " if we are entering a buffer whose taglist list is already loaded, then - " don't do anything. - if !a:on_open_or_write - let bufnr = bufnr(g:TagList_title) - let filebuf = getbufvar(bufnr, 'taglisttoo_file_bufnr') - if filebuf == bufnr('%') - return - endif - endif - - let filename = expand('%:p') - if filename =~ s:taglisttoo_ignore || filename == '' - return - endif - let filewin = winnr() - - let tags = [] - if s:FileSupported(expand('%:p'), &ft) - if exists('g:tlist_{&ft}_settings') - let settings = g:tlist_{&ft}_settings - let types = join(keys(settings.tags), '') - else - let settings = s:tlist_def_{&ft}_settings - let types = join(keys(settings.tags), '') - endif - - let file = substitute(expand('%:p'), '\', '/', 'g') - - " support generated file contents (like viewing a .class file via jad) - let tempfile = '' - if !filereadable(file) || &buftype == 'nofile' - let tempfile = g:EclimTempDir . '/' . fnamemodify(file, ':t') - if tolower(file) != tolower(tempfile) - let tempfile = escape(tempfile, ' ') - exec 'write! ' . tempfile - let file = tempfile - endif - endif - - try - let command = g:Tlist_Ctags_Cmd_Ctags - - let command .= ' -f - --format=2 --excmd=pattern ' . - \ '--fields=nks --sort=no --language-force= ' . - \ '---types= ""' - let command = substitute(command, '', settings.lang, 'g') - let command = substitute(command, '', types, 'g') - let command = substitute(command, '', file, '') - - if (has('win32') || has('win64')) && command =~ '^"' - let command .= ' "' - endif - - let response = System(command) - finally - if tempfile != '' - call delete(tempfile) - endif - endtry - - if v:shell_error - call EchoError('taglist failed with error code: ' . v:shell_error) - return - endif - - let results = split(response, '\n') - if len(response) == 1 && response[0] == '0' - return - endif - - while len(results) && results[0] =~ 'ctags.*: Warning:' - call remove(results, 0) - endwhile - - let truncated = 0 - if len(results) - " for some reason, vim may truncate the output of system, leading to only - " a partial taglist. - let values = s:ParseOutputLine(results[-1]) - if len(values) < 5 - let truncated = 1 - endif - - for result in results - let values = s:ParseOutputLine(result) - - " filter false positives found in comments. - if values[-1] =~ 'line:[0-9]\+' - exec 'let lnum = ' . substitute(values[-1], 'line:\([0-9]\+\).*', '\1', '') - let line = getline(lnum) - let col = len(line) - len(substitute(line, '^\s*', '', '')) + 1 - if synIDattr(synID(lnum, col, 1), "name") =~ '\([Cc]omment\|[Ss]tring\)' - continue - endif - endif - - " exit if we run into apparent bug in vim that truncates the response - " from system() - if len(values) < 5 - break - endif - - call add(tags, values) - endfor - endif - - if exists('s:tlist_format_{&ft}') - exec 'call s:Window(settings.tags, tags, ' . - \ s:tlist_format_{&ft} . '(settings.tags, tags))' - else - if g:Tlist_Sort_Type == 'name' - call sort(tags) - endif - - call s:Window(settings.tags, tags, s:FormatDefault(settings.tags, tags)) - endif - - " if vim truncated the output, then add a note in the taglist indicating - " the the list has been truncated. - if truncated - setlocal modifiable - call append(line('$'), '') - call append(line('$'), 'Warning: taglist truncated.') - setlocal nomodifiable - endif - - " if the file buffer is no longer in the same window it was, then find its - " new location. Occurs when taglist first opens. - if winbufnr(filewin) != bufnr(filename) - let filewin = bufwinnr(filename) - endif - - if filewin != -1 - exec filewin . 'winc w' - endif - else - " if the file isn't supported, then don't open the taglist window if it - " isn't open already. - let winnum = bufwinnr(g:TagList_title) - if winnum != -1 - call s:Window({}, tags, [[],[]]) - winc p - endif - endif - - call s:ShowCurrentTag() -endfunction " }}} - -" s:ParseOutputLine(line) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:ParseOutputLine(line) - let pre = substitute(a:line, '\(.\{-}\)\t\/\^.*', '\1', '') - let pattern = substitute(a:line, '.\{-}\(\/\^.*\$\/;"\).*', '\1', '') - let post = substitute(a:line, '.*\$\/;"\t', '', '') - return split(pre, '\t') + [pattern] + split(post, '\t') -endfunction " }}} - -" s:FormatDefault(types, tags) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -" All format functions must return a two element list containing: -" result[0] - A list of length len(result[1]) where each value specifies the -" tag index such that result[0][line('.') - 1] == tag index for -" the current line. -" For content lines that do no map to a tag, use -1 as the value. -" result[1] - A list of lines to be inserted as content into the taglist -" window. -function! s:FormatDefault(types, tags) - let lines = [] - let content = [] - - call add(content, expand('%:t')) - call add(lines, -1) - - for key in keys(a:types) - let values = filter(copy(a:tags), 'len(v:val) > 3 && v:val[3] == key') - call s:FormatType(a:tags, a:types[key], values, lines, content, "\t") - endfor - - return [lines, content] -endfunction " }}} - -" s:JumpToTag() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:JumpToTag() - if line('.') > len(b:taglisttoo_content[0]) - return - endif - - let index = b:taglisttoo_content[0][line('.') - 1] - if index == -1 - return - endif - - let tag_info = b:taglisttoo_tags[index] - - call s:StopAutocmds() - - " handle case of buffer open in multiple windows. - if s:taglisttoo_prevwinnr && - \ winbufnr(s:taglisttoo_prevwinnr) == b:taglisttoo_file_bufnr - exec s:taglisttoo_prevwinnr . 'winc w' - else - exec bufwinnr(b:taglisttoo_file_bufnr) . 'winc w' - endif - - call s:StartAutocmds() - - let lnum = s:GetTagLineNumber(tag_info) - let pattern = s:GetTagPattern(tag_info) - - " account for my plugin which removes trailing spaces from the file - let pattern = escape(pattern, '.~*[]') - let pattern = substitute(pattern, '\s\+\$$', '\\s*$', '') - - if getline(lnum) =~ pattern - mark ' - call cursor(lnum, 1) - call s:ShowCurrentTag() - else - let pos = getpos('.') - - call cursor(lnum, 1) - - let up = search(pattern, 'bcnW') - let down = search(pattern, 'cnW') - - " pattern found below recorded line - if !up && down - let line = down - - " pattern found above recorded line - elseif !down && up - let line = up - - " pattern found above and below recorded line - elseif up && down - " use the closest match to the recorded line - if (lnum - up) < (down - lnum) - let line = up - else - let line = down - endif - - " pattern not found. - else - let line = 0 - endif - - call setpos('.', pos) - if line - mark ' - call cursor(line, 1) - call s:ShowCurrentTag() - endif - endif -endfunction " }}} - -" s:Window(types, tags, content) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:Window(types, tags, content) - let filename = expand('%:t') - let file_bufnr = bufnr('%') - - let winnum = bufwinnr(g:TagList_title) - if winnum != -1 - exe winnum . 'wincmd w' - else - call VerticalToolWindowOpen(g:TagList_title, 10) - - setlocal filetype=taglist - setlocal buftype=nofile - setlocal bufhidden=delete - setlocal noswapfile - setlocal nobuflisted - setlocal nowrap - setlocal tabstop=2 - - syn match TagListFileName "^.*\%1l.*" - hi link TagListFileName Identifier - hi link TagListKeyword Statement - hi TagListCurrentTag term=bold,underline cterm=bold,underline gui=bold,underline - - nnoremap :call JumpToTag() - endif - - let pos = [0, 1, 1, 0] - " if we are updating the taglist for the same file, then preserve the - " cursor position. - if len(a:content[1]) > 0 && getline(1) == a:content[1][0] - let pos = getpos('.') - endif - - setlocal modifiable - silent 1,$delete _ - call append(1, a:content[1]) - silent retab - silent 1,1delete _ - setlocal nomodifiable - - call setpos('.', pos) - - " if the entire taglist can fit in the window, then reposition the content - " just in case the previous contents result in the current contents being - " scrolled up a bit. - if len(a:content[1]) < winheight(winnr()) - normal! zb - endif - - silent! syn clear TagListKeyword - for value in values(a:types) - exec 'syn keyword TagListKeyword ' . value - endfor - syn match TagListKeyword /^Warning:/ - - let b:taglisttoo_content = a:content - let b:taglisttoo_tags = a:tags - let b:taglisttoo_file_bufnr = file_bufnr -endfunction " }}} - -" s:ShowCurrentTag() eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:ShowCurrentTag() - if s:FileSupported(expand('%:p'), &ft) && bufwinnr(g:TagList_title) != -1 - let tags = getbufvar(g:TagList_title, 'taglisttoo_tags') - let content = getbufvar(g:TagList_title, 'taglisttoo_content') - - let clnum = line('.') - let tlnum = 0 - let tindex = -1 - - let index = 0 - for tag in tags - let lnum = s:GetTagLineNumber(tag) - let diff = clnum - lnum - if diff >= 0 && (diff < (clnum - tlnum)) - let tlnum = lnum - let current = tag - let tindex = index - endif - let index += 1 - endfor - - if exists('current') - let cwinnum = winnr() - let twinnum = bufwinnr(g:TagList_title) - - call ExecWithoutAutocmds(twinnum . 'winc w') - - let index = index(content[0], tindex) + 1 - syn clear TagListCurrentTag - exec 'syn match TagListCurrentTag "\S*\%' . index . 'l\S*"' - if index != line('.') - call cursor(index, 0) - call winline() - endif - - call ExecWithoutAutocmds(cwinnum . 'winc w') - endif - endif -endfunction " }}} - -" s:FileSupported(filename, ftype) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -" Check whether tag listing is supported for the specified file -function! s:FileSupported(filename, ftype) - " Skip buffers with no names, buffers with filetype not set, and vimballs - if a:filename == '' || a:ftype == '' || expand('%:e') == 'vba' - return 0 - endif - - " Skip files which are not supported by exuberant ctags - " First check whether default settings for this filetype are available. - " If it is not available, then check whether user specified settings are - " available. If both are not available, then don't list the tags for this - " filetype - let var = 's:tlist_def_' . a:ftype . '_settings' - if !exists(var) - let var = 'g:tlist_' . a:ftype . '_settings' - if !exists(var) - return 0 - endif - endif - - " Skip files which are not readable or files which are not yet stored - " to the disk - if !filereadable(a:filename) - return 0 - endif - - return 1 -endfunction " }}} - -" s:GetTagLineNumber(tag) eclim/autoload/eclim/taglist/taglisttoo.vim {{{ -function! s:GetTagLineNumber(tag) - if len(a:tag) > 4 - return substitute(a:tag[4], '.*:\(.*\)', '\1', '') - endif - return 0 -endfunction " }}} - - -" FormatJava(types, tags) eclim/autoload/eclim/taglist/lang/java.vim {{{ -function! FormatJava(types, tags) - let lines = [] - let content = [] - - call add(content, expand('%:t')) - call add(lines, -1) - - let package = filter(copy(a:tags), 'v:val[3] == "p"') - call s:FormatType( - \ a:tags, a:types['p'], package, lines, content, "\t") - - let classes = filter(copy(a:tags), 'v:val[3] == "c"') - - " sort classes alphabetically except for the primary containing class. - if len(classes) > 1 && g:Tlist_Sort_Type == 'name' - let classes = [classes[0]] + sort(classes[1:]) - endif - - for class in classes - call add(content, "") - call add(lines, -1) - let visibility = s:GetVisibility(class) - call add(content, "\t" . visibility . a:types['c'] . ' ' . class[0]) - call add(lines, index(a:tags, class)) - - let fields = filter(copy(a:tags), - \ 'v:val[3] == "f" && len(v:val) > 5 && v:val[5] =~ "class:.*\\<" . class[0] . "$"') - call s:FormatType( - \ a:tags, a:types['f'], fields, lines, content, "\t\t") - - let methods = filter(copy(a:tags), - \ 'v:val[3] == "m" && len(v:val) > 5 && v:val[5] =~ "class:.*\\<" . class[0] . "$"') - call s:FormatType( - \ a:tags, a:types['m'], methods, lines, content, "\t\t") - endfor - - let interfaces = filter(copy(a:tags), 'v:val[3] == "i"') - if g:Tlist_Sort_Type == 'name' - call sort(interfaces) - endif - for interface in interfaces - call add(content, "") - call add(lines, -1) - let visibility = s:GetVisibility(interface) - call add(content, "\t" . visibility . a:types['i'] . ' ' . interface[0]) - call add(lines, index(a:tags, interface)) - - let fields = filter(copy(a:tags), - \ 'v:val[3] == "f" && len(v:val) > 5 && v:val[5] =~ "interface:.*\\<" . interface[0] . "$"') - call s:FormatType( - \ a:tags, a:types['f'], fields, lines, content, "\t\t") - - let methods = filter(copy(a:tags), - \ 'v:val[3] == "m" && len(v:val) > 5 && v:val[5] =~ "interface:.*\\<" . interface[0] . "$"') - call s:FormatType( - \ a:tags, a:types['m'], methods, lines, content, "\t\t") - endfor - - return [lines, content] -endfunction " }}} - -" FormatJavascript(types, tags) eclim/autoload/eclim/taglist/lang/javascript.vim {{{ -function! FormatJavascript(types, tags) - let pos = getpos('.') - - let lines = [] - let content = [] - - call add(content, expand('%:t')) - call add(lines, -1) - - let object_contents = [] - - let objects = filter(copy(a:tags), 'v:val[3] == "o"') - let members = filter(copy(a:tags), 'v:val[3] == "m"') - let functions = filter(copy(a:tags), - \ 'v:val[3] == "f" && v:val[2] =~ "\\"') - let object_bounds = {} - for object in objects - exec 'let object_start = ' . split(object[4], ':')[1] - call cursor(object_start, 1) - while search('{', 'W') && s:SkipComments() - " no op - endwhile - let object_end = searchpair('{', '', '}', 'W', 's:SkipComments()') - - let methods = [] - let indexes = [] - let index = 0 - for fct in members - if len(fct) > 3 - exec 'let fct_line = ' . split(fct[4], ':')[1] - if fct_line > object_start && fct_line < object_end - call add(methods, fct) - elseif fct_line > object_end - break - elseif fct_line < object_end - call add(indexes, index) - endif - endif - let index += 1 - endfor - call reverse(indexes) - for i in indexes - call remove(members, i) - endfor - - let indexes = [] - let index = 0 - for fct in functions - if len(fct) > 3 - exec 'let fct_line = ' . split(fct[4], ':')[1] - if fct_line > object_start && fct_line < object_end - call add(methods, fct) - call add(indexes, index) - elseif fct_line == object_start - call add(indexes, index) - elseif fct_line > object_end - break - endif - endif - let index += 1 - endfor - call reverse(indexes) - for i in indexes - call remove(functions, i) - endfor - - if len(methods) > 0 - let parent_object = s:GetParentObject( - \ object_contents, object_bounds, object_start, object_end) - " remove methods from the parent if necessary - if len(parent_object) - call filter(parent_object.methods, 'index(methods, v:val) == -1') - endif - let object_bounds[string(object)] = [object_start, object_end] - call add(object_contents, {'object': object, 'methods': methods}) - endif - endfor - - if len(functions) > 0 - call add(content, "") - call add(lines, -1) - call s:FormatType( - \ a:tags, a:types['f'], functions, lines, content, "\t") - endif - - if g:Tlist_Sort_Type == 'name' - call sort(object_contents, function('s:ObjectComparator')) - endif - - for object_content in object_contents - call add(content, "") - call add(lines, -1) - call add(content, "\t" . a:types['o'] . ' ' . object_content.object[0]) - call add(lines, index(a:tags, object_content.object)) - - call s:FormatType( - \ a:tags, a:types['f'], object_content.methods, lines, content, "\t\t") - endfor - - call setpos('.', pos) - - return [lines, content] -endfunction " }}} - -" s:ObjectComparator(o1, o2) eclim/autoload/eclim/taglist/lang/javascript.vim {{{ -function s:ObjectComparator(o1, o2) - let n1 = a:o1['object'][0] - let n2 = a:o2['object'][0] - return n1 == n2 ? 0 : n1 > n2 ? 1 : -1 -endfunction " }}} - -" s:SkipComments() eclim/autoload/eclim/taglist/lang/javascript.vim {{{ -function s:SkipComments() - let synname = synIDattr(synID(line('.'), col('.'), 1), "name") - return synname =~ '\([Cc]omment\|[Ss]tring\)' -endfunction " }}} - -" s:GetParentObject(objects, bounds, start, end) eclim/autoload/eclim/taglist/lang/javascript.vim {{{ -function s:GetParentObject(objects, bounds, start, end) - for key in keys(a:bounds) - let range = a:bounds[key] - if range[0] < a:start && range[1] > a:end - for object_content in a:objects - if string(object_content.object) == key - return object_content - endif - endfor - break - endif - endfor - return {} -endfunction " }}} - -" FormatType(tags, type, values, lines, content, indent) eclim/autoload/eclim/taglist/util.vim {{{ -" tags: The list of tag results from eclim/ctags. -" type: The display name of the tag type we are formatting. -" values: List of tag results for the type. -" lines: The list representing the mapping of content entries to tag info. -" content: The list representing the display that we will add to. -" indent: The indentation to use on the display (string). -function! s:FormatType(tags, type, values, lines, content, indent) - if len(a:values) > 0 - if g:Tlist_Sort_Type == 'name' - call sort(a:values) - endif - - call add(a:content, a:indent . a:type) - call add(a:lines, -1) - - for value in a:values - let visibility = s:GetVisibility(value) - call add(a:content, "\t" . a:indent . visibility . value[0]) - call add(a:lines, index(a:tags, value)) - endfor - endif -endfunction " }}} - -" GetTagPattern(tag) eclim/autoload/eclim/taglist/util.vim {{{ -function! s:GetTagPattern(tag) - return strpart(a:tag[2], 1, len(a:tag[2]) - 4) -endfunction " }}} - -" GetVisibility(tag) eclim/autoload/eclim/taglist/util.vim {{{ -" Gets the visibility string for the supplied tag. -function! s:GetVisibility(tag) - let pattern = s:GetTagPattern(a:tag) - if pattern =~ '\' - if pattern =~ '\' - return '*' - endif - return '+' - elseif pattern =~ '\' - return '#' - elseif pattern =~ '\' - return '-' - endif - return '' -endfunction " }}} - -" FormatPhp(types, tags) eclim/autoload/eclim/taglist/lang/php.vim {{{ -function! FormatPhp(types, tags) - let pos = getpos('.') - - let lines = [] - let content = [] - - call add(content, expand('%:t')) - call add(lines, -1) - - let top_functions = filter(copy(a:tags), 'v:val[3] == "f"') - - let class_contents = [] - let classes = filter(copy(a:tags), 'v:val[3] == "c"') - if g:Tlist_Sort_Type == 'name' - call sort(classes) - endif - for class in classes - exec 'let object_start = ' . split(class[4], ':')[1] - call cursor(object_start, 1) - call search('{', 'W') - let object_end = searchpair('{', '', '}', 'W') - - let functions = [] - let indexes = [] - let index = 0 - for fct in top_functions - if len(fct) > 3 - exec 'let fct_line = ' . split(fct[4], ':')[1] - if fct_line > object_start && fct_line < object_end - call add(functions, fct) - call add(indexes, index) - endif - endif - let index += 1 - endfor - call reverse(indexes) - for i in indexes - call remove(top_functions, i) - endfor - - call add(class_contents, {'class': class, 'functions': functions}) - endfor - - let interface_contents = [] - let interfaces = filter(copy(a:tags), 'v:val[3] == "i"') - if g:Tlist_Sort_Type == 'name' - call sort(interfaces) - endif - for interface in interfaces - exec 'let object_start = ' . split(interface[4], ':')[1] - call cursor(object_start, 1) - call search('{', 'W') - let object_end = searchpair('{', '', '}', 'W') - - let functions = [] - let indexes = [] - let index = 0 - for fct in top_functions - if len(fct) > 3 - exec 'let fct_line = ' . split(fct[4], ':')[1] - if fct_line > object_start && fct_line < object_end - call add(functions, fct) - call add(indexes, index) - endif - endif - let index += 1 - endfor - call reverse(indexes) - for i in indexes - call remove(top_functions, i) - endfor - - call add(interface_contents, {'interface': interface, 'functions': functions}) - endfor - - if len(top_functions) > 0 - call add(content, "") - call add(lines, -1) - call s:FormatType( - \ a:tags, a:types['f'], top_functions, lines, content, "\t") - endif - - for class_content in class_contents - call add(content, "") - call add(lines, -1) - call add(content, "\t" . a:types['c'] . ' ' . class_content.class[0]) - call add(lines, index(a:tags, class_content.class)) - - call s:FormatType( - \ a:tags, a:types['f'], class_content.functions, lines, content, "\t\t") - endfor - - for interface_content in interface_contents - call add(content, "") - call add(lines, -1) - call add(content, "\t" . a:types['i'] . ' ' . interface_content.interface[0]) - call add(lines, index(a:tags, interface_content.interface)) - - call s:FormatType( - \ a:tags, a:types['f'], interface_content.functions, lines, content, "\t\t") - endfor - - call setpos('.', pos) - - return [lines, content] -endfunction " }}} - -" FormatPython(types, tags) eclim/autoload/eclim/taglist/lang/python.vim {{{ -function! FormatPython(types, tags) - let lines = [] - let content = [] - - call add(content, expand('%:t')) - call add(lines, -1) - - let functions = filter(copy(a:tags), 'len(v:val) > 3 && v:val[3] == "f"') - call s:FormatType( - \ a:tags, a:types['f'], functions, lines, content, "\t") - - let classes = filter(copy(a:tags), 'len(v:val) > 3 && v:val[3] == "c"') - if g:Tlist_Sort_Type == 'name' - call sort(classes) - endif - - for class in classes - call add(content, "") - call add(lines, -1) - call add(content, "\t" . a:types['c'] . ' ' . class[0]) - call add(lines, index(a:tags, class)) - - let members = filter(copy(a:tags), - \ 'len(v:val) > 5 && v:val[3] == "m" && v:val[5] == "class:" . class[0]') - call s:FormatType( - \ a:tags, a:types['m'], members, lines, content, "\t\t") - endfor - - return [lines, content] -endfunction " }}} - - -" GlobalVariables eclim/autoload/eclim/display/window.vim {{{ -let g:VerticalToolBuffers = {} - -if !exists('g:VerticalToolWindowSide') - let g:VerticalToolWindowSide = 'left' -endif - -if g:VerticalToolWindowSide == 'right' - let g:VerticalToolWindowPosition = 'botright vertical' -else - let g:VerticalToolWindowPosition = 'topleft vertical' -endif - -if !exists('g:VerticalToolWindowWidth') - let g:VerticalToolWindowWidth = 40 -endif -" }}} - -" VerticalToolWindowOpen(name, weight) eclim/autoload/eclim/display/window.vim {{{ -" Handles opening windows in the vertical tool window on the left (taglist, -" project tree, etc.) -function! VerticalToolWindowOpen(name, weight) - let taglist_window = exists('g:TagList_title') ? bufwinnr(g:TagList_title) : -1 - if exists('g:Tlist_Use_Horiz_Window') && g:Tlist_Use_Horiz_Window - let taglist_window = -1 - endif - - let relative_window = 0 - let relative_window_loc = 'below' - if taglist_window != -1 || len(g:VerticalToolBuffers) > 0 - if taglist_window != -1 - let relative_window = taglist_window - endif - for toolbuf in keys(g:VerticalToolBuffers) - exec 'let toolbuf = ' . toolbuf - if bufwinnr(toolbuf) != -1 - if relative_window == 0 - let relative_window = bufwinnr(toolbuf) - if getbufvar(toolbuf, 'weight') > a:weight - let relative_window_loc = 'below' - else - let relative_window_loc = 'above' - endif - elseif getbufvar(toolbuf, 'weight') > a:weight - let relative_window = bufwinnr(toolbuf) - let relative_window_loc = 'below' - endif - endif - endfor - endif - - if relative_window != 0 - let wincmd = relative_window . 'winc w | ' . relative_window_loc . ' ' - else - let wincmd = g:VerticalToolWindowPosition . ' ' . g:VerticalToolWindowWidth - endif - - let escaped = substitute( - \ a:name, '\(.\{-}\)\[\(.\{-}\)\]\(.\{-}\)', '\1[[]\2[]]\3', 'g') - let bufnum = bufnr(escaped) - let name = bufnum == -1 ? a:name : '+buffer' . bufnum - silent call ExecWithoutAutocmds(wincmd . ' split ' . name) - - setlocal winfixwidth - setlocal nonumber - - let b:weight = a:weight - let bufnum = bufnr('%') - let g:VerticalToolBuffers[bufnum] = a:name - augroup eclim_vertical_tool_windows - autocmd! - autocmd BufDelete * call s:PreventCloseOnBufferDelete() - autocmd BufEnter * nested call s:CloseIfLastWindow() - augroup END - if exists('g:TagList_title') && - \ !exists('g:TagListToo') && - \ (!exists('g:Tlist_Use_Horiz_Window') || !g:Tlist_Use_Horiz_Window) - augroup eclim_vertical_tool_windows_move - autocmd! - augroup END - exec 'autocmd BufWinEnter ' . g:TagList_title . - \ ' call s:MoveRelativeTo(g:TagList_title)' - endif - augroup eclim_vertical_tool_windows_buffer - exec 'autocmd BufWinLeave ' . - \ 'silent! call remove(g:VerticalToolBuffers, ' . bufnum . ') | ' . - \ 'autocmd! eclim_vertical_tool_windows_buffer * ' - augroup END -endfunction " }}} - -" GetWindowOptions(winnum) eclim/autoload/eclim/display/window.vim {{{ -" Gets a dictionary containing all the localy set options for the specified -" window. -function! GetWindowOptions(winnum) - let curwin = winnr() - try - exec a:winnum . 'winc w' - redir => list - silent exec 'setlocal' - redir END - finally - exec curwin . 'winc w' - endtry - - let list = substitute(list, '---.\{-}---', '', '') - let winopts = {} - for wopt in split(list, '\_s\+')[1:] - if wopt =~ '^[a-z]' - if wopt =~ '=' - let key = substitute(wopt, '\(.\{-}\)=.*', '\1', '') - let value = substitute(wopt, '.\{-}=\(.*\)', '\1', '') - let winopts[key] = value - else - let winopts[wopt] = '' - endif - endif - endfor - return winopts -endfunction " }}} - -" SetWindowOptions(winnum, options) eclim/autoload/eclim/display/window.vim {{{ -" Given a dictionary of options, sets each as local options for the specified -" window. -function! SetWindowOptions(winnum, options) - let curwin = winnr() - try - exec a:winnum . 'winc w' - for key in keys(a:options) - if key =~ '^no' - silent! exec 'setlocal ' . key - else - silent! exec 'setlocal ' . key . '=' . a:options[key] - endif - endfor - finally - exec curwin . 'winc w' - endtry -endfunction " }}} - -" s:CloseIfLastWindow() eclim/autoload/eclim/display/window.vim {{{ -function! s:CloseIfLastWindow() - if histget(':', -1) !~ '^bd' - let numtoolwindows = 0 - for toolbuf in keys(g:VerticalToolBuffers) - exec 'let toolbuf = ' . toolbuf - if bufwinnr(toolbuf) != -1 - let numtoolwindows += 1 - endif - endfor - if winnr('$') == numtoolwindows - if tabpagenr('$') > 1 - tabclose - else - quitall - endif - endif - endif -endfunction " }}} - -" s:MoveRelativeTo(name) eclim/autoload/eclim/display/window.vim {{{ -function! s:MoveRelativeTo(name) - for toolbuf in keys(g:VerticalToolBuffers) - exec 'let toolbuf = ' . toolbuf - if bufwinnr(toolbuf) != -1 - call setwinvar(bufwinnr(toolbuf), 'marked_for_removal', 1) - let winoptions = GetWindowOptions(bufwinnr(toolbuf)) - call remove(winoptions, 'filetype') - call remove(winoptions, 'syntax') - call VerticalToolWindowOpen( - \ g:VerticalToolBuffers[toolbuf], getbufvar(toolbuf, 'weight')) - call SetWindowOptions(winnr(), winoptions) - endif - endfor - - let winnum = 1 - while winnum <= winnr('$') - if getwinvar(winnum, 'marked_for_removal') == 1 - exec winnum . 'winc w' - close - else - let winnum += 1 - endif - endwhile - call VerticalToolWindowRestore() -endfunction " }}} - -" s:PreventCloseOnBufferDelete() eclim/autoload/eclim/display/window.vim {{{ -function! s:PreventCloseOnBufferDelete() - let numtoolwindows = 0 - for toolbuf in keys(g:VerticalToolBuffers) - exec 'let toolbuf = ' . toolbuf - if bufwinnr(toolbuf) != -1 - let numtoolwindows += 1 - endif - endfor - - let index = 1 - let numtempwindows = 0 - let tempbuffers = [] - while index <= winnr('$') - let buf = winbufnr(index) - if buf != -1 && getbufvar(buf, 'eclim_temp_window') != '' - call add(tempbuffers, buf) - endif - let index += 1 - endwhile - - if winnr('$') == (numtoolwindows + len(tempbuffers)) - let toolbuf = bufnr('%') - if g:VerticalToolWindowSide == 'right' - vertical topleft new - else - vertical botright new - endif - setlocal noreadonly modifiable - let winnum = winnr() - exec 'let bufnr = ' . expand('') - - redir => list - silent exec 'buffers' - redir END - - " build list of buffers open in other tabs to exclude - let tabbuffers = [] - let lasttab = tabpagenr('$') - let index = 1 - while index <= lasttab - if index != tabpagenr() - for bnum in tabpagebuflist(index) - call add(tabbuffers, bnum) - endfor - endif - let index += 1 - endwhile - - " build list of buffers not open in any window - let buffers = [] - for entry in split(list, '\n') - exec 'let bnum = ' . substitute(entry, '\s*\([0-9]\+\).*', '\1', '') - if bnum != bufnr && index(tabbuffers, bnum) == -1 && bufwinnr(bnum) == -1 - if bnum < bufnr - call insert(buffers, bnum) - else - call add(buffers, bnum) - endif - endif - endfor - - " we found a hidden buffer, so open it - if len(buffers) > 0 - exec 'buffer ' . buffers[0] - doautocmd BufEnter - doautocmd BufWinEnter - doautocmd BufReadPost - endif - - exec bufwinnr(toolbuf) . 'winc w' - exec 'vertical resize ' . g:VerticalToolWindowWidth - - " fix the position of the temp windows - if len(tempbuffers) > 0 - for buf in tempbuffers - " open the buffer in the temp window position - botright 10new - exec 'buffer ' . buf - setlocal winfixheight - - " close the old window - let winnr = winnr() - let index = 1 - while index <= winnr('$') - if winbufnr(index) == buf && index != winnr - exec index . 'winc w' - close - winc p - break - endif - let index += 1 - endwhile - endfor - endif - - exec winnum . 'winc w' - endif -endfunction " }}} - - -" End TagListToo: }}} - - " vim:ft=vim:fdm=marker