diff --git a/editor/vi/component.xml b/editor/vi/component.xml
new file mode 100644
index 0000000000..8561f47953
--- /dev/null
+++ b/editor/vi/component.xml
@@ -0,0 +1,3 @@
+
+ editor.vi
+
diff --git a/editor/vi/vim/actions.py b/editor/vi/vim/actions.py
new file mode 100644
index 0000000000..2ccdf8957d
--- /dev/null
+++ b/editor/vi/vim/actions.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Licensed under the GNU General Public License, version 3.
+# See the file http://www.gnu.org/licenses/gpl.txt
+
+from pisi.actionsapi import autotools
+from pisi.actionsapi import pisitools
+from pisi.actionsapi import shelltools
+from pisi.actionsapi import get
+
+
+#WorkDir = "vim74"
+
+def setup():
+ # TODO: do we need that ?
+ shelltools.export("CXXFLAGS", get.CXXFLAGS().replace("-D_FORTIFY_SOURCE=2", ""))
+ shelltools.export("CFLAGS", get.CFLAGS().replace("-D_FORTIFY_SOURCE=2", ""))
+ pisitools.dosed("runtime/tools/mve.awk", "#!/usr/bin/nawk -f", "#!/usr/bin/awk -f")
+
+ # define the place for the global (g)vimrc file (set to /etc/vim/vimrc)
+ shelltools.echo("src/feature.h", "#define SYS_VIMRC_FILE \"/etc/vim/vimrc\"")
+
+ # our binary ctags file is names as exuberant-ctags
+ pisitools.dosed("runtime/doc/syntax.txt", "(ctags(\"| [-*.]|\\s+/))", "exuberant-\\1")
+ pisitools.dosed("runtime/doc/tagsrch.txt", "(ctags(\"| [-*.]|\\s+/))", "exuberant-\\1")
+ pisitools.dosed("runtime/doc/usr_29.txt", "(ctags(\"| [-*.]|\\s+/))", "exuberant-\\1")
+ pisitools.dosed("runtime/menu.vim", "(ctags(\"| [-*.]|\\s+/))", "exuberant-\\1")
+ pisitools.dosed("src/configure.in", "(ctags(\"| [-*.]|\\s+/))", "exuberant-\\1")
+
+ # TODO: do we need that ?
+ pisitools.dosed("src/configure.in", r"libc\.h", "")
+
+ # TODO: we could need that
+ #autotools.make("-C src autoconf")
+
+ # TODO: * We should use "big" feature instead of "huge".
+ # * Investigate impacts on current use
+ options ="--with-features=huge \
+ --enable-multibyte \
+ --enable-perlinterp \
+ --enable-pythoninterp \
+ --enable-rubyinterp \
+ --enable-gui=no \
+ --with-tlib=ncurses \
+ --prefix=/usr \
+ --localstatedir=/var/lib/vim \
+ --with-features=big \
+ --disable-acl \
+ --with-compiledby=PisiLinux \
+ --enable-gpm \
+ --enable-acl \
+ --enable-cscope \
+ --disable-netbeans \
+ --enable-perlinterp \
+ --disable-luainterp \
+ --with-x=no \
+ --with-modified-by=PisiLinux"
+
+ if get.buildTYPE() == "gui":
+ options += " --enable-gui=gtk2 \
+ --with-vim-name=gvim \
+ --with-view-name=gview \
+ --with-x=yes"
+
+ autotools.configure(options)
+
+def build():
+ autotools.make()
+
+def install():
+ autotools.rawInstall("VIMRCLOC=/etc/vim DESTDIR=%s" % get.installDIR())
+
+ # enough for gui building, quit here
+ if get.buildTYPE() == "gui":
+ return
+
+ # Vi != Vim, it's hard to break habbits
+ pisitools.dosym("vim", "/usr/bin/vi")
+ pisitools.dosym("/usr/bin/vim", "/bin/ex")
+
diff --git a/editor/vi/vim/files/gvim.desktop b/editor/vi/vim/files/gvim.desktop
new file mode 100644
index 0000000000..96a230309a
--- /dev/null
+++ b/editor/vi/vim/files/gvim.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=gVim
+GenericName[en]=Gvim Text Editor
+GenericName[tr]=Gvim Metin Düzenleyici
+Comment[en]=A highly configurable text editor
+Comment[tr]=Özelleştirilebilir metin düzenleyici
+Exec=/usr/bin/gvim -f
+Icon=/usr/share/pixmaps/gvim.xpm
+Terminal=false
+Type=Application
+MimeType=text/css;text/html;text/htmlh;text/plain;text/rss;text/sgml;text/x-adasrc;text/x-authors;text/x-c++hdr;text/x-c++src;text/x-copying;text/x-credits;text/x-csharp;text/x-csrc;text/x-dtd;text/x-fortran;text/x-gettext-translation-template;text/x-gettext-translation;text/x-gtkrc;text/x-haskell;text/x-idl;text/x-install;text/x-java;text/x-js;text/x-ksh;text/x-ksysv-log;text/x-literate-haskell;text/x-log;text/x-makefile;text/x-moc;text/x-msil;text/x-nemerle;text/x-objcsrc;text/x-pascal;text/x-patch;text/x-readme;text/x-scheme;text/x-setext;text/x-sql;text/x-tcl;text/x-tex;text/x-texinfo;text/x-troff-me;text/x-troff-mm;text/x-troff-ms;text/x-uil;text/x-vb;text/xml;
+Categories=Application;TextEditor;
diff --git a/editor/vi/vim/files/gvim.xpm b/editor/vi/vim/files/gvim.xpm
new file mode 100644
index 0000000000..694720ac30
--- /dev/null
+++ b/editor/vi/vim/files/gvim.xpm
@@ -0,0 +1,46 @@
+/* XPM */
+static char *magick[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 8 1",
+" c Gray0",
+". c #000080",
+"X c #008000",
+"o c Green",
+"O c #808080",
+"+ c #c0c0c0",
+"@ c Gray100",
+"# c None",
+/* pixels */
+"############### ###############",
+"############## oo ##############",
+"### oXXo # ###",
+"## @@@@@@@@@@@ XXXo @@@@@@@@@ ##",
+"## @+++++++++++ XXX @+++++++++ #",
+"### ++++++++++O XXXX ++++++++O #",
+"#### O++++++OO XXXXXX O+++++OO #",
+"#### @++++++O XXXXXX @+++++OO ##",
+"#### @++++++O XXXXX @@++++OO ###",
+"#### @++++++O XXXX @@++++OO ####",
+"#### @++++++O XXX @@++++OO #####",
+"#### @++++++O XX @@++++OO . ####",
+"### @++++++O X @@++++OO XX. ###",
+"## o @++++++O @@++++OO XXXX. ##",
+"# oX @++++++O @@++++OO XXXXXX. #",
+" oXX @++++++O@@++++OO XXXXXXXX. ",
+" oXX @++++++O@++++OO XXXXXXXXX. ",
+"# oX @++++++O++++OO XXXXXXXXX. #",
+"## o @++++++++++ XXXXXXXXX. ##",
+"### @+++++++++ ++ XXXXXXXX. ###",
+"#### @+++++++++ ++ XXXXXXX. ####",
+"#### @++++++++O X X ###",
+"#### @+++++++O +++ +++ +++ ++ ##",
+"#### @++++++OO ++ ++++++++++ #",
+"#### @+++++OO ++ ++..++ + ##",
+"#### @++++OO X ++ ++. ++ ++ ##",
+"#### @+++OO XX ++ ++ ++ ++ ##",
+"#### @++OO X ++ ++ ++ ++ ###",
+"##### +OO ## +++ ++ ++ +++ ##",
+"###### #### . ## ## ###",
+"############## .. ##############",
+"############### ###############"
+};
diff --git a/editor/vi/vim/files/gvimtutor b/editor/vi/vim/files/gvimtutor
new file mode 100644
index 0000000000..16152b5500
--- /dev/null
+++ b/editor/vi/vim/files/gvimtutor
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# Start GUI Vim on a copy of the tutor file.
+
+# Usage: gvimtutor [xx]
+# See vimtutor for usage.
+
+exec `dirname $0`/vimtutor -g "$@"
diff --git a/editor/vi/vim/files/official/7.4-461-tar.xz b/editor/vi/vim/files/official/7.4-461-tar.xz
new file mode 100644
index 0000000000..76e355930b
Binary files /dev/null and b/editor/vi/vim/files/official/7.4-461-tar.xz differ
diff --git a/editor/vi/vim/files/pisilinux/actions.vim b/editor/vi/vim/files/pisilinux/actions.vim
new file mode 100644
index 0000000000..379e97358c
--- /dev/null
+++ b/editor/vi/vim/files/pisilinux/actions.vim
@@ -0,0 +1,42 @@
+" Vim plugin
+" Purpose: Intelligently create content for PISI's action.py files
+" Author: A. Murat Eren
+" Copyright: Copyright (c) 2005 A. Murat Eren & S. Çağlar Onur
+" Licence: You may redistribute this under the terms of the GNU GPL v2..
+
+if &compatible || v:version < 603
+ finish
+endif
+
+fun! MakeNewActionsPY()
+ set nopaste
+
+ 0 put = '# -*- coding: utf-8 -*-'
+ put = '#'
+ put = '# Copyright 2011 TUBITAK/BILGEM'
+ put = '# Licensed under the GNU General Public License, version 2.'
+ put = '# See the file http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt'
+ put = ''
+ put = 'from pisi.actionsapi import autotools'
+ put = 'from pisi.actionsapi import pisitools'
+ put = 'from pisi.actionsapi import get'
+ put = ''
+ put = 'def setup():'
+ put = ' pass'
+ put = ''
+ put = 'def build():'
+ put = ' pass'
+ put = ''
+ put = 'def install():'
+ put = ' pass'
+ 14
+endfun
+
+com! -nargs=0 NewActionsPY call MakeNewActionsPY()
+
+augroup NewActionsPY
+ au!
+ autocmd BufNewFile actions.py call MakeNewActionsPY()
+augroup END
+
+" vim: set et foldmethod=marker : "
diff --git a/editor/vi/vim/files/pisilinux/bash_completion.patch b/editor/vi/vim/files/pisilinux/bash_completion.patch
new file mode 100644
index 0000000000..e42f4e5b41
--- /dev/null
+++ b/editor/vi/vim/files/pisilinux/bash_completion.patch
@@ -0,0 +1,11 @@
+diff -Nur vim72-old/runtime/filetype.vim vim72/runtime/filetype.vim
+--- vim72-old/runtime/filetype.vim 2008-10-18 01:14:23.000000000 +0300
++++ vim72/runtime/filetype.vim 2008-10-18 01:15:01.000000000 +0300
+@@ -1677,6 +1677,7 @@
+ " Shell scripts (sh, ksh, bash, bash2, csh); Allow .profile_foo etc.
+ " Gentoo ebuilds are actually bash scripts
+ au BufNewFile,BufRead .bashrc*,bashrc,bash.bashrc,.bash_profile*,.bash_logout*,*.bash,*.ebuild call SetFileTypeSH("bash")
++au BufNewFile,BufRead */etc/bash*completion*/* call SetFileTypeSH("bash")
+ au BufNewFile,BufRead .kshrc*,*.ksh call SetFileTypeSH("ksh")
+ au BufNewFile,BufRead /etc/profile,.profile*,*.sh,*.env call SetFileTypeSH(getline(1))
+
diff --git a/editor/vi/vim/files/pisilinux/grub_conf.patch b/editor/vi/vim/files/pisilinux/grub_conf.patch
new file mode 100644
index 0000000000..ed5c863715
--- /dev/null
+++ b/editor/vi/vim/files/pisilinux/grub_conf.patch
@@ -0,0 +1,12 @@
+diff -Nur vim72-old/runtime/syntax/grub.vim vim72/runtime/syntax/grub.vim
+--- vim72-old/runtime/syntax/grub.vim 2008-10-18 01:14:23.000000000 +0300
++++ vim72/runtime/syntax/grub.vim 2008-10-18 01:18:04.000000000 +0300
+@@ -27,7 +27,7 @@
+
+ syn cluster grubCommands contains=grubCommand,grubTitleCommand
+
+-syn keyword grubCommand contained default fallback hiddenmenu timeout
++syn keyword grubCommand contained default fallback hiddenmenu timeout splashimage background gfxmenu
+
+ syn keyword grubTitleCommand contained title nextgroup=grubTitle skipwhite
+
diff --git a/editor/vi/vim/files/pisilinux/pspec.vim b/editor/vi/vim/files/pisilinux/pspec.vim
new file mode 100644
index 0000000000..361e07f9cd
--- /dev/null
+++ b/editor/vi/vim/files/pisilinux/pspec.vim
@@ -0,0 +1,75 @@
+if &compatible || v:version < 603
+ finish
+endif
+
+fun! MakeNewPSPEC()
+ set nopaste
+
+ 0 put = ''
+ put = ''
+ put = ''
+ put = ' '
+ put = ' '
+ put = ' http://'
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' GPLv2'
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' http://'
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ''
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' /etc'
+ put = ' /usr/bin'
+ put = ' /usr/include'
+ put = ' /usr/lib'
+ put = ' /usr/share/locale'
+ put = ' /usr/share/man'
+ put = ' /usr/share/doc'
+ put = ' /usr/share'
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ''
+ put = ' '
+ put = ' '
+ put = ' YYYY-MM-DD'
+ put = ' '
+ put = ' First release.'
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ''
+ 14
+endfun
+
+com! -nargs=0 NewPSPEC call MakeNewPSPEC()
+
+augroup NewPSPEC
+ au!
+ autocmd BufNewFile pspec.xml call MakeNewPSPEC()
+augroup END
+
+" vim: set et foldmethod=marker : "
diff --git a/editor/vi/vim/files/pisilinux/translations.vim b/editor/vi/vim/files/pisilinux/translations.vim
new file mode 100644
index 0000000000..eecfe6725a
--- /dev/null
+++ b/editor/vi/vim/files/pisilinux/translations.vim
@@ -0,0 +1,32 @@
+" Vim plugin
+" Purpose: Intelligently create content for PISI's translations.xml files
+" Author: İnanç Yıldırgan
+" Copyright: Copyright (c) 2008 İnanç Yıldırgan
+" Licence: You may redistribute this under the terms of the GNU GPL v2..
+
+if &compatible || v:version < 603
+ finish
+endif
+
+fun! MakeNewTranslations()
+ set nopaste
+
+ 0 put = ''
+ put = ''
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ' '
+ put = ''
+ 14
+endfun
+
+com! -nargs=0 MakeNewTranslations call MakeNewTranslations()
+
+augroup MakeNewTranslations
+ au!
+ autocmd BufNewFile translations.xml call MakeNewTranslations()
+augroup END
+
+" vim: set et foldmethod=marker : "
diff --git a/editor/vi/vim/files/pisilinux/xorg_conf.patch b/editor/vi/vim/files/pisilinux/xorg_conf.patch
new file mode 100644
index 0000000000..b6a6a233da
--- /dev/null
+++ b/editor/vi/vim/files/pisilinux/xorg_conf.patch
@@ -0,0 +1,19 @@
+diff -Nur vim72-old/runtime/syntax/xf86conf.vim vim72/runtime/syntax/xf86conf.vim
+--- vim72-old/runtime/syntax/xf86conf.vim 2008-10-18 01:14:23.000000000 +0300
++++ vim72/runtime/syntax/xf86conf.vim 2008-10-18 01:16:12.000000000 +0300
+@@ -68,6 +68,7 @@
+ syn region xf86confSectionMonitor matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Monitor\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionMode,xf86confModeLine,xf86confComment,xf86confOption,xf86confKeyword
+ syn region xf86confSectionModes matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Modes\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionMode,xf86confModeLine,xf86confComment
+ syn region xf86confSectionScreen matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Screen\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confSubsectionDisplay,xf86confComment,xf86confOption,xf86confKeyword
++ syn region xf86confSectionExtensions matchgroup=xf86confSectionDelim start="^\s*Section\s\+\"Extensions\"" end="^\s*EndSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOption,xf86confKeyword
+ syn region xf86confSubSectionAny matchgroup=xf86confSectionDelim start="^\s*SubSection\s\+\"[^\"]\+\"" end="^\s*EndSubSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+ syn region xf86confSubSectionMode matchgroup=xf86confSectionDelim start="^\s*Mode\s\+\"[^\"]\+\"" end="^\s*EndMode\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confKeyword,@xf86confSectionErrors
+ syn region xf86confSubSectionDisplay matchgroup=xf86confSectionDelim start="^\s*SubSection\s\+\"Display\"" end="^\s*EndSubSection\>" skip="#.*$\|\"[^\"]*\"" contains=xf86confComment,xf86confOption,xf86confKeyword,@xf86confSectionErrors
+@@ -174,6 +175,7 @@
+ endif
+ syn sync match xf86confSyncSectionMonitor groupthere xf86confSectionMonitor "^\s*Section\s\+\"Monitor\""
+ syn sync match xf86confSyncSectionScreen groupthere xf86confSectionScreen "^\s*Section\s\+\"Screen\""
++syn sync match xf86confSyncSectionExtensions groupthere xf86confSectionExtensions "^\s*Section\s\+\"Extensions\""
+ syn sync match xf86confSyncEndSection groupthere NONE "^\s*End_*Section\s*$"
+
+ " Define the default highlighting
diff --git a/editor/vi/vim/files/plugins/kde-devel-vim.vim b/editor/vi/vim/files/plugins/kde-devel-vim.vim
new file mode 100644
index 0000000000..b988f21227
--- /dev/null
+++ b/editor/vi/vim/files/plugins/kde-devel-vim.vim
@@ -0,0 +1,428 @@
+" To use this file, add this line to your ~/.vimrc:, w/o the dquote
+" source /path/to/kde/sources/kdesdk/scripts/kde-devel-vim.vim
+"
+" For CreateChangeLogEntry() : If you don't want to re-enter your
+" Name/Email in each vim session then make sure to have the viminfo
+" option enabled in your ~/.vimrc, with the '!' flag, enabling persistent
+" storage of global variables. Something along the line of
+" set viminfo=%,!,'50,\"100,:100,n~/.viminfo
+" should do the trick.
+
+" Don't include these in filename completions
+set suffixes+=.lo,.o,.moc,.la,.closure,.loT
+
+" Search for headers here
+set path=.,/usr/include,/usr/local/include,
+if $QTDIR != ''
+ let &path = &path . $QTDIR . '/include/,'
+endif
+if $KDEDIR != ''
+ let &path = &path . $KDEDIR . '/include/,'
+ let &path = &path . $KDEDIR . '/include/arts/,'
+endif
+if $KDEDIRS != ''
+ let &path = &path . substitute( $KDEDIRS, '\(:\|$\)', '/include,', 'g' )
+ let &path = &path . substitute( $KDEDIRS, '\(:\|$\)', '/include/arts,', 'g' )
+endif
+set path+=,
+
+" Use makeobj to build
+set mp=makeobj
+
+" If TagList is Loaded then get a funny statusline
+" Only works if kde-devel-vim.vim is loaded after taglist.
+" Droping this script in ~/.vim/plugin works fine
+if exists('loaded_taglist')
+ let Tlist_Process_File_Always=1
+ set statusline=%<%f:[\ %{Tlist_Get_Tag_Prototype_By_Line()}\ ]\ %h%m%r%=%-14.(%l,%c%V%)\ %P
+endif
+
+" Insert tab character in whitespace-only lines, complete otherwise
+inoremap =SmartTab()
+
+if exists("EnableSmartParens")
+" Insert a space after ( or [ and before ] or ) unless preceded by a matching
+" paren/bracket or space or inside a string or comment. Comments are only
+" recognized as such if they start on the current line :-(
+inoremap ( =SmartParens( '(' )
+inoremap [ =SmartParens( '[' )
+inoremap ] =SmartParens( ']', '[' )
+inoremap ) =SmartParens( ')', '(' )
+endif
+
+" Insert an #include statement for the current/last symbol
+inoremap :call AddHeader()
+
+" Insert a forward declaration for the current/last symbol
+" FIXME: not implemented yet
+" inoremap :call AddForward()
+
+" Switch between header and implementation files on ,h
+nmap ,h :call SwitchHeaderImpl()
+
+" Comment selected lines on ,c in visual mode
+vmap ,c :s,^,//X ,:noh
+" Uncomment selected lines on ,u in visual mode
+vmap ,u :s,^//X ,,
+
+" Insert an include guard based on the file name on ,i
+nmap ,i :call IncludeGuard()o
+
+" Insert simple debug statements into each method
+nmap ,d :call InsertMethodTracer()
+
+" Expand #i to #include <.h> or #include ".h". The latter is chosen
+" if the character typed after #i is a dquote
+" If the character is > #include <> is inserted (standard C++ headers w/o .h)
+iab #i =SmartInclude()
+
+" Insert a stripped down CVS diff
+iab DIFF :call RunDiff()
+
+" mark 'misplaced' tab characters
+set listchars=tab:·\ ,trail:·
+set list
+
+set incsearch
+
+function! SmartTab()
+ let col = col('.') - 1
+ if !col || getline('.')[col-1] !~ '\k'
+ return "\"
+ else
+ return "\"
+ endif
+endfunction
+
+function! SmartParens( char, ... )
+ if ! ( &syntax =~ '^\(c\|cpp\|java\)$' )
+ return a:char
+ endif
+ let s = strpart( getline( '.' ), 0, col( '.' ) - 1 )
+ if s =~ '//'
+ return a:char
+ endif
+ let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' )
+ let s = substitute( s, "'[^']*'", '', 'g' )
+ let s = substitute( s, '"\(\\"\|[^"]\)*"', '', 'g' )
+ if s =~ "\\([\"']\\|/\\*\\)"
+ return a:char
+ endif
+ if a:0 > 0
+ if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == a:1 . ' '
+ return "\" . a:char
+ endif
+ if strpart( getline( '.' ), col( '.' ) - 2, 1 ) == ' '
+ return a:char
+ endif
+ return ' ' . a:char
+ endif
+ if a:char == '('
+ if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == 'if' ||
+ \strpart( getline( '.' ), col( '.' ) - 4, 3 ) == 'for' ||
+ \strpart( getline( '.' ), col( '.' ) - 6, 5 ) == 'while' ||
+ \strpart( getline( '.' ), col( '.' ) - 7, 6 ) == 'switch'
+ return ' ( '
+ endif
+ endif
+ return a:char . ' '
+endfunction
+
+function! SwitchHeaderImpl()
+ let headers = '\.\([hH]\|hpp\|hxx\)$'
+ let impl = '\.\([cC]\|cpp\|cc\|cxx\)$'
+ let fn = expand( '%' )
+ if fn =~ headers
+ let list = glob( substitute( fn, headers, '.*', '' ) )
+ elseif fn =~ impl
+ let list = glob( substitute( fn, impl, '.*', '' ) )
+ endif
+ while strlen( list ) > 0
+ let file = substitute( list, "\n.*", '', '' )
+ let list = substitute( list, "[^\n]*", '', '' )
+ let list = substitute( list, "^\n", '', '' )
+ if ( fn =~ headers && file =~ impl ) || ( fn =~ impl && file =~ headers )
+ execute( "edit " . file )
+ return
+ endif
+ endwhile
+ echohl ErrorMsg
+ echo "File switch failed!"
+ echohl None
+endfunction
+
+function! IncludeGuard()
+ let guard = toupper( substitute( expand( '%' ), '\([^.]*\)\.h', '\1_h', '' ) )
+ call append( '^', '#define ' . guard )
+ +
+ call append( '^', '#ifndef ' . guard )
+ call append( '$', '#endif // ' . guard )
+ +
+endfunction
+
+function! SmartInclude()
+ let next = nr2char( getchar( 0 ) )
+ if next == '"'
+ return "#include \".h\"\\\"
+ endif
+ if next == '>'
+ return "#include <>\"
+ endif
+ return "#include <.h>\\\"
+endfunction
+
+function! MapIdentHeader( ident )
+ " Qt stuff
+ if a:ident =~ 'Q.*Layout'
+ return ''
+ elseif a:ident == 'QListViewItem' ||
+ \a:ident == 'QCheckListItem' ||
+ \a:ident == 'QListViewItemIterator'
+ return ''
+ elseif a:ident == 'QIconViewItem' ||
+ \a:ident == 'QIconDragItem' ||
+ \a:ident == 'QIconDrag'
+ return ''
+ elseif a:ident =~ 'Q.*Drag' ||
+ \a:ident == 'QDragManager'
+ return ''
+ elseif a:ident == 'QMimeSource' ||
+ \a:ident == 'QMimeSourceFactory' ||
+ \a:ident == 'QWindowsMime'
+ return ''
+ elseif a:ident == 'QPtrListIterator'
+ return ''
+ elseif a:ident =~ 'Q.*Event'
+ return ''
+ elseif a:ident == 'QTime' ||
+ \a:ident == 'QDate'
+ return ''
+ elseif a:ident == 'QTimeEdit' ||
+ \a:ident == 'QDateTimeEditBase' ||
+ \a:ident == 'QDateEdit'
+ return ''
+ elseif a:ident == 'QByteArray'
+ return ''
+ elseif a:ident == 'QWidgetListIt'
+ return ''
+ elseif a:ident == 'QTab'
+ return ''
+ elseif a:ident == 'QColorGroup'
+ return ''
+ elseif a:ident == 'QActionGroup'
+ return ''
+ elseif a:ident =~ 'Q.*Validator'
+ return ''
+ elseif a:ident =~ 'QListBox.*'
+ return ''
+ elseif a:ident == 'QChar' ||
+ \a:ident == 'QCharRef' ||
+ \a:ident == 'QConstString'
+ return ''
+ elseif a:ident =~ 'QCanvas.*'
+ return ''
+ elseif a:ident =~ 'QGL.*'
+ return ''
+ elseif a:ident == 'QTableSelection' ||
+ \a:ident == 'QTableItem' ||
+ \a:ident == 'QComboTableItem' ||
+ \a:ident == 'QCheckTableItem'
+ return ''
+ elseif a:ident == 'qApp'
+ return ''
+
+ " KDE stuff
+ elseif a:ident == 'K\(Double\|Int\)\(NumInput\|SpinBox\)'
+ return ''
+ elseif a:ident == 'KConfigGroup'
+ return ''
+ elseif a:ident == 'KListViewItem'
+ return ''
+ elseif a:ident =~ 'kd\(Debug\|Warning\|Error\|Fatal\|Backtrace\)'
+ return ''
+ elseif a:ident == 'kapp'
+ return ''
+ elseif a:ident == 'i18n' ||
+ \a:ident == 'I18N_NOOP'
+ return ''
+ elseif a:ident == 'locate' ||
+ \a:ident == 'locateLocal'
+ return ''
+
+ " aRts stuff
+ elseif a:ident =~ '\arts_\(debug\|info\|warning\|fatal\)'
+ return ''
+
+ " Standard Library stuff
+ elseif a:ident =~ '\(std::\)\?\(cout\|cerr\|endl\)'
+ return ''
+ elseif a:ident =~ '\(std::\)\?is\(alnum\|alpha\|ascii\|blank\|graph\|lower\|print\|punct\|space\|upper\|xdigit\)'
+ return ''
+ endif
+
+ let header = tolower( substitute( a:ident, '::', '/', 'g' ) ) . '.h'
+ let check = header
+ while 1
+ if filereadable( check )
+ return '"' . check . '"'
+ endif
+ let slash = match( check, '/' )
+ if slash == -1
+ return '<' . header . '>'
+ endif
+ let check = strpart( check, slash + 1 )
+ endwhile
+endfunction
+
+" This is a rather dirty hack, but seems to work somehow :-) (malte)
+function! AddHeader()
+ let s = getline( '.' )
+ let i = col( '.' ) - 1
+ while i > 0 && strpart( s, i, 1 ) !~ '[A-Za-z0-9_:]'
+ let i = i - 1
+ endwhile
+ while i > 0 && strpart( s, i, 1 ) =~ '[A-Za-z0-9_:]'
+ let i = i - 1
+ endwhile
+ let start = match( s, '[A-Za-z0-9_]\+\(::[A-Za-z0-9_]\+\)*', i )
+ let end = matchend( s, '[A-Za-z0-9_]\+\(::[A-Za-z0-9_]\+\)*', i )
+ if end > col( '.' )
+ let end = matchend( s, '[A-Za-z0-9_]\+', i )
+ endif
+ let ident = strpart( s, start, end - start )
+ let include = '#include ' . MapIdentHeader( ident )
+
+ let line = 1
+ let incomment = 0
+ let appendpos = 0
+ let codestart = 0
+ while line <= line( '$' )
+ let s = getline( line )
+ if incomment == 1
+ let end = matchend( s, '\*/' )
+ if end == -1
+ let line = line + 1
+ continue
+ else
+ let s = strpart( s, end )
+ let incomment = 0
+ endif
+ endif
+ let s = substitute( s, '//.*', '', '' )
+ let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' )
+ if s =~ '/\*'
+ let incomment = 1
+ elseif s =~ '^' . include
+ break
+ elseif s =~ '^#include' && s !~ '\.moc"'
+ let appendpos = line
+ elseif codestart == 0 && s !~ '^$'
+ let codestart = line
+ endif
+ let line = line + 1
+ endwhile
+ if line == line( '$' ) + 1
+ if appendpos == 0
+ call append( codestart - 1, include )
+ call append( codestart, '' )
+ else
+ call append( appendpos, include )
+ endif
+ endif
+endfunction
+
+function! RunDiff()
+ echo 'Diffing....'
+ read! cvs diff -bB -I \\\#include | egrep -v '(^Index:|^=+$|^RCS file:|^retrieving revision|^diff -u|^[+-]{3})'
+endfunction
+
+function! CreateChangeLogEntry()
+ let currentBuffer = expand( "%" )
+
+ if exists( "g:EMAIL" )
+ let mail = g:EMAIL
+ elseif exists( "$EMAIL" )
+ let mail = $EMAIL
+ else
+ let mail = inputdialog( "Enter Name/Email for Changelog entry: " )
+ if mail == ""
+ echo "Aborted ChangeLog edit..."
+ return
+ endif
+ let g:EMAIL = mail
+ endif
+
+ if bufname( "ChangeLog" ) != "" && bufwinnr( bufname( "ChangeLog" ) ) != -1
+ execute bufwinnr( bufname( "ChangeLog" ) ) . " wincmd w"
+ else
+ execute "split ChangeLog"
+ endif
+
+ let lastEntry = getline( nextnonblank( 1 ) )
+ let newEntry = strftime("%Y-%m-%d") . " " . mail
+
+ if lastEntry != newEntry
+ call append( 0, "" )
+ call append( 0, "" )
+ call append( 0, newEntry )
+ endif
+
+ " like emacs, prepend the current buffer name to the entry. but unlike
+ " emacs I have no idea how to figure out the current function name :(
+ " (Simon)
+ if currentBuffer != ""
+ let newLine = "\t* " . currentBuffer . ": "
+ else
+ let newLine = "\t* "
+ endif
+
+ call append( 2, newLine )
+
+ execute "normal 3G$"
+endfunction
+
+function! AddQtSyntax()
+ if expand( "" ) == "cpp"
+ syn keyword qtKeywords signals slots emit foreach
+ syn keyword qtMacros Q_OBJECT Q_WIDGET Q_PROPERTY Q_ENUMS Q_OVERRIDE Q_CLASSINFO Q_SETS SIGNAL SLOT
+ syn keyword qtCast qt_cast qobject_cast qvariant_cast qstyleoption_cast
+ syn keyword qtTypedef uchar uint ushort ulong Q_INT8 Q_UINT8 Q_INT16 Q_UINT16 Q_INT32 Q_UINT32 Q_LONG Q_ULONG Q_INT64 Q_UINT64 Q_LLONG Q_ULLONG pchar puchar pcchar qint8 quint8 qint16 quint16 qint32 quint32 qint64 quint64 qlonglong qulonglong
+ syn keyword kdeKeywords k_dcop k_dcop_signals
+ syn keyword kdeMacros K_DCOP ASYNC
+ syn keyword cRepeat foreach
+ syn keyword cRepeat forever
+
+ hi def link qtKeywords Statement
+ hi def link qtMacros Type
+ hi def link qtCast Statement
+ hi def link qtTypedef Type
+ hi def link kdeKeywords Statement
+ hi def link kdeMacros Type
+ endif
+endfunction
+
+function! InsertMethodTracer()
+ :normal [[kf(yBjokdDebug() << ""()" << endl;
+endfunction
+
+function! UpdateMocFiles()
+ if &syntax == "cpp"
+ let i = 1
+ while i < 80
+ let s = getline( i )
+ if s =~ '^#include ".*\.moc"'
+ let s = substitute( s, '.*"\(.*\)\.moc"', '\1.h', '' )
+ if stridx( &complete, s ) == -1
+ let &complete = &complete . ',k' . s
+ endif
+ break
+ endif
+ let i = i + 1
+ endwhile
+ endif
+endfunction
+
+autocmd Syntax * call AddQtSyntax()
+autocmd CursorHold * call UpdateMocFiles()
+
+" vim: sw=4 sts=4 et
diff --git a/editor/vi/vim/files/plugins/newpythonfile.vim b/editor/vi/vim/files/plugins/newpythonfile.vim
new file mode 100644
index 0000000000..4a5edaae48
--- /dev/null
+++ b/editor/vi/vim/files/plugins/newpythonfile.vim
@@ -0,0 +1,28 @@
+"
+" Just a little plugin to automatically set utf-8 for new Python files
+"
+
+if &compatible || v:version < 603
+ finish
+endif
+
+fun! MakeNewPythonFile()
+ " actions.py has another handler
+ if expand("") == 'actions.py'
+ return
+ endif
+ set nopaste
+ 0 put = '#!/usr/bin/python'
+ put = '# -*- coding: utf-8 -*-'
+ put = ''
+ 5
+endfun
+
+com! -nargs=0 NewPythonFile call MakeNewPythonFile()
+
+augroup NewPythonFile
+ au!
+ autocmd BufNewFile *.py call MakeNewPythonFile()
+augroup END
+
+" vim: set et foldmethod=marker : "
diff --git a/editor/vi/vim/files/plugins/redstring.vim b/editor/vi/vim/files/plugins/redstring.vim
new file mode 100644
index 0000000000..5b751828e5
--- /dev/null
+++ b/editor/vi/vim/files/plugins/redstring.vim
@@ -0,0 +1,26 @@
+" Vim color file
+" Maintainer: Connor Berry
+" Last Change: 2006/05/25
+" Version: 1.0
+
+set background=dark
+highlight clear
+if exists("syntax on")
+ syntax reset
+endif
+
+let g:colors_name = "redstring"
+
+highlight Normal term=none ctermfg=grey cterm=none ctermbg=black guifg=white gui=none guibg=black
+highlight Comment term=none ctermfg=DarkGrey guifg=DarkGrey
+highlight Constant term=none ctermfg=red cterm=none guifg=red gui=none
+highlight Special term=none ctermfg=red cterm=bold guifg=red gui=bold
+highlight Identifier term=none ctermfg=lightgreen cterm=none guifg=lightgreen gui=none
+highlight Statement term=bold ctermfg=cyan cterm=bold guifg=cyan gui=bold
+highlight Operator term=bold ctermfg=cyan cterm=bold guifg=cyan gui=bold
+highlight PreProc term=bold ctermfg=lightgreen cterm=none guifg=green gui=none
+highlight Type term=bold ctermfg=lightgreen cterm=none guifg=lightgreen gui=none
+highlight String term=none ctermfg=red cterm=none guifg=red gui=none
+highlight Number term=none ctermfg=red cterm=none guifg=red gui=none
+
+" vim:ts=2:sw=2:et
diff --git a/editor/vi/vim/files/plugins/taglist.vim b/editor/vi/vim/files/plugins/taglist.vim
new file mode 100644
index 0000000000..59901f64fa
--- /dev/null
+++ b/editor/vi/vim/files/plugins/taglist.vim
@@ -0,0 +1,4546 @@
+" File: taglist.vim
+" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
+" Version: 4.5
+" Last Modified: September 21, 2007
+" Copyright: Copyright (C) 2002-2007 Yegappan Lakshmanan
+" Permission is hereby granted to use and distribute this code,
+" with or without modifications, provided that this copyright
+" notice is copied with it. Like anything else that's free,
+" taglist.vim is provided *as is* and comes with no warranty of any
+" kind, either expressed or implied. In no event will the copyright
+" holder be liable for any damamges resulting from the use of this
+" software.
+"
+" The "Tag List" plugin is a source code browser plugin for Vim and provides
+" an overview of the structure of the programming language files and allows
+" you to efficiently browse through source code files for different
+" programming languages. You can visit the taglist plugin home page for more
+" information:
+"
+" http://vim-taglist.sourceforge.net
+"
+" You can subscribe to the taglist mailing list to post your questions
+" or suggestions for improvement or to report bugs. Visit the following
+" page for subscribing to the mailing list:
+"
+" http://groups.yahoo.com/group/taglist/
+"
+" For more information about using this plugin, after installing the
+" taglist plugin, use the ":help taglist" command.
+"
+" Installation
+" ------------
+" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim
+" or the $HOME/vimfiles or the $VIM/vimfiles directory. This should
+" unzip the following two files (the directory structure should be
+" preserved):
+"
+" plugin/taglist.vim - main taglist plugin file
+" doc/taglist.txt - documentation (help) file
+"
+" Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath'
+" Vim help pages for more details about installing Vim plugins.
+" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or
+" $VIM/vimfiles/doc directory, start Vim and run the ":helptags ."
+" command to process the taglist help file.
+" 3. If the exuberant ctags utility is not present in your PATH, then set the
+" Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags
+" utility (not to the directory) in the .vimrc file.
+" 4. If you are running a terminal/console version of Vim and the
+" terminal doesn't support changing the window width then set the
+" 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file.
+" 5. Restart Vim.
+" 6. You can now use the ":TlistToggle" command to open/close the taglist
+" window. You can use the ":help taglist" command to get more
+" information about using the taglist plugin.
+"
+" ****************** Do not modify after this line ************************
+
+" Line continuation used here
+let s:cpo_save = &cpo
+set cpo&vim
+
+if !exists('loaded_taglist')
+ " First time loading the taglist plugin
+ "
+ " To speed up the loading of Vim, the taglist plugin uses autoload
+ " mechanism to load the taglist functions.
+ " Only define the configuration variables, user commands and some
+ " auto-commands and finish sourcing the file
+
+ " The taglist plugin requires the built-in Vim system() function. If this
+ " function is not available, then don't load the plugin.
+ if !exists('*system')
+ echomsg 'Taglist: Vim system() built-in function is not available. ' .
+ \ 'Plugin is not loaded.'
+ let loaded_taglist = 'no'
+ let &cpo = s:cpo_save
+ finish
+ endif
+
+ " Location of the exuberant ctags tool
+ if !exists('Tlist_Ctags_Cmd')
+ if executable('exuberant-ctags')
+ " On Debian Linux, exuberant ctags is installed
+ " as exuberant-ctags
+ let Tlist_Ctags_Cmd = 'exuberant-ctags'
+ elseif executable('exctags')
+ " On Free-BSD, exuberant ctags is installed as exctags
+ let Tlist_Ctags_Cmd = 'exctags'
+ elseif executable('ctags')
+ let Tlist_Ctags_Cmd = 'ctags'
+ elseif executable('ctags.exe')
+ let Tlist_Ctags_Cmd = 'ctags.exe'
+ elseif executable('tags')
+ let Tlist_Ctags_Cmd = 'tags'
+ else
+ echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' .
+ \ 'not found in PATH. Plugin is not loaded.'
+ " Skip loading the plugin
+ let loaded_taglist = 'no'
+ let &cpo = s:cpo_save
+ finish
+ endif
+ endif
+
+
+ " Automatically open the taglist window on Vim startup
+ if !exists('Tlist_Auto_Open')
+ let Tlist_Auto_Open = 0
+ endif
+
+ " When the taglist window is toggle opened, move the cursor to the
+ " taglist window
+ if !exists('Tlist_GainFocus_On_ToggleOpen')
+ let Tlist_GainFocus_On_ToggleOpen = 0
+ endif
+
+ " Process files even when the taglist window is not open
+ if !exists('Tlist_Process_File_Always')
+ let Tlist_Process_File_Always = 0
+ endif
+
+ if !exists('Tlist_Show_Menu')
+ let Tlist_Show_Menu = 0
+ endif
+
+ " Tag listing sort type - 'name' or 'order'
+ if !exists('Tlist_Sort_Type')
+ let Tlist_Sort_Type = 'order'
+ endif
+
+ " Tag listing window split (horizontal/vertical) control
+ if !exists('Tlist_Use_Horiz_Window')
+ let Tlist_Use_Horiz_Window = 0
+ endif
+
+ " Open the vertically split taglist window on the left or on the right
+ " side. This setting is relevant only if Tlist_Use_Horiz_Window is set to
+ " zero (i.e. only for vertically split windows)
+ if !exists('Tlist_Use_Right_Window')
+ let Tlist_Use_Right_Window = 0
+ endif
+
+ " Increase Vim window width to display vertically split taglist window.
+ " For MS-Windows version of Vim running in a MS-DOS window, this must be
+ " set to 0 otherwise the system may hang due to a Vim limitation.
+ if !exists('Tlist_Inc_Winwidth')
+ if (has('win16') || has('win95')) && !has('gui_running')
+ let Tlist_Inc_Winwidth = 0
+ else
+ let Tlist_Inc_Winwidth = 1
+ endif
+ endif
+
+ " Vertically split taglist window width setting
+ if !exists('Tlist_WinWidth')
+ let Tlist_WinWidth = 30
+ endif
+
+ " Horizontally split taglist window height setting
+ if !exists('Tlist_WinHeight')
+ let Tlist_WinHeight = 10
+ endif
+
+ " Display tag prototypes or tag names in the taglist window
+ if !exists('Tlist_Display_Prototype')
+ let Tlist_Display_Prototype = 0
+ endif
+
+ " Display tag scopes in the taglist window
+ if !exists('Tlist_Display_Tag_Scope')
+ let Tlist_Display_Tag_Scope = 1
+ endif
+
+ " Use single left mouse click to jump to a tag. By default this is disabled.
+ " Only double click using the mouse will be processed.
+ if !exists('Tlist_Use_SingleClick')
+ let Tlist_Use_SingleClick = 0
+ endif
+
+ " Control whether additional help is displayed as part of the taglist or
+ " not. Also, controls whether empty lines are used to separate the tag
+ " tree.
+ if !exists('Tlist_Compact_Format')
+ let Tlist_Compact_Format = 0
+ endif
+
+ " Exit Vim if only the taglist window is currently open. By default, this is
+ " set to zero.
+ if !exists('Tlist_Exit_OnlyWindow')
+ let Tlist_Exit_OnlyWindow = 0
+ endif
+
+ " Automatically close the folds for the non-active files in the taglist
+ " window
+ if !exists('Tlist_File_Fold_Auto_Close')
+ let Tlist_File_Fold_Auto_Close = 0
+ endif
+
+ " Close the taglist window when a tag is selected
+ if !exists('Tlist_Close_On_Select')
+ let Tlist_Close_On_Select = 0
+ endif
+
+ " Automatically update the taglist window to display tags for newly
+ " edited files
+ if !exists('Tlist_Auto_Update')
+ let Tlist_Auto_Update = 1
+ endif
+
+ " Automatically highlight the current tag
+ if !exists('Tlist_Auto_Highlight_Tag')
+ let Tlist_Auto_Highlight_Tag = 1
+ endif
+
+ " Automatically highlight the current tag on entering a buffer
+ if !exists('Tlist_Highlight_Tag_On_BufEnter')
+ let Tlist_Highlight_Tag_On_BufEnter = 1
+ endif
+
+ " Enable fold column to display the folding for the tag tree
+ if !exists('Tlist_Enable_Fold_Column')
+ let Tlist_Enable_Fold_Column = 1
+ endif
+
+ " Display the tags for only one file in the taglist window
+ if !exists('Tlist_Show_One_File')
+ let Tlist_Show_One_File = 0
+ endif
+
+ if !exists('Tlist_Max_Submenu_Items')
+ let Tlist_Max_Submenu_Items = 20
+ endif
+
+ if !exists('Tlist_Max_Tag_Length')
+ let Tlist_Max_Tag_Length = 10
+ endif
+
+ " Do not change the name of the taglist title variable. The winmanager
+ " plugin relies on this name to determine the title for the taglist
+ " plugin.
+ let TagList_title = "__Tag_List__"
+
+ " Taglist debug messages
+ let s:tlist_msg = ''
+
+ " Define the taglist autocommand to automatically open the taglist window
+ " on Vim startup
+ if g:Tlist_Auto_Open
+ autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open()
+ endif
+
+ " Refresh the taglist
+ if g:Tlist_Process_File_Always
+ autocmd BufEnter * call s:Tlist_Refresh()
+ endif
+
+ if g:Tlist_Show_Menu
+ autocmd GUIEnter * call s:Tlist_Menu_Init()
+ endif
+
+ " When the taglist buffer is created when loading a Vim session file,
+ " the taglist buffer needs to be initialized. The BufFilePost event
+ " is used to handle this case.
+ autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load()
+
+ " Define the user commands to manage the taglist window
+ command! -nargs=0 -bar TlistToggle call s:Tlist_Window_Toggle()
+ command! -nargs=0 -bar TlistOpen call s:Tlist_Window_Open()
+ " For backwards compatiblity define the Tlist command
+ command! -nargs=0 -bar Tlist TlistToggle
+ command! -nargs=+ -complete=file TlistAddFiles
+ \ call s:Tlist_Add_Files()
+ command! -nargs=+ -complete=dir TlistAddFilesRecursive
+ \ call s:Tlist_Add_Files_Recursive()
+ command! -nargs=0 -bar TlistClose call s:Tlist_Window_Close()
+ command! -nargs=0 -bar TlistUpdate call s:Tlist_Update_Current_File()
+ command! -nargs=0 -bar TlistHighlightTag call s:Tlist_Window_Highlight_Tag(
+ \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1)
+ " For backwards compatiblity define the TlistSync command
+ command! -nargs=0 -bar TlistSync TlistHighlightTag
+ command! -nargs=* -complete=buffer TlistShowPrototype
+ \ echo Tlist_Get_Tag_Prototype_By_Line()
+ command! -nargs=* -complete=buffer TlistShowTag
+ \ echo Tlist_Get_Tagname_By_Line()
+ command! -nargs=* -complete=file TlistSessionLoad
+ \ call s:Tlist_Session_Load()
+ command! -nargs=* -complete=file TlistSessionSave
+ \ call s:Tlist_Session_Save()
+ command! -bar TlistLock let Tlist_Auto_Update=0
+ command! -bar TlistUnlock let Tlist_Auto_Update=1
+
+ " Commands for enabling/disabling debug and to display debug messages
+ command! -nargs=? -complete=file -bar TlistDebug
+ \ call s:Tlist_Debug_Enable()
+ command! -nargs=0 -bar TlistUndebug call s:Tlist_Debug_Disable()
+ command! -nargs=0 -bar TlistMessages call s:Tlist_Debug_Show()
+
+ " Define autocommands to autoload the taglist plugin when needed.
+
+ " Trick to get the current script ID
+ map xx xx
+ let s:tlist_sid = substitute(maparg('xx'), '\(\d\+_\)xx$',
+ \ '\1', '')
+ unmap xx
+
+ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_* source ' .
+ \ escape(expand(''), ' ')
+ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Window_* source ' .
+ \ escape(expand(''), ' ')
+ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Menu_* source ' .
+ \ escape(expand(''), ' ')
+ exe 'autocmd FuncUndefined Tlist_* source ' .
+ \ escape(expand(''), ' ')
+ exe 'autocmd FuncUndefined TagList_* source ' .
+ \ escape(expand(''), ' ')
+
+ let loaded_taglist = 'fast_load_done'
+
+ if g:Tlist_Show_Menu && has('gui_running')
+ call s:Tlist_Menu_Init()
+ endif
+
+ " restore 'cpo'
+ let &cpo = s:cpo_save
+ finish
+endif
+
+if !exists('s:tlist_sid')
+ " Two or more versions of taglist plugin are installed. Don't
+ " load this version of the plugin.
+ finish
+endif
+
+unlet! s:tlist_sid
+
+if loaded_taglist != 'fast_load_done'
+ " restore 'cpo'
+ let &cpo = s:cpo_save
+ finish
+endif
+
+" Taglist plugin functionality is available
+let loaded_taglist = 'available'
+
+"------------------- end of user configurable options --------------------
+
+" Default language specific settings for supported file types and tag types
+"
+" Variable name format:
+"
+" s:tlist_def_{vim_ftype}_settings
+"
+" vim_ftype - Filetype detected by Vim
+"
+" Value format:
+"
+" ;:;:;...
+"
+" ctags_ftype - File type supported by exuberant ctags
+" flag - Flag supported by exuberant ctags to generate a tag type
+" name - Name of the tag type used in the taglist window to display the
+" tags of this type
+"
+
+" assembly language
+let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type'
+
+" aspperl language
+let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable'
+
+" aspvbs language
+let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable'
+
+" awk language
+let s:tlist_def_awk_settings = 'awk;f:function'
+
+" beta language
+let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern'
+
+" c language
+let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' .
+ \ 'v:variable;f:function'
+
+" c++ language
+let s:tlist_def_cpp_settings = 'c++;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 = 'c#;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 = 'cobol;d:data;f:file;g:group;p:paragraph;' .
+ \ 'P:program;s:section'
+
+" eiffel language
+let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature'
+
+" erlang language
+let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function'
+
+" expect (same as tcl) language
+let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure'
+
+" fortran language
+let s:tlist_def_fortran_settings = 'fortran;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 = 'html;a:anchor;f:javascript function'
+
+" java language
+let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' .
+ \ 'f:field;m:method'
+
+" javascript language
+let s:tlist_def_javascript_settings = 'javascript;f:function'
+
+" lisp language
+let s:tlist_def_lisp_settings = 'lisp;f:function'
+
+" lua language
+let s:tlist_def_lua_settings = 'lua;f:function'
+
+" makefiles
+let s:tlist_def_make_settings = 'make;m:macro'
+
+" pascal language
+let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure'
+
+" perl language
+let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine'
+
+" php language
+let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function'
+
+" python language
+let s:tlist_def_python_settings = 'python;c:class;m:member;f:function'
+
+" rexx language
+let s:tlist_def_rexx_settings = 'rexx;s:subroutine'
+
+" ruby language
+let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' .
+ \ 'm:singleton method'
+
+" scheme language
+let s:tlist_def_scheme_settings = 'scheme;s:set;f:function'
+
+" shell language
+let s:tlist_def_sh_settings = 'sh;f:function'
+
+" C shell language
+let s:tlist_def_csh_settings = 'sh;f:function'
+
+" Z shell language
+let s:tlist_def_zsh_settings = 'sh;f:function'
+
+" slang language
+let s:tlist_def_slang_settings = 'slang;n:namespace;f:function'
+
+" sml language
+let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' .
+ \ 'r:structure;t:type;v:value;f:function'
+
+" sql language
+let s:tlist_def_sql_settings = 'sql;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 = 'tcl;c:class;f:method;m:method;p:procedure'
+
+" vera language
+let s:tlist_def_vera_settings = 'vera;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 = 'verilog;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 = 'vim;a:autocmds;v:variable;f:function'
+
+" yacc language
+let s:tlist_def_yacc_settings = 'yacc;l:label'
+
+"------------------- end of language specific options --------------------
+
+" Vim window size is changed by the taglist plugin or not
+let s:tlist_winsize_chgd = -1
+" Taglist window is maximized or not
+let s:tlist_win_maximized = 0
+" Name of files in the taglist
+let s:tlist_file_names=''
+" Number of files in the taglist
+let s:tlist_file_count = 0
+" Number of filetypes supported by taglist
+let s:tlist_ftype_count = 0
+" Is taglist part of other plugins like winmanager or cream?
+let s:tlist_app_name = "none"
+" Are we displaying brief help text
+let s:tlist_brief_help = 1
+" List of files removed on user request
+let s:tlist_removed_flist = ""
+" Index of current file displayed in the taglist window
+let s:tlist_cur_file_idx = -1
+" Taglist menu is empty or not
+let s:tlist_menu_empty = 1
+
+" An autocommand is used to refresh the taglist window when entering any
+" buffer. We don't want to refresh the taglist window if we are entering the
+" file window from one of the taglist functions. The 'Tlist_Skip_Refresh'
+" variable is used to skip the refresh of the taglist window and is set
+" and cleared appropriately.
+let s:Tlist_Skip_Refresh = 0
+
+" Tlist_Window_Display_Help()
+function! s:Tlist_Window_Display_Help()
+ if s:tlist_app_name == "winmanager"
+ " To handle a bug in the winmanager plugin, add a space at the
+ " last line
+ call setline('$', ' ')
+ endif
+
+ if s:tlist_brief_help
+ " Add the brief help
+ call append(0, '" Press to display help text')
+ else
+ " Add the extensive help
+ call append(0, '" : Jump to tag definition')
+ call append(1, '" o : Jump to tag definition in new window')
+ call append(2, '" p : Preview the tag definition')
+ call append(3, '" : Display tag prototype')
+ call append(4, '" u : Update tag list')
+ call append(5, '" s : Select sort field')
+ call append(6, '" d : Remove file from taglist')
+ call append(7, '" x : Zoom-out/Zoom-in taglist window')
+ call append(8, '" + : Open a fold')
+ call append(9, '" - : Close a fold')
+ call append(10, '" * : Open all folds')
+ call append(11, '" = : Close all folds')
+ call append(12, '" [[ : Move to the start of previous file')
+ call append(13, '" ]] : Move to the start of next file')
+ call append(14, '" q : Close the taglist window')
+ call append(15, '" : Remove help text')
+ endif
+endfunction
+
+" Tlist_Window_Toggle_Help_Text()
+" Toggle taglist plugin help text between the full version and the brief
+" version
+function! s:Tlist_Window_Toggle_Help_Text()
+ if g:Tlist_Compact_Format
+ " In compact display mode, do not display help
+ return
+ endif
+
+ " Include the empty line displayed after the help text
+ let brief_help_size = 1
+ let full_help_size = 16
+
+ setlocal modifiable
+
+ " Set report option to a huge value to prevent informational messages
+ " while deleting the lines
+ let old_report = &report
+ set report=99999
+
+ " Remove the currently highlighted tag. Otherwise, the help text
+ " might be highlighted by mistake
+ match none
+
+ " Toggle between brief and full help text
+ if s:tlist_brief_help
+ let s:tlist_brief_help = 0
+
+ " Remove the previous help
+ exe '1,' . brief_help_size . ' delete _'
+
+ " Adjust the start/end line numbers for the files
+ call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size)
+ else
+ let s:tlist_brief_help = 1
+
+ " Remove the previous help
+ exe '1,' . full_help_size . ' delete _'
+
+ " Adjust the start/end line numbers for the files
+ call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size)
+ endif
+
+ call s:Tlist_Window_Display_Help()
+
+ " Restore the report option
+ let &report = old_report
+
+ setlocal nomodifiable
+endfunction
+
+" Taglist debug support
+let s:tlist_debug = 0
+
+" File for storing the debug messages
+let s:tlist_debug_file = ''
+
+" Tlist_Debug_Enable
+" Enable logging of taglist debug messages.
+function! s:Tlist_Debug_Enable(...)
+ let s:tlist_debug = 1
+
+ " Check whether a valid file name is supplied.
+ if a:1 != ''
+ let s:tlist_debug_file = fnamemodify(a:1, ':p')
+
+ " Empty the log file
+ exe 'redir! > ' . s:tlist_debug_file
+ redir END
+
+ " Check whether the log file is present/created
+ if !filewritable(s:tlist_debug_file)
+ call s:Tlist_Warning_Msg('Taglist: Unable to create log file '
+ \ . s:tlist_debug_file)
+ let s:tlist_debug_file = ''
+ endif
+ endif
+endfunction
+
+" Tlist_Debug_Disable
+" Disable logging of taglist debug messages.
+function! s:Tlist_Debug_Disable(...)
+ let s:tlist_debug = 0
+ let s:tlist_debug_file = ''
+endfunction
+
+" Tlist_Debug_Show
+" Display the taglist debug messages in a new window
+function! s:Tlist_Debug_Show()
+ if s:tlist_msg == ''
+ call s:Tlist_Warning_Msg('Taglist: No debug messages')
+ return
+ endif
+
+ " Open a new window to display the taglist debug messages
+ new taglist_debug.txt
+ " Delete all the lines (if the buffer already exists)
+ silent! %delete _
+ " Add the messages
+ silent! put =s:tlist_msg
+ " Move the cursor to the first line
+ normal! gg
+endfunction
+
+" Tlist_Log_Msg
+" Log the supplied debug message along with the time
+function! s:Tlist_Log_Msg(msg)
+ if s:tlist_debug
+ if s:tlist_debug_file != ''
+ exe 'redir >> ' . s:tlist_debug_file
+ silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n"
+ redir END
+ else
+ " Log the message into a variable
+ " Retain only the last 3000 characters
+ let len = strlen(s:tlist_msg)
+ if len > 3000
+ let s:tlist_msg = strpart(s:tlist_msg, len - 3000)
+ endif
+ let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' .
+ \ a:msg . "\n"
+ endif
+ endif
+endfunction
+
+" Tlist_Warning_Msg()
+" Display a message using WarningMsg highlight group
+function! s:Tlist_Warning_Msg(msg)
+ echohl WarningMsg
+ echomsg a:msg
+ echohl None
+endfunction
+
+" Last returned file index for file name lookup.
+" Used to speed up file lookup
+let s:tlist_file_name_idx_cache = -1
+
+" Tlist_Get_File_Index()
+" Return the index of the specified filename
+function! s:Tlist_Get_File_Index(fname)
+ if s:tlist_file_count == 0 || a:fname == ''
+ return -1
+ endif
+
+ " If the new filename is same as the last accessed filename, then
+ " return that index
+ if s:tlist_file_name_idx_cache != -1 &&
+ \ s:tlist_file_name_idx_cache < s:tlist_file_count
+ if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname
+ " Same as the last accessed file
+ return s:tlist_file_name_idx_cache
+ endif
+ endif
+
+ " First, check whether the filename is present
+ let s_fname = a:fname . "\n"
+ let i = stridx(s:tlist_file_names, s_fname)
+ if i == -1
+ let s:tlist_file_name_idx_cache = -1
+ return -1
+ endif
+
+ " Second, compute the file name index
+ let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g')
+ let s:tlist_file_name_idx_cache = strlen(nl_txt)
+ return s:tlist_file_name_idx_cache
+endfunction
+
+" Last returned file index for line number lookup.
+" Used to speed up file lookup
+let s:tlist_file_lnum_idx_cache = -1
+
+" Tlist_Window_Get_File_Index_By_Linenum()
+" Return the index of the filename present in the specified line number
+" Line number refers to the line number in the taglist window
+function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
+ call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')')
+
+ " First try to see whether the new line number is within the range
+ " of the last returned file
+ if s:tlist_file_lnum_idx_cache != -1 &&
+ \ s:tlist_file_lnum_idx_cache < s:tlist_file_count
+ if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start &&
+ \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end
+ return s:tlist_file_lnum_idx_cache
+ endif
+ endif
+
+ let fidx = -1
+
+ if g:Tlist_Show_One_File
+ " Displaying only one file in the taglist window. Check whether
+ " the line is within the tags displayed for that file
+ if s:tlist_cur_file_idx != -1
+ if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start
+ \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end
+ let fidx = s:tlist_cur_file_idx
+ endif
+
+ endif
+ else
+ " Do a binary search in the taglist
+ let left = 0
+ let right = s:tlist_file_count - 1
+
+ while left < right
+ let mid = (left + right) / 2
+
+ if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end
+ let s:tlist_file_lnum_idx_cache = mid
+ return mid
+ endif
+
+ if a:lnum < s:tlist_{mid}_start
+ let right = mid - 1
+ else
+ let left = mid + 1
+ endif
+ endwhile
+
+ if left >= 0 && left < s:tlist_file_count
+ \ && a:lnum >= s:tlist_{left}_start
+ \ && a:lnum <= s:tlist_{left}_end
+ let fidx = left
+ endif
+ endif
+
+ let s:tlist_file_lnum_idx_cache = fidx
+
+ return fidx
+endfunction
+
+" Tlist_Exe_Cmd_No_Acmds
+" Execute the specified Ex command after disabling autocommands
+function! s:Tlist_Exe_Cmd_No_Acmds(cmd)
+ let old_eventignore = &eventignore
+ set eventignore=all
+ exe a:cmd
+ let &eventignore = old_eventignore
+endfunction
+
+" Tlist_Skip_File()
+" Check whether tag listing is supported for the specified file
+function! s:Tlist_Skip_File(filename, ftype)
+ " Skip buffers with no names and buffers with filetype not set
+ if a:filename == '' || a:ftype == ''
+ return 1
+ 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 1
+ endif
+ endif
+
+ " Skip files which are not readable or files which are not yet stored
+ " to the disk
+ if !filereadable(a:filename)
+ return 1
+ endif
+
+ return 0
+endfunction
+
+" Tlist_User_Removed_File
+" Returns 1 if a file is removed by a user from the taglist
+function! s:Tlist_User_Removed_File(filename)
+ return stridx(s:tlist_removed_flist, a:filename . "\n") != -1
+endfunction
+
+" Tlist_Update_Remove_List
+" Update the list of user removed files from the taglist
+" add == 1, add the file to the removed list
+" add == 0, delete the file from the removed list
+function! s:Tlist_Update_Remove_List(filename, add)
+ if a:add
+ let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n"
+ else
+ let idx = stridx(s:tlist_removed_flist, a:filename . "\n")
+ let text_before = strpart(s:tlist_removed_flist, 0, idx)
+ let rem_text = strpart(s:tlist_removed_flist, idx)
+ let next_idx = stridx(rem_text, "\n")
+ let text_after = strpart(rem_text, next_idx + 1)
+
+ let s:tlist_removed_flist = text_before . text_after
+ endif
+endfunction
+
+" Tlist_FileType_Init
+" Initialize the ctags arguments and tag variable for the specified
+" file type
+function! s:Tlist_FileType_Init(ftype)
+ call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')')
+ " If the user didn't specify any settings, then use the default
+ " ctags args. Otherwise, use the settings specified by the user
+ let var = 'g:tlist_' . a:ftype . '_settings'
+ if exists(var)
+ " User specified ctags arguments
+ let settings = {var} . ';'
+ else
+ " Default ctags arguments
+ let var = 's:tlist_def_' . a:ftype . '_settings'
+ if !exists(var)
+ " No default settings for this file type. This filetype is
+ " not supported
+ return 0
+ endif
+ let settings = s:tlist_def_{a:ftype}_settings . ';'
+ endif
+
+ let msg = 'Taglist: Invalid ctags option setting - ' . settings
+
+ " Format of the option that specifies the filetype and ctags arugments:
+ "
+ " ;flag1:name1;flag2:name2;flag3:name3
+ "
+
+ " Extract the file type to pass to ctags. This may be different from the
+ " file type detected by Vim
+ let pos = stridx(settings, ';')
+ if pos == -1
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+ let ctags_ftype = strpart(settings, 0, pos)
+ if ctags_ftype == ''
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+ " Make sure a valid filetype is supplied. If the user didn't specify a
+ " valid filetype, then the ctags option settings may be treated as the
+ " filetype
+ if ctags_ftype =~ ':'
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+
+ " Remove the file type from settings
+ let settings = strpart(settings, pos + 1)
+ if settings == ''
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+
+ " Process all the specified ctags flags. The format is
+ " flag1:name1;flag2:name2;flag3:name3
+ let ctags_flags = ''
+ let cnt = 0
+ while settings != ''
+ " Extract the flag
+ let pos = stridx(settings, ':')
+ if pos == -1
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+ let flag = strpart(settings, 0, pos)
+ if flag == ''
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+ " Remove the flag from settings
+ let settings = strpart(settings, pos + 1)
+
+ " Extract the tag type name
+ let pos = stridx(settings, ';')
+ if pos == -1
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+ let name = strpart(settings, 0, pos)
+ if name == ''
+ call s:Tlist_Warning_Msg(msg)
+ return 0
+ endif
+ let settings = strpart(settings, pos + 1)
+
+ let cnt = cnt + 1
+
+ let s:tlist_{a:ftype}_{cnt}_name = flag
+ let s:tlist_{a:ftype}_{cnt}_fullname = name
+ let ctags_flags = ctags_flags . flag
+ endwhile
+
+ let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype .
+ \ ' --' . ctags_ftype . '-types=' . ctags_flags
+ let s:tlist_{a:ftype}_count = cnt
+ let s:tlist_{a:ftype}_ctags_flags = ctags_flags
+
+ " Save the filetype name
+ let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype
+ let s:tlist_ftype_count = s:tlist_ftype_count + 1
+
+ return 1
+endfunction
+
+" Tlist_Detect_Filetype
+" Determine the filetype for the specified file using the filetypedetect
+" autocmd.
+function! s:Tlist_Detect_Filetype(fname)
+ " Ignore the filetype autocommands
+ let old_eventignore = &eventignore
+ set eventignore=FileType
+
+ " Save the 'filetype', as this will be changed temporarily
+ let old_filetype = &filetype
+
+ " Run the filetypedetect group of autocommands to determine
+ " the filetype
+ exe 'doautocmd filetypedetect BufRead ' . a:fname
+
+ " Save the detected filetype
+ let ftype = &filetype
+
+ " Restore the previous state
+ let &filetype = old_filetype
+ let &eventignore = old_eventignore
+
+ return ftype
+endfunction
+
+" Tlist_Get_Buffer_Filetype
+" Get the filetype for the specified buffer
+function! s:Tlist_Get_Buffer_Filetype(bnum)
+ let buf_ft = getbufvar(a:bnum, '&filetype')
+
+ if bufloaded(a:bnum)
+ " For loaded buffers, the 'filetype' is already determined
+ return buf_ft
+ endif
+
+ " For unloaded buffers, if the 'filetype' option is set, return it
+ if buf_ft != ''
+ return buf_ft
+ endif
+
+ " Skip non-existent buffers
+ if !bufexists(a:bnum)
+ return ''
+ endif
+
+ " For buffers whose filetype is not yet determined, try to determine
+ " the filetype
+ let bname = bufname(a:bnum)
+
+ return s:Tlist_Detect_Filetype(bname)
+endfunction
+
+" Tlist_Discard_TagInfo
+" Discard the stored tag information for a file
+function! s:Tlist_Discard_TagInfo(fidx)
+ call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' .
+ \ s:tlist_{a:fidx}_filename . ')')
+ let ftype = s:tlist_{a:fidx}_filetype
+
+ " Discard information about the tags defined in the file
+ let i = 1
+ while i <= s:tlist_{a:fidx}_tag_count
+ let fidx_i = 's:tlist_' . a:fidx . '_' . i
+ unlet! {fidx_i}_tag
+ unlet! {fidx_i}_tag_name
+ unlet! {fidx_i}_tag_type
+ unlet! {fidx_i}_ttype_idx
+ unlet! {fidx_i}_tag_proto
+ unlet! {fidx_i}_tag_searchpat
+ unlet! {fidx_i}_tag_linenum
+ let i = i + 1
+ endwhile
+
+ let s:tlist_{a:fidx}_tag_count = 0
+
+ " Discard information about tag type groups
+ let i = 1
+ while i <= s:tlist_{ftype}_count
+ let ttype = s:tlist_{ftype}_{i}_name
+ if s:tlist_{a:fidx}_{ttype} != ''
+ let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype
+ let {fidx_ttype} = ''
+ let {fidx_ttype}_offset = 0
+ let cnt = {fidx_ttype}_count
+ let {fidx_ttype}_count = 0
+ let j = 1
+ while j <= cnt
+ unlet! {fidx_ttype}_{j}
+ let j = j + 1
+ endwhile
+ endif
+ let i = i + 1
+ endwhile
+
+ " Discard the stored menu command also
+ let s:tlist_{a:fidx}_menu_cmd = ''
+endfunction
+
+" Tlist_Window_Update_Line_Offsets
+" Update the line offsets for tags for files starting from start_idx
+" and displayed in the taglist window by the specified offset
+function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset)
+ let i = a:start_idx
+
+ while i < s:tlist_file_count
+ if s:tlist_{i}_visible
+ " Update the start/end line number only if the file is visible
+ if a:increment
+ let s:tlist_{i}_start = s:tlist_{i}_start + a:offset
+ let s:tlist_{i}_end = s:tlist_{i}_end + a:offset
+ else
+ let s:tlist_{i}_start = s:tlist_{i}_start - a:offset
+ let s:tlist_{i}_end = s:tlist_{i}_end - a:offset
+ endif
+ endif
+ let i = i + 1
+ endwhile
+endfunction
+
+" Tlist_Discard_FileInfo
+" Discard the stored information for a file
+function! s:Tlist_Discard_FileInfo(fidx)
+ call s:Tlist_Log_Msg('Tlist_Discard_FileInfo (' .
+ \ s:tlist_{a:fidx}_filename . ')')
+ call s:Tlist_Discard_TagInfo(a:fidx)
+
+ let ftype = s:tlist_{a:fidx}_filetype
+
+ let i = 1
+ while i <= s:tlist_{ftype}_count
+ let ttype = s:tlist_{ftype}_{i}_name
+ unlet! s:tlist_{a:fidx}_{ttype}
+ unlet! s:tlist_{a:fidx}_{ttype}_offset
+ unlet! s:tlist_{a:fidx}_{ttype}_count
+ let i = i + 1
+ endwhile
+
+ unlet! s:tlist_{a:fidx}_filename
+ unlet! s:tlist_{a:fidx}_sort_type
+ unlet! s:tlist_{a:fidx}_filetype
+ unlet! s:tlist_{a:fidx}_mtime
+ unlet! s:tlist_{a:fidx}_start
+ unlet! s:tlist_{a:fidx}_end
+ unlet! s:tlist_{a:fidx}_valid
+ unlet! s:tlist_{a:fidx}_visible
+ unlet! s:tlist_{a:fidx}_tag_count
+ unlet! s:tlist_{a:fidx}_menu_cmd
+endfunction
+
+" Tlist_Window_Remove_File_From_Display
+" Remove the specified file from display
+function! s:Tlist_Window_Remove_File_From_Display(fidx)
+ call s:Tlist_Log_Msg('Tlist_Window_Remove_File_From_Display (' .
+ \ s:tlist_{a:fidx}_filename . ')')
+ " If the file is not visible then no need to remove it
+ if !s:tlist_{a:fidx}_visible
+ return
+ endif
+
+ " Remove the tags displayed for the specified file from the window
+ let start = s:tlist_{a:fidx}_start
+ " Include the empty line after the last line also
+ if g:Tlist_Compact_Format
+ let end = s:tlist_{a:fidx}_end
+ else
+ let end = s:tlist_{a:fidx}_end + 1
+ endif
+
+ setlocal modifiable
+ exe 'silent! ' . start . ',' . end . 'delete _'
+ setlocal nomodifiable
+
+ " Correct the start and end line offsets for all the files following
+ " this file, as the tags for this file are removed
+ call s:Tlist_Window_Update_Line_Offsets(a:fidx + 1, 0, end - start + 1)
+endfunction
+
+" Tlist_Remove_File
+" Remove the file under the cursor or the specified file index
+" user_request - User requested to remove the file from taglist
+function! s:Tlist_Remove_File(file_idx, user_request)
+ let fidx = a:file_idx
+
+ if fidx == -1
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
+ if fidx == -1
+ return
+ endif
+ endif
+ call s:Tlist_Log_Msg('Tlist_Remove_File (' .
+ \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')')
+
+ let save_winnr = winnr()
+ let winnum = bufwinnr(g:TagList_title)
+ if winnum != -1
+ " Taglist window is open, remove the file from display
+
+ if save_winnr != winnum
+ let old_eventignore = &eventignore
+ set eventignore=all
+ exe winnum . 'wincmd w'
+ endif
+
+ call s:Tlist_Window_Remove_File_From_Display(fidx)
+
+ if save_winnr != winnum
+ exe save_winnr . 'wincmd w'
+ let &eventignore = old_eventignore
+ endif
+ endif
+
+ let fname = s:tlist_{fidx}_filename
+
+ if a:user_request
+ " As the user requested to remove the file from taglist,
+ " add it to the removed list
+ call s:Tlist_Update_Remove_List(fname, 1)
+ endif
+
+ " Remove the file name from the taglist list of filenames
+ let idx = stridx(s:tlist_file_names, fname . "\n")
+ let text_before = strpart(s:tlist_file_names, 0, idx)
+ let rem_text = strpart(s:tlist_file_names, idx)
+ let next_idx = stridx(rem_text, "\n")
+ let text_after = strpart(rem_text, next_idx + 1)
+ let s:tlist_file_names = text_before . text_after
+
+ call s:Tlist_Discard_FileInfo(fidx)
+
+ " Shift all the file variables by one index
+ let i = fidx + 1
+
+ while i < s:tlist_file_count
+ let j = i - 1
+
+ let s:tlist_{j}_filename = s:tlist_{i}_filename
+ let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type
+ let s:tlist_{j}_filetype = s:tlist_{i}_filetype
+ let s:tlist_{j}_mtime = s:tlist_{i}_mtime
+ let s:tlist_{j}_start = s:tlist_{i}_start
+ let s:tlist_{j}_end = s:tlist_{i}_end
+ let s:tlist_{j}_valid = s:tlist_{i}_valid
+ let s:tlist_{j}_visible = s:tlist_{i}_visible
+ let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count
+ let s:tlist_{j}_menu_cmd = s:tlist_{i}_menu_cmd
+
+ let k = 1
+ while k <= s:tlist_{j}_tag_count
+ let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag
+ let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name
+ let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k)
+ let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx
+ let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k)
+ let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k)
+ let s:tlist_{j}_{k}_tag_linenum = s:Tlist_Get_Tag_Linenum(i, k)
+ let k = k + 1
+ endwhile
+
+ let ftype = s:tlist_{i}_filetype
+
+ let k = 1
+ while k <= s:tlist_{ftype}_count
+ let ttype = s:tlist_{ftype}_{k}_name
+ let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype}
+ let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset
+ let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count
+ if s:tlist_{j}_{ttype} != ''
+ let l = 1
+ while l <= s:tlist_{j}_{ttype}_count
+ let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l}
+ let l = l + 1
+ endwhile
+ endif
+ let k = k + 1
+ endwhile
+
+ " As the file and tag information is copied to the new index,
+ " discard the previous information
+ call s:Tlist_Discard_FileInfo(i)
+
+ let i = i + 1
+ endwhile
+
+ " Reduce the number of files displayed
+ let s:tlist_file_count = s:tlist_file_count - 1
+
+ if g:Tlist_Show_One_File
+ " If the tags for only one file is displayed and if we just
+ " now removed that file, then invalidate the current file idx
+ if s:tlist_cur_file_idx == fidx
+ let s:tlist_cur_file_idx = -1
+ endif
+ endif
+endfunction
+
+" Tlist_Window_Goto_Window
+" Goto the taglist window
+function! s:Tlist_Window_Goto_Window()
+ let winnum = bufwinnr(g:TagList_title)
+ if winnum != -1
+ if winnr() != winnum
+ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w')
+ endif
+ endif
+endfunction
+
+" Tlist_Window_Create
+" Create a new taglist window. If it is already open, jump to it
+function! s:Tlist_Window_Create()
+ call s:Tlist_Log_Msg('Tlist_Window_Create()')
+ " If the window is open, jump to it
+ let winnum = bufwinnr(g:TagList_title)
+ if winnum != -1
+ " Jump to the existing window
+ if winnr() != winnum
+ exe winnum . 'wincmd w'
+ endif
+ return
+ endif
+
+ " If used with winmanager don't open windows. Winmanager will handle
+ " the window/buffer management
+ if s:tlist_app_name == "winmanager"
+ return
+ endif
+
+ " Create a new window. If user prefers a horizontal window, then open
+ " a horizontally split window. Otherwise open a vertically split
+ " window
+ if g:Tlist_Use_Horiz_Window
+ " Open a horizontally split window
+ let win_dir = 'botright'
+ " Horizontal window height
+ let win_size = g:Tlist_WinHeight
+ else
+ if s:tlist_winsize_chgd == -1
+ " Open a vertically split window. Increase the window size, if
+ " needed, to accomodate the new window
+ if g:Tlist_Inc_Winwidth &&
+ \ &columns < (80 + g:Tlist_WinWidth)
+ " Save the original window position
+ let s:tlist_pre_winx = getwinposx()
+ let s:tlist_pre_winy = getwinposy()
+
+ " one extra column is needed to include the vertical split
+ let &columns= &columns + g:Tlist_WinWidth + 1
+
+ let s:tlist_winsize_chgd = 1
+ else
+ let s:tlist_winsize_chgd = 0
+ endif
+ endif
+
+ if g:Tlist_Use_Right_Window
+ " Open the window at the rightmost place
+ let win_dir = 'botright vertical'
+ else
+ " Open the window at the leftmost place
+ let win_dir = 'topleft vertical'
+ endif
+ let win_size = g:Tlist_WinWidth
+ endif
+
+ " If the tag listing temporary buffer already exists, then reuse it.
+ " Otherwise create a new buffer
+ let bufnum = bufnr(g:TagList_title)
+ if bufnum == -1
+ " Create a new buffer
+ let wcmd = g:TagList_title
+ else
+ " Edit the existing buffer
+ let wcmd = '+buffer' . bufnum
+ endif
+
+ " Create the taglist window
+ exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd
+
+ " Save the new window position
+ let s:tlist_winx = getwinposx()
+ let s:tlist_winy = getwinposy()
+
+ " Initialize the taglist window
+ call s:Tlist_Window_Init()
+endfunction
+
+" Tlist_Window_Zoom
+" Zoom (maximize/minimize) the taglist window
+function! s:Tlist_Window_Zoom()
+ if s:tlist_win_maximized
+ " Restore the window back to the previous size
+ if g:Tlist_Use_Horiz_Window
+ exe 'resize ' . g:Tlist_WinHeight
+ else
+ exe 'vert resize ' . g:Tlist_WinWidth
+ endif
+ let s:tlist_win_maximized = 0
+ else
+ " Set the window size to the maximum possible without closing other
+ " windows
+ if g:Tlist_Use_Horiz_Window
+ resize
+ else
+ vert resize
+ endif
+ let s:tlist_win_maximized = 1
+ endif
+endfunction
+
+" Tlist_Ballon_Expr
+" When the mouse cursor is over a tag in the taglist window, display the
+" tag prototype (balloon)
+function! Tlist_Ballon_Expr()
+ " Get the file index
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(v:beval_lnum)
+ if fidx == -1
+ return ''
+ endif
+
+ " Get the tag output line for the current tag
+ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, v:beval_lnum)
+ if tidx == 0
+ return ''
+ endif
+
+ " Get the tag search pattern and display it
+ return s:Tlist_Get_Tag_Prototype(fidx, tidx)
+endfunction
+
+" Tlist_Window_Check_Width
+" Check the width of the taglist window. For horizontally split windows, the
+" 'winfixheight' option is used to fix the height of the window. For
+" vertically split windows, Vim doesn't support the 'winfixwidth' option. So
+" need to handle window width changes from this function.
+function! s:Tlist_Window_Check_Width()
+ let tlist_winnr = bufwinnr(g:TagList_title)
+ if tlist_winnr == -1
+ return
+ endif
+
+ let width = winwidth(tlist_winnr)
+ if width != g:Tlist_WinWidth
+ call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " .
+ \ "width from " . width . " to " . g:Tlist_WinWidth)
+ let save_winnr = winnr()
+ if save_winnr != tlist_winnr
+ call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w')
+ endif
+ exe 'vert resize ' . g:Tlist_WinWidth
+ if save_winnr != tlist_winnr
+ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
+ endif
+ endif
+endfunction
+
+" Tlist_Window_Exit_Only_Window
+" If the 'Tlist_Exit_OnlyWindow' option is set, then exit Vim if only the
+" taglist window is present.
+function! s:Tlist_Window_Exit_Only_Window()
+ " Before quitting Vim, delete the taglist buffer so that
+ " the '0 mark is correctly set to the previous buffer.
+ if v:version < 700
+ if winbufnr(2) == -1
+ bdelete
+ quit
+ endif
+ else
+ if winbufnr(2) == -1
+ if tabpagenr('$') == 1
+ " Only one tag page is present
+ bdelete
+ quit
+ else
+ " More than one tab page is present. Close only the current
+ " tab page
+ close
+ endif
+ endif
+ endif
+endfunction
+
+" Tlist_Window_Init
+" Set the default options for the taglist window
+function! s:Tlist_Window_Init()
+ call s:Tlist_Log_Msg('Tlist_Window_Init()')
+
+ " The 'readonly' option should not be set for the taglist buffer.
+ " If Vim is started as "view/gview" or if the ":view" command is
+ " used, then the 'readonly' option is set for all the buffers.
+ " Unset it for the taglist buffer
+ setlocal noreadonly
+
+ " Set the taglist buffer filetype to taglist
+ setlocal filetype=taglist
+
+ " Define taglist window element highlighting
+ syntax match TagListComment '^" .*'
+ syntax match TagListFileName '^[^" ].*$'
+ syntax match TagListTitle '^ \S.*$'
+ syntax match TagListTagScope '\s\[.\{-\}\]$'
+
+ " Define the highlighting only if colors are supported
+ if has('gui_running') || &t_Co > 2
+ " Colors to highlight various taglist window elements
+ " If user defined highlighting group exists, then use them.
+ " Otherwise, use default highlight groups.
+ if hlexists('MyTagListTagName')
+ highlight link TagListTagName MyTagListTagName
+ else
+ highlight default link TagListTagName Search
+ endif
+ " Colors to highlight comments and titles
+ if hlexists('MyTagListComment')
+ highlight link TagListComment MyTagListComment
+ else
+ highlight clear TagListComment
+ highlight default link TagListComment Comment
+ endif
+ if hlexists('MyTagListTitle')
+ highlight link TagListTitle MyTagListTitle
+ else
+ highlight clear TagListTitle
+ highlight default link TagListTitle Title
+ endif
+ if hlexists('MyTagListFileName')
+ highlight link TagListFileName MyTagListFileName
+ else
+ highlight clear TagListFileName
+ highlight default TagListFileName guibg=Grey ctermbg=darkgray
+ \ guifg=white ctermfg=white
+ endif
+ if hlexists('MyTagListTagScope')
+ highlight link TagListTagScope MyTagListTagScope
+ else
+ highlight clear TagListTagScope
+ highlight default link TagListTagScope Identifier
+ endif
+ else
+ highlight default TagListTagName term=reverse cterm=reverse
+ endif
+
+ " Folding related settings
+ setlocal foldenable
+ setlocal foldminlines=0
+ setlocal foldmethod=manual
+ setlocal foldlevel=9999
+ if g:Tlist_Enable_Fold_Column
+ setlocal foldcolumn=3
+ else
+ setlocal foldcolumn=0
+ endif
+ setlocal foldtext=v:folddashes.getline(v:foldstart)
+
+ if s:tlist_app_name != "winmanager"
+ " Mark buffer as scratch
+ silent! setlocal buftype=nofile
+ if s:tlist_app_name == "none"
+ silent! setlocal bufhidden=delete
+ endif
+ silent! setlocal noswapfile
+ " Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted
+ " buffers. So if the taglist buffer is unlisted, multiple taglist
+ " windows will be opened. This bug is fixed in Vim 6.1 and above
+ if v:version >= 601
+ silent! setlocal nobuflisted
+ endif
+ endif
+
+ silent! setlocal nowrap
+
+ " If the 'number' option is set in the source window, it will affect the
+ " taglist window. So forcefully disable 'number' option for the taglist
+ " window
+ silent! setlocal nonumber
+
+ " Use fixed height when horizontally split window is used
+ if g:Tlist_Use_Horiz_Window
+ if v:version >= 602
+ set winfixheight
+ endif
+ endif
+ if !g:Tlist_Use_Horiz_Window && v:version >= 700
+ set winfixwidth
+ endif
+
+ " Setup balloon evaluation to display tag prototype
+ if v:version >= 700 && has('balloon_eval')
+ setlocal balloonexpr=Tlist_Ballon_Expr()
+ set ballooneval
+ endif
+
+ " Setup the cpoptions properly for the maps to work
+ let old_cpoptions = &cpoptions
+ set cpoptions&vim
+
+ " Create buffer local mappings for jumping to the tags and sorting the list
+ nnoremap
+ \ :call Tlist_Window_Jump_To_Tag('useopen')
+ nnoremap o
+ \ :call Tlist_Window_Jump_To_Tag('newwin')
+ nnoremap p
+ \ :call Tlist_Window_Jump_To_Tag('preview')
+ nnoremap P
+ \ :call Tlist_Window_Jump_To_Tag('prevwin')
+ if v:version >= 700
+ nnoremap t
+ \ :call Tlist_Window_Jump_To_Tag('checktab')
+ nnoremap
+ \ :call Tlist_Window_Jump_To_Tag('newtab')
+ endif
+ nnoremap <2-LeftMouse>
+ \ :call Tlist_Window_Jump_To_Tag('useopen')
+ nnoremap s
+ \ :call Tlist_Change_Sort('cmd', 'toggle', '')
+ nnoremap + :silent! foldopen
+ nnoremap - :silent! foldclose
+ nnoremap * :silent! %foldopen!
+ nnoremap = :silent! %foldclose
+ nnoremap :silent! foldopen
+ nnoremap :silent! foldclose
+ nnoremap :silent! %foldopen!
+ nnoremap :call Tlist_Window_Show_Info()
+ nnoremap u :call Tlist_Window_Update_File()
+ nnoremap d :call Tlist_Remove_File(-1, 1)
+ nnoremap x :call Tlist_Window_Zoom()
+ nnoremap [[ :call Tlist_Window_Move_To_File(-1)
+ nnoremap :call Tlist_Window_Move_To_File(-1)
+ nnoremap ]] :call Tlist_Window_Move_To_File(1)
+ nnoremap :call Tlist_Window_Move_To_File(1)
+ nnoremap :call Tlist_Window_Toggle_Help_Text()
+ nnoremap q :close
+
+ " Insert mode mappings
+ inoremap
+ \ :call Tlist_Window_Jump_To_Tag('useopen')
+ " Windows needs return
+ inoremap
+ \ :call Tlist_Window_Jump_To_Tag('useopen')
+ inoremap o
+ \ :call Tlist_Window_Jump_To_Tag('newwin')
+ inoremap p
+ \ :call Tlist_Window_Jump_To_Tag('preview')
+ inoremap P
+ \ :call Tlist_Window_Jump_To_Tag('prevwin')
+ if v:version >= 700
+ inoremap t
+ \ :call Tlist_Window_Jump_To_Tag('checktab')
+ inoremap
+ \ :call Tlist_Window_Jump_To_Tag('newtab')
+ endif
+ inoremap <2-LeftMouse>
+ \ :call Tlist_Window_Jump_To_Tag('useopen')
+ inoremap s
+ \ :call Tlist_Change_Sort('cmd', 'toggle', '')
+ inoremap + :silent! foldopen
+ inoremap -