" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
UseVimball
finish
ftplugin/vim_ftpdev.vim [[[1
721
" Title: Vim filetype plugin file
" Author: Marcin Szamotulski
" Email: mszamot [AT] gmail [DOT] com
" License: vim-license, see ':help license'
" Copyright: © Marcin Szamotulski, 2012
" GetLatestVimScript: 3322 2 :AutoInstall: FTPDEV
"
" Todo: gd (search in current scope) and gD (search for global definition).
" Copyright Statement: {{{1
" This file is a part of Automatic Tex Plugin for Vim.
"
" Automatic Tex Plugin for Vim is free software: you can redistribute it
" and/or modify it under the terms of the GNU General Public License as
" published by the Free Software Foundation, either version 3 of the
" License, or (at your option) any later version.
"
" Automatic Tex Plugin for Vim is distributed in the hope that it will be
" useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
" General Public License for more details.
"
" You should have received a copy of the GNU General Public License along
" with Automatic Tex Plugin for Vim. If not, see .
"
" This licence applies to all files shipped with Automatic Tex Plugin.
"{{{1 GLOBAL VARIABLES
let s:vim_dirs = [ "ftplugin", "plugin", "autoload", "compiler", "syntax",
\ "indent", "colors", "doc", "keymap", "lang", "macros", "print",
\ "spell", "tools", "tutor", ]
if !exists("g:ftplugin_dir")
let dir_path = ''
for dir in s:vim_dirs
let dir_path = fnamemodify(finddir(dir, expand("%:p:h").';'), ':p')
if !empty(dir_path)
break
endif
endfor
if !empty(dir_path)
let g:ftplugin_dir = fnamemodify(dir_path, ':h:h')
else
let g:ftplugin_dir = expand("%:p:h")
endif
endif
fun! FTPDEV_GetInstallDir()
" lcd to g:ftplugin_dir, we want path to be relative to this directory.
exe 'lcd '.fnameescape(g:ftplugin_dir)
" Check only vim files:
let files = map(filter(split(globpath('.', '**'), '\n'), 'fnamemodify(v:val, ":e") == "vim"'), 'v:val[2:]')
lcd -
" Good files to check are those in s:vim_dirs:
" i.e. in plugin, ftplugin, ... directories.
let gfiles = []
for file in files
if file =~ '^\%('.join(s:vim_dirs, '\|').'\)\>'
call add(gfiles, file)
endif
endfor
if len(gfiles)
let files = gfiles
endif
" ipath - install path
let ipath = ''
for file in files
" Find each file in 'runtimepath'
let ipath = globpath(&rtp, file)
if !empty(ipath)
break
endif
endfor
" Get the install path, count the directory level of file and strip that
" many directories from the corresponing ipath. This should be the install
" path.
let idx = 0
while file != "."
let idx += 1
let file = fnamemodify(file, ':h')
endwhile
let ipath = fnamemodify(ipath, repeat(':h', idx))
return ipath
endfun
if !exists("g:ftplugin_installdir")
let dir = FTPDEV_GetInstallDir()
if !empty(dir)
let g:ftplugin_installdir = dir
else
let g:ftplugin_installdir = split(&rtp, ',')[0]
endif
endif
if !exists("g:ftplugin_notinstall")
let g:ftplugin_notinstall=['Makefile', '\.tar\%(\.bz2\|\.gz\)\?$', '\.vba$', '.*\.vmb$']
endif
if exists("g:ftplugin_ResetPath") && g:ftplugin_ResetPath == 1
au! BufEnter *.vim exe "setl path=".substitute(g:ftplugin_dir.",".join(filter(split(globpath(g:ftplugin_dir, '**'), "\n"), "isdirectory(v:val)"), ","), " ", '\\\\\\\ ', 'g')
else
func! FTPDEV_AddPath()
let path=map(split(&path, ','), "fnamemodify(v:val, ':p')")
if index(path,fnamemodify(g:ftplugin_dir, ":p")) == -1 && g:ftplugin_dir != ""
let add = join(filter(split(globpath(g:ftplugin_dir, '**'), "\n"), "isdirectory(v:val)"), ",")
let add = substitute(add, " ", '\\\\\\\ ', 'g')
exe "setl path+=".add
endif
endfun
exe "au! BufEnter ".g:ftplugin_dir."* call FTPDEV_AddPath()"
exe "au! VimEnter * call FTPDEV_AddPath()"
endif
try
"1}}}
" Vim Settings:
" vim scripts written on windows works on Linux only if the EOF are dos or unix.
setl fileformats=unix,dos
" FUNCTIONS AND COMMANDS AND MAPS:
fun! PyGrep(what, files) " {{{1
python << EOF
import vim
import re
import json
what = vim.eval('a:what')
files = vim.eval('a:files')
if what == 'function':
pat = re.compile('\s*(?:silent!?)?\s*(?:fu|fun|func|funct|functio|function)!?\s')
elif what == 'command':
pat = re.compile('\s*(?:silent!?)?\s*(?:com|comm|comma|comman|command)!?\s')
elif what == 'variable':
pat = re.compile('\s*let\s')
elif what == 'maplhs':
pat = re.compile('\s*[cilnosvx!]?(?:nore)?(?:m|ma|map)\s' )
elif what == 'maprhs':
pat = re.compile('\s*[cilnosvx!]?(?:nore)?(?:m|ma|map)' )
loclist = []
for filename in files:
if vim.eval("bufloaded('%s')" % filename) == '1':
for buf in vim.buffers:
if buf.name == filename:
buf_nr = buf.number
break
else:
buf_nr = 0
with open(filename) as fo:
buf = fo.read().splitlines()
lnr = 0
buf_len = len(buf)
while lnr < buf_len:
lnr += 1
line = buf[lnr-1]
if line.startswith('py'):
# Skip over :python << EOF, :perl << EOF until EOF:
eof = re.match('(?:py|pyt|pyth|pytho|python|pe|per|perl)\s*<<\s*(\w+)',line).group(1)
while not line.startswith(eof):
lnr +=1
if lnr == buf_len:
break
line = buf[lnr-1]
if lnr == buf_len:
break
lnr += 1
line = buf[lnr-1]
match = re.match(pat, line)
if match:
loclist.append({
"bufnr" : buf_nr,
"filename" : filename,
"lnum" : lnr,
"text" : line
})
vim.command("let loclist=%s" % json.dumps(loclist))
EOF
return loclist
endfun
fun! Goto(what,bang,...) "{{{1
let pattern = (a:0 >= 1 ?
\ (a:1 =~ '.*\ze\s\+\d\+$' ? matchstr(a:1, '.*\ze\s\+\d\+$') : a:1)
\ : 'no_arg')
let line = (a:0 >= 1 ?
\ (a:1 =~ '.*\ze\s\+\d\+$' ? matchstr(a:1, '.*\s\+\zs\d\+$') : 0)
\ : 0)
" Go to a:2 lines below
let grep_flag = ( a:bang == "!" ? 'j' : '' )
if a:what == 'function'
if !has("python")
let pattern = '^\s*\%(silent!\=\)\=\s*fu\%[nction]!\=\s\+\%(s:\|<\csid>\|\f\+\#\)\=' . ( a:0 >= 1 ? pattern : '' )
else
let cpat = '^\s*\%(silent!\=\)\=\s*fu\%[nction]!\=\s\+\%(s:\|<\csid>\)\=\zs[^(]*'
let pattern = ( a:0 >= 1 ? pattern : '' )
endif
elseif a:what == 'command'
if !has("python")
let pattern = '^\s*\%(silent!\=\)\=\s*com\%[mand]!\=\%(\s*-buffer\s*\|\s*-nargs=[01*?+]\s*\|\s*-complete=\S\+\s*\|\s*-bang\s*\|\s*-range=\=[\d%]*\s*\|\s*-count=\d\+\s*\|\s*-bar\s*\|\s*-register\s*\)*\s*'.( a:0 >= 1 ? pattern : '' )
else
let cpat = '^\s*\%(silent!\=\)\=\s*com\%[mand]!\=\%(\s*-buffer\s*\|\s*-nargs=[01*?+]\s*\|\s*-complete=\S\+\s*\|\s*-bang\s*\|\s*-range=\=[\d%]*\s*\|\s*-count=\d\+\s*\|\s*-bar\s*\|\s*-register\s*\)*\s*\zs\S*'
let pattern = ( a:0 >= 1 ? pattern : '' )
endif
elseif a:what == 'variable'
if !has("python")
let pattern = '^\s*let\s\+' . ( a:0 >= 1 ? pattern : '' )
else
let cpat = '^\s*let\s\+\zs[^\s=]*'
let pattern = ( a:0 >= 1 ? pattern : '' )
endif
elseif a:what == 'maplhs'
let cpat = '^\s*[cilnosvx!]\?\%(nore\)\?m\%[ap]\>\s\+\%(\%(\|\|\|\)\s*\)*\(\)\?\zs\S*'
let pattern = ( a:0 >= 1 ? pattern : '' )
if !has("python")
let pattern = '^\s*[cilnosvx!]\?\%(nore\)\?m\%[ap]\>\s\+\%(\%(\|\|\|\)\s*\)*\(\)\?'.pattern
endif
elseif a:what == 'maprhs'
let cpat = '^\s*[cilnosvx!]\?\%(nore\)\?m\%[ap]\>\s\+\%(\%(\|\|\|\)\s*\)*\s\+\<\S\+\>\s\+\%(\)\?\zs.*'
let pattern = ( a:0 >= 1 ? pattern : '' )
if !has("python")
let pattern = '^\s*[cilnosvx!]\?\%(nore\)\?m\%[ap]\>\s\+\%(\%(\|\|\|\)\s*\)*\s\+\<\S\+\>\s\+\%(\)\?'.pattern
endif
else
let pattern = '^\s*[ci]\=\%(\%(nore\|un\)a\%[bbrev]\|ab\%[breviate]\)' . ( a:0 >= 1 ? pattern : '' )
endif
let files = map(split(globpath(g:ftplugin_dir, '**/*vim'), "\n"), "fnameescape(v:val)")
let filename = join(files)
if has("python")
call map(files, 'fnamemodify(v:val, ":p")')
if !exists("s:loclist")
let loclist = PyGrep(a:what, files)
else
let loclist = s:loclist
unlet s:loclist
endif
let nloclist = []
for loc in loclist
let loc['m_text'] = matchstr(loc['text'], cpat)
call add(nloclist, loc)
endfor
let loclist = nloclist
call filter(loclist, 'v:val["m_text"] =~ pattern')
call setloclist(0, loclist)
try
ll
let error = 0
catch /E42/
let error = 1
endtry
else
let error = 0
if !exists("s:loclist")
try
exe 'silent! lvimgrep /'.pattern.'/' . grep_flag . ' ' . filename
catch /E480:/
echoerr 'E480: No match: ' . pattern
let error = 1
endtry
endif
endif
if len(getloclist(".")) >= 2
llist
endif
if !error
exe 'silent! normal zv'
if a:what == 'function'
exe 'normal zt'
endif
endif
" Goto lines below
if line
exe "normal ".line."j"
endif
endfun
catch /E127/
endtry
" Completion is not working for a very simple reason: we are edditing a vim
" script which might not be sourced.
com! -buffer -bang -nargs=? -complete=customlist,FuncCompl Function :call Goto('function', , )
try
fun! FuncCompl(A,B,C) "{{{1
let files = map(split(globpath(g:ftplugin_dir, '**/*vim'), "\n"), "fnameescape(v:val)")
let filename = join(files)
if has("python")
let loclist = PyGrep('function', files)
let s:loclist = deepcopy(loclist)
else
let saved_loclist=getloclist(0)
try
exe 'lvimgrep /^\s*fun\%[ction]/gj '.filename
catch /E480:/
endtry
let loclist = getloclist(0)
let s:loclist = deepcopy(loclist)
call setloclist(0, saved_loclist)
endif
call map(loclist, 'get(v:val, "text", "")')
call map(loclist, 'matchstr(v:val, ''^\s*fun\%[ction]!\=\s*\(<\csid>\|\cs:\)\=\zs.*\ze\s*('')')
call filter(loclist, "v:val =~ a:A")
if !has("python")
call map(loclist, 'v:val.''\>''')
else
call map(loclist, '"^".v:val."\\>"')
endif
return loclist
endfun
catch /E127/
endtry
try
fun! CommandCompl(A,B,C) "{{{1
let files = map(split(globpath(g:ftplugin_dir, '**/*vim'), "\n"), "fnameescape(v:val)")
let filename = join(files)
if has("python")
let loclist = PyGrep('command', files)
let s:loclist = deepcopy(loclist)
else
let saved_loclist=getloclist(0)
try
exe 'lvimgrep /^\s*com\%[mand]/gj '.filename
catch /E480:/
endtry
let loclist = getloclist(0)
call setloclist(0, saved_loclist)
endif
call map(loclist, 'get(v:val, "text", "")')
call map(loclist, 'matchstr(v:val, ''^\s*com\%[mand]!\=\(\s*-buffer\s*\|\s*-nargs=[01*?+]\s*\|\s*-complete=\S\+\s*\|\s*-bang\s*\|\s*-range=\=[\d%]*\s*\|\s*-count=\d\+\s*\|\s*-bar\s*\|\s*-register\s*\)*\s*\zs\w*\>\ze'')')
if !has("python")
call map(loclist, 'v:val.''\>''')
else
call map(loclist, '"^".v:val."\\>"')
endif
return join(loclist, "\n")
endfun
catch /E127/
endtry
try
fun! MapRhsCompl(A,B,C) "{{{1
let files = map(split(globpath(g:ftplugin_dir, '**/*vim'), "\n"), "fnameescape(v:val)")
let filename = join(files)
if has("python")
let loclist = PyGrep('maprhs', files)
let s:loclist = deepcopy(loclist)
else
let saved_loclist=getloclist(0)
try
exe 'lvimgrep /^\s*[cilnosvx!]\=\%(nore\)\=m\%[ap]\>/gj '.filename
catch /E480:/
endtry
let loclist = getloclist(0)
call setloclist(0, saved_loclist)
endif
call map(loclist, 'get(v:val, "text", "")')
call map(loclist, 'matchstr(v:val, ''^\s*[cilnosvx!]\=\%(nore\)\=m\%[ap]\>\s\+\%(\%(\|\|\|\)\s*\)*\(\)\=\zs.*'')')
call map(loclist, 'matchstr(v:val, ''\S\+\s\+\%(\)\?\zs.*'')')
call filter(loclist, 'v:val =~ a:A')
call map(loclist, 'escape(v:val, "[]")')
return loclist
endfun
catch /E127/
endtry
try
fun! MapLhsCompl(A,B,C) "{{{1
let files = map(split(globpath(g:ftplugin_dir, '**/*vim'), "\n"), "fnameescape(v:val)")
let filename = join(files)
if has("python")
let loclist = PyGrep('maplhs', files)
let s:loclist = deepcopy(loclist)
else
let saved_loclist=getloclist(0)
try
exe 'lvimgrep /^\s*[cilnosvx!]\=\%(nore\)\=m\%[ap]\>/gj '.filename
catch /E480:/
endtry
let loclist = getloclist(0)
call setloclist(0, saved_loclist)
endif
call map(loclist, 'get(v:val, "text", "")')
call map(loclist, 'matchstr(v:val, ''^\s*[cilnosvx!]\=\%(nore\)\=m\%[ap]\>\s\+\%(\%(\|\|\|\)\s*\)*\(\)\=\zs\S*\ze'')')
call map(loclist, 'escape(v:val, "[]")')
return join(loclist, "\n")
endfun
catch /E127/
endtry "}}}1
com! -buffer -bang -nargs=? -complete=custom,CommandCompl Command :call Goto('command', , )
com! -buffer -bang -nargs=? Variable :call Goto('variable', , )
com! -buffer -bang -nargs=? -complete=custom,MapLhsCompl MapLhs :call Goto('maplhs', , )
com! -buffer -bang -nargs=? -complete=customlist,MapRhsCompl MapRhs :call Goto('maprhs', , )
" Search in current function
fun! SearchInFunction(pattern, flag) "{{{1
let [ cline, ccol ] = [ line("."), col(".") ]
if a:flag =~# 'b\|w' || &wrapscan
let begin = searchpairpos('^\s*fun\%[ction]\>', '', '^\s*endfun\%[ction]\>', 'bWn')
endif
if a:flag !~# 'b' || a:flag =~# 'w' || &wrapscan
let end = searchpairpos('^\s*fun\%[ction]\>', '', '^\s*endfun\%[ction]\>', 'Wn')
endif
if a:flag !~# 'b'
let pos = searchpos('\(' . a:pattern . ( a:pattern =~ '\\v' ? '|^\s*endfun%[ction]>)' : '\|^\s*endfun\%[ction]\>\)' ), 'W')
else
let pos = searchpos('\(' . a:pattern . ( a:pattern =~ '\\v' ? '|^\s*endfun%[ction]>)' : '\|^\s*endfun\%[ction]\>\)' ), 'Wb')
endif
let msg=""
if a:flag =~# 'w' || &wrapscan
if a:flag !~# 'b' && pos == end
let msg="search hit BOTTOM, continuing at TOP"
call cursor(begin)
call search('^\s*fun\%[ction]\zs', '')
let pos = searchpos('\(' . a:pattern . ( a:pattern =~ '\\v' ? '|^\s*endfun%[ction]>)' : '\|^\s*endfun\%[ction]\>\)' ), 'W')
elseif a:flag =~# 'b' && pos == begin
let msg="search hit TOP, continuing at BOTTOM"
call cursor(end)
let pos = searchpos('\(' . a:pattern . ( a:pattern =~ '\\v' ? '|^\s*endfun%[ction]>)' : '\|^\s*endfun\%[ction]\>\)' ), 'Wb')
endif
if pos == end || pos == begin
let msg="Pattern: " . a:pattern . " not found."
call cursor(cline, ccol)
endif
else
if pos == end || pos == begin
let msg="Pattern: " . a:pattern . " not found."
call cursor(cline, ccol)
endif
endif
if msg != ""
echohl WarningMsg
redraw
exe "echomsg '".msg."'"
echohl Normal
endif
endfun
fun! GetSearchArgs(Arg,flags) "{{{1
if a:Arg =~ '^\/'
let pattern = matchstr(a:Arg, '^\/\zs.*\ze\/')
let flag = matchstr(a:Arg, '\/.*\/\s*\zs['.a:flags.']*\ze\s*$')
elseif a:Arg =~ '^\i' && a:Arg !~ '^\w'
let pattern = matchstr(a:Arg, '^\(\i\)\zs.*\ze\1')
let flag = matchstr(a:Arg, '\(\i\).*\1\s*\zs['.a:flags.']*\ze\s*$')
else
let pattern = matchstr(a:Arg, '^\zs\S*\ze')
let flag = matchstr(a:Arg, '^\S*\s*\zs['.a:flags.']*\ze\s*$')
endif
return [ pattern, flag ]
endfun
fun! Search(Arg) "{{{1
let [ pattern, flag ] = GetSearchArgs(a:Arg, 'bcenpswW')
let @/ = pattern
call histadd("search", pattern)
if pattern == ""
echohl ErrorMsg
redraw
echomsg "Enclose the pattern with /.../"
echohl Normal
return
endif
call SearchInFunction(pattern, flag)
endfun "}}}1
com! -buffer -nargs=* S :call Search() | let v:searchforward = ( GetSearchArgs(, 'bcenpswW')[1] =~# 'b' ? 0 : 1 )
nmap :call SearchInFunction(@/,'')
nmap :call SearchInFunction(@/,'b')
nmap gn :call SearchInFunction(@/,( v:searchforward ? '' : 'b'))
nmap gN :call SearchInFunction(@/,(!v:searchforward ? '' : 'b'))
fun! PluginDir(...) "{{{1
if a:0 == 0
echo g:ftplugin_dir
else
let g:ftplugin_dir=a:1
endif
endfun "}}}1
com! -nargs=? -complete=file PluginDir :call PluginDir()
try
fun! Pgrep(vimgrep_arg) "{{{1
let filename = join(filter(map(split(globpath(g:ftplugin_dir, '**/*'), "\n"), "fnameescape(v:val)"),"!isdirectory(v:val)"))
try
execute "lvimgrep " . a:vimgrep_arg . " " . filename
catch /E480:/
echohl ErrorMsg
redraw
echo "E480: No match: ".a:vimgrep_arg
echohl Normal
endtry
endfun
catch /E127:/
endtry
com! -nargs=1 Pgrep :call Pgrep()
fun! ListFunctions(bang) "{{{1
try
lvimgrep /^\s*fun\%[ction]/gj %
catch /E480:/
echohl ErrorMsg
redraw
echo "E480: No match: ".a:vimgrep_arg
echohl Normal
endtry
let loclist = getloclist(0)
call map(loclist, 'get(v:val, "text", "")')
call map(loclist, 'matchstr(v:val, ''^\s*fun\%[ction]!\=\s*\zs.*\ze\s*('')')
if a:bang == "!"
call sort(loclist)
endif
return join(PrintTable(loclist, 2), "\n")
endfun
com! -bang ListFunctions :echo ListFunctions()
fun! ListCommands(bang) "{{{1
try
lvimgrep /^\s*com\%[mmand]/gj %
catch /E480:/
echohl ErrorMsg
redraw
echo "E480: No match: ".a:vimgrep_arg
echohl Normal
endtry
let loclist = getloclist(0)
call map(loclist, 'get(v:val, "text", "")')
call map(loclist, 'substitute(v:val, ''^\s*'', '''', '''')')
if a:bang == "!"
call sort(loclist)
endif
let cmds = []
for raw_cmd in loclist
let pattern = '^\s*com\%[mand]!\=\%(\s*-buffer\s*\|\s*-nargs=[01*?+]\s*\|\s*-complete=\S\+\s*\|\s*-bang\s*\|\s*-range=\=[\d%]*\s*\|\s*-count=\d\+\s*\|\s*-bar\s*\|\s*-register\s*\)*\s*\zs\w*\ze'
call add(cmds, matchstr(raw_cmd, pattern))
endfor
return join(cmds, "\n")
endfun
com! -bang ListCommands :echo ListCommands()
nmap ]# :call searchpair('^[^"]*\<\zsif\>', '^[^"]*\<\zselse\%(if\)\=\>', '^[^"]*\<\zsendif\>')
nmap [# :call searchpair('^[^"]*\<\zsif\>', '^[^"]*\<\zselse\%(if\)\=\>', '^[^"]*\<\zsendif\>', 'b')
fun! Install(bang) "{{{1
if g:ftplugin_dir = g:ftplugin_installdir
return
endif
exe 'lcd '.fnameescape(g:ftplugin_dir)
if a:bang == ""
" Note: this returns non zero list if the buffer is loaded
" ':h getbufline()'
let file_name = expand('%:.')
let file = getbufline('%', '1', '$')
let install_path = substitute(g:ftplugin_installdir, '\/\s*$', '', '').'/'.file_name
call writefile(file, install_path)
echom 'File installed to: "'.install_path.'".'
else
let install_path = substitute(g:ftplugin_installdir, '\/\s*$', '', '')
let file_list = filter(split(globpath(g:ftplugin_dir, '**'), "\n"), "!isdirectory(v:val) && !Match(g:ftplugin_notinstall, fnamemodify(v:val, ':.'))")
for file in file_list
if bufloaded(file)
let file_list = getbufline(file, '1', '$')
else
let file_list = readfile(file)
endif
let file_name = fnamemodify(file, ':.')
echo 'Installing: "'.file_name.'" to "'.install_path.'/'.file_name.'"'
try
call writefile(file_list, install_path.'/'.file_name)
catch /E482/
let dir = fnamemodify(install_path.'/'.file_name, ':h')
echohl WarningMsg
echom 'Making directory "'.dir.'"'
echohl None
call mkdir(dir, 'p')
call writefile(file_list, install_path.'/'.file_name)
endtry
endfor
endif
lcd -
endfun
fun! Match(pattern_list, element) "{{{2
let match = 0
for pattern in a:pattern_list
if a:element =~ pattern || a:element == pattern
let match = 1
break
endif
endfor
return match
endfun "}}}2
com! -bang Install :call Install()
fun! Evaluate(mode) "{{{1
let saved_pos = getpos(".")
let saved_reg = @e
if a:mode == "n"
if strpart(getline(line(".")), col(".")-1) =~ '[bg]:'
let end_pos = searchpos('[bg]:\w*\zs\>', 'cW')
else
let end_pos = searchpos('\ze\>', 'cW')
endif
let end_pos[1] -= 1
call cursor(saved_pos[1], saved_pos[2])
normal! v
call cursor(end_pos)
normal! "ey
let expr = @e
elseif a:mode ==? 'v'
let beg_pos = getpos("'<")
let end_pos = getpos("'>")
call cursor(beg_pos[1], beg_pos[2])
normal! v
call cursor(end_pos[1], end_pos[2])
normal! "ey
let expr= @e
endif
let @e = saved_reg
try
echo expr."=".string({expr})
catch /E121:/
echomsg "variable ".expr." undefined"
endtry
endfun
com! -buffer -range Eval :call Evaluate(mode())
"}}}1
" Print table tools:
fun! FormatListinColumns(list,s) "{{{1
" take a list and reformat it into many columns
" a:s is the number of spaces between columns
" for example of usage see atplib#PrintTable
let max_len=max(map(copy(a:list), 'len(v:val)'))
" let g:list=a:list
" let g:max_len=max_len+a:s
let new_list=[]
let k=&l:columns/(max_len+a:s)
" let g:k=k
let len=len(a:list)
let column_len=len/k
for i in range(0, column_len)
let entry=[]
for j in range(0,k)
call add(entry, get(a:list, i+j*(column_len+1), ""))
endfor
call add(new_list,entry)
endfor
return new_list
endfun
fun! PrintTable(list, spaces) "{{{1
" Take list format it with atplib#FormatListinColumns and then with
" atplib#Table (which makes columns of equal width)
" a:list - list to print
" a:spaces - nr of spaces between columns
let list = atplib#FormatListinColumns(a:list, a:spaces)
let nr_of_columns = max(map(copy(list), 'len(v:val)'))
let spaces_list = ( nr_of_columns == 1 ? [0] : map(range(1,nr_of_columns-1), 'a:spaces') )
let g:spaces_list = spaces_list
let g:nr_of_columns=nr_of_columns
return atplib#Table(list, spaces_list)
endfun
fun! LocalDeclaration(variable) "{{{1
python << EOF
import vim
import re
var = vim.eval('a:variable')
buf = vim.current.buffer
idx = vim.current.window.cursor[0]-1
col = vim.current.window.cursor[1]
var_pat = re.compile(r'^(\s*let\s*)%s\b' % var)
endfun_pat = re.compile(r'^\s*(?:endf|endfu|endfun|endfunc|endfunct|endfuncti|endfunctio|endfunction)\b')
fun_pat = re.compile(r'^\s*(?:fu|fun|func|funct|functi|functio|function)\b')
def jump(idx): # {{{2
global buf
while idx >= 0:
idx -= 1
line = buf[idx]
if re.match(fun_pat, line):
idx = -1
return (-1, -1)
if re.match(endfun_pat, line):
idx -= 1
line = buf[idx]
m = re.match(fun_pat, line)
while not m and idx >= 0:
idx -= 1
line = buf[idx]
m = re.match(fun_pat, line)
if re.match(var_pat, line):
col = line.index(var)
return (idx, col)
else:
return (-1, -1) # }}}2
(n_idx, n_col) = jump(idx)
while n_idx != -1:
(idx, col) = (n_idx, n_col)
(n_idx, n_col) = jump(idx)
vim.command("let lnr=%s" % (idx+1))
vim.command("let col=%s" % (col+1))
EOF
let g:lnr = lnr
let g:col = col
if lnr
call setpos(".", [0, lnr, col, 0])
endif
endfun
if has("python")
nnoremap gd :call LocalDeclaration(expand(""))
endif
doc/ftpdev.txt [[[1
236
*ftpdev.txt* For Vim version 7 Last change: 27 IX 2012
A help file for {F}ile {T}ype {P}lugin {DEV}elopemnt (ver. 5.6)
by Marcin Szamotulski
mszamot [AT] gmail [DOT] com
----------------------------------------
This file type plugin provides some additional functions and commands which
help writing and vim plugins. Especially big ones. Here is the list of
available commands and maps with some explanation:
======
NEWS *ftpdev-news*
>
version 6
<
The core functionality of |ftpdev-:Function|, |ftpdev-:Command|,
|ftpdev-:MapLhs| and |ftpdev-:MapRhs| was rewritten in Python. If your Vim
has Python interface (:echo has("+python")) then these commands will be much
faster.
For |ftpdev-:MapLhs| and |ftpdev-:MapRhs| if your vim is compiled with Python
interface then the pattern matches can use '^' to match the begining of the
lhs or rhs of the map (the '' is not included in the lhs/rhs).
|g:ftplugin_dir| and |g:ftplugin_installdir| should work out of the box.
|g:ftplugin_installdir| will work if one file of the project is already
installed in the 'runtimepath' (and it is distinguished on under
'runtimepath').
|ftpdev-:Install| will print where it puts files and will make missing
directories. It will exit silently if both |g:ftplugin_dir| and
|g:ftplugin_installdir| are set to the same value. This is useful when you
set |ftpdev-:Install| through an autocommand and then edit files under the
'runtimepath'.
You can folow development of this plugin on GitHub:
https://github.com/coot/vim_ftpdev
NEW FEATURE: ~
gd - jump to local declaration: it finds the first declaration of the
variable under the cursor. The declaration is search in the current function
scope and outside all nested function definitions. Thus when you are outside
a function whole script is searched backward from the cursor position,
omitting all functions.
>
version 5.4
<
gn and gN changed into ]# and [# what is more in a vim way. See |ftpdev-]#|
and |ftpdev-[#|.
:Edit, :Split, ... commands removed. Instead the |path| option is set so you
can use |:find|, |:sfind|, ... commands.
======
CONFIGURATION *ftpdev-configure*
*ftpdev-g:ftplugin_dir*
There is one variable which needs to be configured >
g:ftplugin_dir
< This is the directory which will be searched for files. If you set this to
your ~/.vim/ftplugin directory where you have lots of scripts this plugin
might be a bit slow. Each plugin that I develop has its own directory (you
probably use some version control system as I do) then this variable is set
in my vimrc file via an autocommand: >
au BufEnter /plugin_dev_dir/* let g:ftplugin=
<
*ftpdev-:PluginDir*
:PluginDir {dir}
This sets value of the variable |ftpdev-g:ftplugin_dir| to {dir}. It
has dir type completion.
*ftpdev-g:ftplugin_ResetPath*
|g:ftplugin_ResetPath| is set to 1 it will set |path|=g:ftplugin_dir, if not
set or equal 0 it will add g:ftplugin_dir to |path| (only if the path already
does not contain it).
This makes the use of |edit|, |split|, |vsplit|, |diffsplit| a lot nicer.
*ftpdev-g:ftplugin_notinstall*
g:ftplugin_notinstall=['Makefile', '.*\.tar\.\%(bz2\|gz\)$', '.*\.vba$']
This is list of patterns or file names relative to |g:ftplugin_dir|
which will not be installed by the |ftpdev-:Install| command.
*ftpdev-g:ftplugin_installdir*
g:ftplugin_installdir=split(&runtimepath,",")[0]
Directory name where to |ftpdev-:Install| files.
TIP ~
It might be good idea to put in your vimrc file: >
au BufEnter {path_to_project_dir}/* source ~/.vim/ftplugin/vim_ftdev.vim
or 's:' even if the function name
has it.
The bang is present |lvimgrep| is supplied with the j switch, i.e.
the location list will be filled with matches without jumping to the
first match.
There is a completion for {fname}s.
If [line] is non zero, go [lines] below. This is especially useful
when you are debugging a script and you got en error in function
{fname} at line [line].
:ListFunctions *ftpdev-:ListFunctions*
List functions in defined in the current buffer.
:Command[!] {cname} [line] *ftpdev-:Command*
This finds command which name matches {fname} vim pattern under the
|ftpdev-g:ftplugin_dir| {cname} has the same syntax as {fname}. The
bang works as in |ftpdev-:Function|
There is a completion for {cname}s.
The [line] argument is the same as in |ftpdev-:Function|.
:ListCommands *ftpdev-:ListCommands*
List commands in defined in the current buffer.
:Variable[!] {vname} [line] *ftpdev-:Variable*
This finds variable definition matching {vname}. {vname} has to contain
the g: b: s: t: prefix if the variable has it. The bang works as in
|ftpdev-:Function|
The [line] argument is the same as in |ftpdev-:Function|.
:MapLhs[!] {maplhs} [line] *ftpdev-:MapLhs*
This finds maps which lhs matches {maplhs} vim pattern. The bang works as in
|ftpdev-:Function|
The [line] argument is the same as in |ftpdev-:Function|.
If Vim has Python interface then you can use '^' in {maplhs} pattern
to match the start of the map name (' is not included into the
map name). If Vim has not Python interface the {maplhs} always matches
at the begining, thus if you want to match anywhere use '.*' at the
begining of {maplhs}
:MapRhs[!] {maprhs} [line] *ftpdev-:MapRhs*
This finds maps which rhs matches {maprhs} vim pattern. The bang works as in
|ftpdev-:Function|
The [line] argument is the same as in |ftpdev-:Function|.
{maprhs} works in the same way as {maplhs} argument of |atp-:MapLhs|
command (read there about the difference when Vim has Python
interface).
Note: [todo] some completions might not work (especially complex right
hand side maps, Goto function should check for == in this case).
*ftpdev-]#*
*ftpdev-[#*
*ftpdev-:S*
:S /{pattern}/
map ]#
map [#
This function make a search of {pattern} in the current function (it
can wrap around the end of function. The argument {pattern} is a vim
pattern passed to |vimgrep|. Mixing |\v| and |\m| in a pattern is not
supported.
The pattern is added to search history and copied to the @/ register,
thus you can re use it with |n| and |N| commands to search globally or
gn and gN to search in the scope of current function.
Note that you can first search with the vim standard |/| or |?| and
then use |ftpdev-gn| and |ftpdev-gN|.
*ftpdev-:Eval*
:Eval
Probably in your plugin there are debug |global-variables|. Then
position the cursor on the begining of this variable :Eval will show
you its value (if its defined). You can also use visual mode to select
an expression, but the limitation is that every variable must be
defined (thus it must be a global variable).
*ftpdev-:Pgrep*
:Pgrep /{pattern}/[j][g]
This makes |lvimgrep| in all files under |ftpdev-g:ftplugin_dir|. The
argument syntax is the same as for |lvimgrep|.
This note is just for completeness:
Vim has its own vim.vim ftplugin which defines:
]] (next beginning of a function),
][ (next end of a function),
[[ (previous beginning of a function),
[] (previous end of a function).
nmap Gn *ftpdev-Gn*
nmap GN *ftpdev-GN*
Go to next/previous if/else/elseif/endif pair (this, unlike |n| and |N|
vim maps, doesn't depend on v:searchforward). These maps are defined
by: >
nmap Gn :call searchpair('^[^"]*\<\zsif\>', '^[^"]*\<\zselse\%(if\)\=\>', '^[^"]*\<\zsendif\>')
nmap GN :call searchpair('^[^"]*\<\zsif\>', '^[^"]*\<\zselse\%(if\)\=\>', '^[^"]*\<\zsendif\>', 'b')
<
You can also use the |matchit| plugin. Just configure |b:match_words|
variable.
INSTALLING PLUGIN TO THE RUNTIME PATH ~
:Install[!] *ftpdev-:Install*
Without bang "!": it will copy the current buffer to the location
under |g:ftplugin_installdir| be default it is first path that appear
in 'runtimepath' vim option. With bang "!": it will install all the
files found under |g:ftplugin_dir| except the files in the
(file/pattern) list |g:ftplugin_notinstall|.
You can use this command in an autocommand for certain files: >
au BufWritePost :Install
<
If a directory tree is missing |ftpdev-:Install| will make it on the
fly.
If |g:ftplugin_dir| and |g:ftplugin_installdir| are equal the command
silently returns. This is useful when you set :Install through an
autocommand and edit files under the 'runtimepath'.
Happy vimming :)
vim:tw=75:ts=8:ft=help:norl:ft=help