Add autotags
This commit is contained in:
parent
c460d5ee3c
commit
a0589a1dfe
539
.vim/plugin/autotags.vim
Normal file
539
.vim/plugin/autotags.vim
Normal file
@ -0,0 +1,539 @@
|
||||
" autotags plugin: a wrapper for ctags and cscope, so tags for all languages
|
||||
" supported by ctags can be build (cscope is additionally used for C/C++).
|
||||
" Tags are stored in a separate directory and don't clog you project tree
|
||||
|
||||
|
||||
" vim: set sw=4 sts=4 et ft=vim :
|
||||
" Script: autotags.vim
|
||||
" Author: Basil Gor <basil.gor at gmail.com>
|
||||
" Homepage: http://github.com/basilgor/vim-autotags
|
||||
" Version: 1.0 (10 Oct 2012)
|
||||
" License: Redistribute under the same terms as Vim itself
|
||||
" Purpose: ctags and cscope tags handling
|
||||
" Documentation:
|
||||
" This script is a wrapper for ctags and cscope, so tags for all languages
|
||||
" supported by ctags can be build (cscope is additionally used for C/C++).
|
||||
"
|
||||
" Features
|
||||
" 1. No configuration needed
|
||||
" 2. Build/rebuild index for project with a single key stroke
|
||||
" 3. Tags are loaded then automatically when a file is opened anywhere in
|
||||
" project tree
|
||||
" 4. Tags are stored in a separate directory and don't clog you project tree
|
||||
" 5. Extra directories (like library source or includes) can be added with a
|
||||
" single key stroke too
|
||||
"
|
||||
" Put autotags.vim in your ~/.vim/plugin directory, open source code and
|
||||
" press F4 (map AutotagsUpdate to change it).
|
||||
"
|
||||
" You can reindex sources by pressing F4 again.
|
||||
"
|
||||
" To build and load additional tags for another directory (i.e. external
|
||||
" project or library code you want to navigate to) press F3 (or map
|
||||
" AutotagsAdd).
|
||||
"
|
||||
" Script builds and loads ctags and cscope databases via a single command.
|
||||
" All ctags and cscope files are stored in separate directory ~/.autotags by
|
||||
" default. You can set it via
|
||||
" let g:autotagsdir = $HOME."/boo"
|
||||
"
|
||||
" Project root directory will be asked when indexing new project. After that
|
||||
" tags will be loaded automatically when source files somewhere in project
|
||||
" tree are opened (if path contains project root).
|
||||
"
|
||||
" Exact tags location:
|
||||
" ~/.autotags/byhash/<source dir name hash>/<ctags and cscope files>
|
||||
"
|
||||
" Also `origin` symlink points back to source dir
|
||||
" ~/.autotags/byhash/<source dir name hash>/origin
|
||||
"
|
||||
" `include_*` symlinks point to additional tags for external directories
|
||||
" ~/.autotags/byhash/<source dir name hash>/include_*
|
||||
"
|
||||
" Tags for non-existing source directories are removed automatically
|
||||
" (checked at startup)
|
||||
"
|
||||
" Also ctags file ~/.autotags/global_tags is built for /usr/include once
|
||||
"
|
||||
" Below are configuration variables for the script you can set in .vimrc:
|
||||
"
|
||||
" let g:autotagsdir = $HOME . "/.autotags/byhash"
|
||||
" let g:autotags_global = $HOME . "/.autotags/global_tags"
|
||||
"
|
||||
" Set to 1 to get paths with metachars replaced by . as path hashes
|
||||
" Default is 0, md5sum hash is used
|
||||
" let g:autotags_pathhash_humanreadable = 0
|
||||
" let g:autotags_ctags_exe = "ctags"
|
||||
" let g:autotags_ctags_opts = "--c++-kinds=+p --fields=+iaS --extra=+q"
|
||||
"
|
||||
" see `man ctags` "--languages" options
|
||||
" let g:autotags_ctags_languages = "all"
|
||||
"
|
||||
" see `man ctags` "--langmap" options
|
||||
" let g:autotags_ctags_langmap = "default"
|
||||
"
|
||||
" set to 1 to avoid generating global tags for /usr/include
|
||||
" let g:autotags_no_global = 0
|
||||
" let g:autotags_ctags_global_include = "/usr/include/*"
|
||||
" let g:autotags_cscope_exe = "cscope"
|
||||
" let g:autotags_cscope_file_extensions = ".cpp .cc .cxx .m .hpp .hh .h .hxx .c .idl"
|
||||
"
|
||||
" set to 1 to export $CSCOPE_DIR during initialization and tags build
|
||||
" let g:autotags_export_cscope_dir = 0
|
||||
"
|
||||
" Public Interface:
|
||||
" AutotagsUpdate() build/rebuild tags (mapped to F4 by default)
|
||||
" AutotagsAdd() build and load additional tags for another directory
|
||||
" AutotagsRemove() remove currently used tags
|
||||
"
|
||||
" AutotagsUpdatePath(path) build/rebuild tags (no user interaction)
|
||||
" AutotagsAddPath(path) build and load additional tags for another
|
||||
" directory (no user interaction)
|
||||
"
|
||||
" Last two calls can be used to generate tags from batch mode, i.e.:
|
||||
" $ vim -E -v >/dev/null 2>&1 <<EOF
|
||||
" :call AutotagsUpdatePath("/you/project/source")
|
||||
" :call AutotagsAddPath("/external/library/source")
|
||||
" :call AutotagsAddPath("/external/library2/source")
|
||||
" :call AutotagsAddPath("/external/library3/source")
|
||||
" :quit
|
||||
" EOF
|
||||
"
|
||||
" Dependencies:
|
||||
" ctags and cscope
|
||||
" md5sum
|
||||
" cscope_maps.vim plugin is recommended
|
||||
"
|
||||
|
||||
if exists("g:loaded_autotags") || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_autotags = 1.0
|
||||
let s:keepcpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Global Maps:
|
||||
"
|
||||
if !hasmapto('AutotagsUpdate')
|
||||
map <F3> :call AutotagsUpdate()<CR>
|
||||
endif
|
||||
|
||||
if !hasmapto('AutotagsAdd')
|
||||
map <S-F3> :call AutotagsAdd()<CR>
|
||||
endif
|
||||
|
||||
fun! s:PathHash(val)
|
||||
if g:autotags_pathhash_humanreadable == 0
|
||||
return substitute(system("sha1sum", a:val), " .*", "", "")
|
||||
else
|
||||
return substitute(strpart(a:val, 1),
|
||||
\ '/\|\s\|\[\|\]\|;\|<\|>\|\\\|\*\|`\|&\||\|\$\|#\|!\|(\|)\|{\|}\|:\|"\|'."'", ".", "g")
|
||||
endif
|
||||
endfun
|
||||
|
||||
" find and load tags, delete stale tags
|
||||
fun! s:AutotagsInit()
|
||||
if !exists("g:autotagsdir")
|
||||
let g:autotagsdir = $HOME . "/.autotags/byhash"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_pathhash_humanreadable")
|
||||
let g:autotags_pathhash_humanreadable = 0
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_global")
|
||||
let g:autotags_global = $HOME . "/.autotags/global_tags"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_no_global")
|
||||
let g:autotags_no_global = 0
|
||||
endif
|
||||
|
||||
if g:autotags_no_global == 0 && filereadable(g:autotags_global)
|
||||
exe "set tags=" . g:autotags_global
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_search_tags")
|
||||
let g:autotags_search_tags = 0
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_ctags_exe")
|
||||
let g:autotags_ctags_exe = "ctags"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_ctags_opts")
|
||||
let g:autotags_ctags_opts = "--c++-kinds=+p --fields=+iaS --extra=+q"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_ctags_languages")
|
||||
let g:autotags_ctags_languages = "all"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_ctags_langmap")
|
||||
let g:autotags_ctags_langmap = "default"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_ctags_global_include")
|
||||
let g:autotags_ctags_global_include = "/usr/include/* /usr/include/sys/* " .
|
||||
\ "/usr/include/net* /usr/include/bits/* /usr/include/arpa/* " .
|
||||
\ "/usr/include/asm/* /usr/include/asm-generic/* /usr/include/linux/*"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_cscope_exe")
|
||||
let g:autotags_cscope_exe = "cscope"
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_pycscope_cmd")
|
||||
let g:autotags_pycscope_pyt = "/usr/bin/python"
|
||||
let g:autotags_pycscope_scr = "~/.vim/plugin/pycscope.py"
|
||||
let g:autotags_pycscope_cmd = g:autotags_pycscope_pyt . " " . g:autotags_pycscope_scr
|
||||
endif
|
||||
|
||||
if !exists("g:autotags_cscope_file_extensions")
|
||||
let g:autotags_cscope_file_extensions = ".cpp .cc .cxx .m .hpp .hh .h .hxx .c .idl .java"
|
||||
endif
|
||||
|
||||
let s:cscope_file_pattern = '.*\' .
|
||||
\ join(split(g:autotags_cscope_file_extensions, " "), '\|.*\')
|
||||
|
||||
if !exists("g:autotags_export_cscope_dir")
|
||||
let g:autotags_export_cscope_dir = 0
|
||||
endif
|
||||
|
||||
if executable(g:autotags_ctags_exe) == 0
|
||||
echomsg "autotags warning: `" . g:autotags_ctags_exe .
|
||||
\ "' cannot be found on your system"
|
||||
endif
|
||||
|
||||
if executable(g:autotags_cscope_exe) == 0
|
||||
echomsg "autotags warning: `" . g:autotags_cscope_exe .
|
||||
\ "' cannot be found on your system"
|
||||
endif
|
||||
|
||||
call s:AutotagsCleanup()
|
||||
|
||||
" find autotags subdir
|
||||
let l:dir = getcwd()
|
||||
while l:dir != "/"
|
||||
if getftype(g:autotagsdir . '/' . s:PathHash(l:dir)) == "dir"
|
||||
let s:autotags_subdir = g:autotagsdir . '/' . s:PathHash(l:dir)
|
||||
echomsg "autotags subdir exist: " . s:autotags_subdir
|
||||
break
|
||||
endif
|
||||
" get parent directory
|
||||
let l:dir = fnamemodify(l:dir, ":p:h:h")
|
||||
endwhile
|
||||
|
||||
if exists("s:autotags_subdir")
|
||||
call s:AutotagsReload(s:autotags_subdir)
|
||||
else
|
||||
call s:AutotagsSearchLoadTags()
|
||||
endif
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsIsC()
|
||||
if &ft == "cpp" || &ft == "c"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfun
|
||||
|
||||
fun! GetLocalCscopeDb(pathname)
|
||||
if !isdirectory(a:pathname) || a:pathname == $HOME || a:pathname == '/'
|
||||
return
|
||||
endif
|
||||
let s:cscopefile = a:pathname."/cscope.out"
|
||||
if filereadable(s:cscopefile)
|
||||
" echo "Add cscope db for ".a:pathname
|
||||
execute "cscope add ".s:cscopefile." ".a:pathname
|
||||
endif
|
||||
unlet s:cscopefile
|
||||
call GetLocalCscopeDb(fnamemodify(a:pathname, ":h"))
|
||||
endfunction
|
||||
|
||||
fun! GetLocalTags(pathname)
|
||||
if !isdirectory(a:pathname) || a:pathname == $HOME || a:pathname == '/'
|
||||
return
|
||||
endif
|
||||
let s:ctagsfile = a:pathname."/tags"
|
||||
if filereadable(s:ctagsfile)
|
||||
" echo "Add tags db for ".a:pathname
|
||||
exe "set tags+=" . s:ctagsfile
|
||||
endif
|
||||
unlet s:ctagsfile
|
||||
call GetLocalTags(fnamemodify(a:pathname, ":h"))
|
||||
endfunction
|
||||
|
||||
fun! s:AutotagsSearchLoadTags()
|
||||
" search ctags in current tree
|
||||
call GetLocalTags(expand("%:p:h"))
|
||||
" if filereadable(findfile("tags", ".;"))
|
||||
" let l:ctagsfile = findfile("tags", ".;")
|
||||
" exe "set tags+=" . l:ctagsfile
|
||||
" echomsg "found local ctags file: " . l:ctagsfile
|
||||
" endif
|
||||
|
||||
call GetLocalCscopeDb(expand("%:p:h"))
|
||||
" search cscope db in current tree
|
||||
" if filereadable(findfile("cscope.out", ".;"))
|
||||
" let l:cscopedb = findfile("cscope.out", ".;")
|
||||
" exe "cs add " . l:cscopedb . " " . fnamemodify(l:cscopedb, ":p:h")
|
||||
" echomsg "found local cscopedb file: " . l:cscopedb
|
||||
" endif
|
||||
endfun
|
||||
|
||||
" remove stale tags for non-existing source directories
|
||||
fun! s:AutotagsCleanup()
|
||||
if !isdirectory(g:autotagsdir)
|
||||
return
|
||||
endif
|
||||
|
||||
for l:entry in split(system("ls " . g:autotagsdir), "\n")
|
||||
let l:path = g:autotagsdir . "/" . l:entry
|
||||
if getftype(l:path) == "dir"
|
||||
let l:origin = l:path . "/origin"
|
||||
if getftype(l:origin) == 'link' && !isdirectory(l:origin)
|
||||
echomsg "deleting stale tags for " .
|
||||
\ fnamemodify(resolve(l:origin), ":p")
|
||||
call system("rm -r " . shellescape(l:path))
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsValidatePath(path)
|
||||
if a:path == ""
|
||||
echomsg "no directory specified"
|
||||
return ""
|
||||
endif
|
||||
|
||||
let l:fullpath = fnamemodify(a:path, ":p")
|
||||
|
||||
if !isdirectory(l:fullpath)
|
||||
echomsg "directory " . l:fullpath . " doesn't exist"
|
||||
return ""
|
||||
endif
|
||||
|
||||
let l:fullpath = substitute(l:fullpath, "\/$", "", "")
|
||||
return l:fullpath
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsAskPath(hint, msg)
|
||||
call inputsave()
|
||||
let l:path = input(a:msg, a:hint, "file")
|
||||
call inputrestore()
|
||||
echomsg " "
|
||||
|
||||
return s:AutotagsValidatePath(l:path)
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsMakeTagsDir(sourcedir)
|
||||
let l:tagsdir = g:autotagsdir . '/' . s:PathHash(a:sourcedir)
|
||||
if !isdirectory(l:tagsdir) && !mkdir(l:tagsdir, "p")
|
||||
echomsg "cannot create dir " . l:tagsdir
|
||||
return ""
|
||||
endif
|
||||
|
||||
call system("ln -s " . shellescape(a:sourcedir) . " " .
|
||||
\ shellescape(l:tagsdir . "/origin"))
|
||||
return l:tagsdir
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsGenerateGlobal()
|
||||
echomsg "updating global ctags " . g:autotags_global . " for " .
|
||||
\ g:autotags_ctags_global_include
|
||||
echomsg system("nice -15 " . g:autotags_ctags_exe . " " .
|
||||
\ g:autotags_ctags_opts .
|
||||
\ " -f " . shellescape(g:autotags_global) . " " .
|
||||
\ g:autotags_ctags_global_include)
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsGenerate(sourcedir, tagsdir)
|
||||
let l:ctagsfile = a:tagsdir . "/tags"
|
||||
echomsg "updating ctags " . shellescape(l:ctagsfile) ." for " .
|
||||
\ shellescape(a:sourcedir)
|
||||
echomsg system("nice -15 " . g:autotags_ctags_exe . " -R " .
|
||||
\ g:autotags_ctags_opts .
|
||||
\ " '--languages=" . g:autotags_ctags_languages .
|
||||
\ "' '--langmap=" . g:autotags_ctags_langmap .
|
||||
\ "' -f " . shellescape(l:ctagsfile) . " " .
|
||||
\ shellescape(a:sourcedir))
|
||||
|
||||
let l:cscopedir = a:tagsdir
|
||||
echomsg "updating cscopedb in " . shellescape(l:cscopedir) ." for " .
|
||||
\ shellescape(a:sourcedir)
|
||||
echomsg system("cd " . shellescape(l:cscopedir) . " && " .
|
||||
\ " nice -15 find " . shellescape(a:sourcedir) .
|
||||
\ " -not -regex '.*/\\..*' " .
|
||||
\ " -not -regex '.*/\\%.*' " .
|
||||
\ " -regex '" . s:cscope_file_pattern . "' " .
|
||||
\ " -fprint cscope.files")
|
||||
if getfsize(l:cscopedir . "/cscope.files") > 0
|
||||
if g:autotags_no_global == 0
|
||||
echomsg system("cd " . shellescape(l:cscopedir) . " && " .
|
||||
\ "nice -15 " . g:autotags_cscope_exe . " -b -q")
|
||||
else
|
||||
echomsg system("cd " . shellescape(l:cscopedir) . " && " .
|
||||
\ "nice -15 " . g:autotags_cscope_exe . " -b -q -k")
|
||||
endif
|
||||
endif
|
||||
echomsg system("cd " . shellescape(l:cscopedir) . " && " .
|
||||
\ " nice -15 find " . shellescape(a:sourcedir) .
|
||||
\ " -not -regex '.*/\\..*' " .
|
||||
\ " -not -regex '.*/\\%.*' " .
|
||||
\ " -name '*.py' " .
|
||||
\ " -fprint cscope_py.files")
|
||||
if getfsize(l:cscopedir . "/cscope_py.files") > 0
|
||||
echomsg system("cd " . shellescape(l:cscopedir) . " && " .
|
||||
\ "nice -15 " . g:autotags_pycscope_cmd . " -i cscope_py.files -f cscope_py.out" )
|
||||
endif
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsReload(tagsdir)
|
||||
if g:autotags_export_cscope_dir == 1
|
||||
let $CSCOPE_DIR=a:tagsdir
|
||||
endif
|
||||
|
||||
set nocsverb
|
||||
exe "cs kill -1"
|
||||
if g:autotags_no_global == 0 && filereadable(g:autotags_global)
|
||||
exe "set tags=" . g:autotags_global
|
||||
else
|
||||
exe "set tags="
|
||||
endif
|
||||
|
||||
call s:AutotagsLoad(a:tagsdir)
|
||||
|
||||
for l:entry in split(system("ls " . a:tagsdir), "\n")
|
||||
if stridx(l:entry, "include_") == 0
|
||||
let l:path = a:tagsdir . "/" . l:entry
|
||||
if getftype(l:path) == 'link' && isdirectory(l:path)
|
||||
call s:AutotagsLoad(l:path)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsLoad(tagsdir)
|
||||
let l:ctagsfile = a:tagsdir . "/tags"
|
||||
if filereadable(l:ctagsfile)
|
||||
exe "set tags+=" . l:ctagsfile
|
||||
endif
|
||||
|
||||
let l:cscopedb = a:tagsdir . "/cscope.out"
|
||||
if filereadable(l:cscopedb)
|
||||
exe "cs add " . l:cscopedb
|
||||
endif
|
||||
|
||||
let l:cscopepydb = a:tagsdir . "/cscope_py.out"
|
||||
if filereadable(l:cscopepydb)
|
||||
exe "cs add " . l:cscopepydb
|
||||
endif
|
||||
endfun
|
||||
|
||||
fun! s:AutotagsIsLoaded()
|
||||
if !exists("s:autotags_subdir") ||
|
||||
\ !isdirectory(s:autotags_subdir) ||
|
||||
\ !isdirectory(s:autotags_subdir . '/origin')
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
endif
|
||||
endfun
|
||||
|
||||
fun! AutotagsUpdate()
|
||||
if s:AutotagsIsLoaded() == 0
|
||||
let l:sourcedir = s:AutotagsAskPath(getcwd(), "Select project root: ")
|
||||
if l:sourcedir == ""
|
||||
return
|
||||
endif
|
||||
else
|
||||
let l:sourcedir = resolve(s:autotags_subdir . "/origin")
|
||||
endif
|
||||
|
||||
call AutotagsUpdatePath(l:sourcedir)
|
||||
endfun
|
||||
|
||||
fun! AutotagsUpdatePath(sourcedir)
|
||||
if s:AutotagsIsLoaded() == 0
|
||||
let l:sourcedir = s:AutotagsValidatePath(a:sourcedir)
|
||||
if l:sourcedir == ""
|
||||
return
|
||||
endif
|
||||
|
||||
let s:autotags_subdir = s:AutotagsMakeTagsDir(l:sourcedir)
|
||||
if s:autotags_subdir == ""
|
||||
unlet s:autotags_subdir
|
||||
return
|
||||
endif
|
||||
else
|
||||
let l:sourcedir = resolve(s:autotags_subdir . "/origin")
|
||||
endif
|
||||
|
||||
if g:autotags_no_global == 0 && !filereadable(g:autotags_global)
|
||||
call s:AutotagsGenerateGlobal()
|
||||
endif
|
||||
call s:AutotagsGenerate(l:sourcedir, s:autotags_subdir)
|
||||
call s:AutotagsReload(s:autotags_subdir)
|
||||
endfun
|
||||
|
||||
" Add dependent source directory, tags for that directory will be loaded to
|
||||
" current project
|
||||
fun! AutotagsAdd()
|
||||
if s:AutotagsIsLoaded() == 0
|
||||
call AutotagsUpdate()
|
||||
endif
|
||||
|
||||
let l:sourcedir = s:AutotagsAskPath(getcwd(), "Select additional directory: ")
|
||||
if l:sourcedir == ""
|
||||
return
|
||||
endif
|
||||
|
||||
call AutotagsAddPath(l:sourcedir)
|
||||
endfun
|
||||
|
||||
fun! AutotagsAddPath(sourcedir)
|
||||
if s:AutotagsIsLoaded() == 0
|
||||
echomsg "call AutotagsUpdate first"
|
||||
return
|
||||
endif
|
||||
|
||||
let l:sourcedir = s:AutotagsValidatePath(a:sourcedir)
|
||||
if l:sourcedir == "" ||
|
||||
\ l:sourcedir == resolve(s:autotags_subdir . "/origin")
|
||||
return
|
||||
endif
|
||||
|
||||
let l:tagsdir = s:AutotagsMakeTagsDir(l:sourcedir)
|
||||
if l:tagsdir == ""
|
||||
return
|
||||
endif
|
||||
|
||||
call s:AutotagsGenerate(l:sourcedir, l:tagsdir)
|
||||
|
||||
call system("ln -s " . shellescape(l:tagsdir) . " " .
|
||||
\ shellescape(s:autotags_subdir . "/include_" . s:PathHash(l:sourcedir)))
|
||||
call s:AutotagsReload(s:autotags_subdir)
|
||||
endfun
|
||||
|
||||
fun! AutotagsRemove()
|
||||
if exists("s:autotags_subdir")
|
||||
echomsg "deleting autotags " . s:autotags_subdir . " for " .
|
||||
\ fnamemodify(resolve(s:autotags_subdir . "/origin"), ":p")
|
||||
call system("rm -r " . shellescape(s:autotags_subdir))
|
||||
if g:autotags_no_global == 0 && filereadable(g:autotags_global)
|
||||
exe "set tags=" . g:autotags_global
|
||||
else
|
||||
exe "set tags="
|
||||
endif
|
||||
exe "cs kill -1"
|
||||
exe "cs reset"
|
||||
endif
|
||||
endfun
|
||||
|
||||
set nocsverb
|
||||
call <SID>AutotagsInit()
|
||||
|
||||
let &cpo= s:keepcpo
|
||||
unlet s:keepcpo
|
Loading…
Reference in New Issue
Block a user