hi, allI guess I should really write either a TIP or a Plugin for this.After I have modified source files, I need to update cscope.out file by run "cscope -b -R" on shell then do ":cs reset" in vim. It is so inconvenience.I want vim do it for me. how to reach this aim?
Below contains a bunch of stuff:
1. Couple of functions to detect if a cscope.out is already active, what options it was started with and determine how to refresh it (ie. cscope -b).
2. A pile of mappings to make my life a bit easier, since cscope is designed for C, but I use it for SQL and Perl and others.
3. Some commands, the important one being - CSRefresh, it will stop cscope, re-run cscope -b and restart cscope with the same options.
4. Some options you can set from your vimrc to control it's behaviour.
5. An autocmd to detect if there is a cscope.out and automatically run :cs add
In a nutshell, on Windows I do this:
dir /s/b *.sql > cscope.files (create a file with all the files I want indexed)
cscope -b (create the cscope database)
Open Vim:
Edit a file
Run :cs show, you should see cscope active.
Update your source and :w
Run :CSRefresh
I don't want to run CSRefresh all the time (for example in a autocmd on saving) since there could be lots of files and unless you are adding new methods or changing signatures, it is unnecessary.
I wrote the following and keep it in my .vimrc
" CScope support for VIM:/*{{{*/
if has("cscope")
" See below about creating the cscope.files file.
" This autocmd will remove the entries from within
" a file that cscope cannot deal with, or does not
" make sense indexing.
autocmd BufReadPost cscope.files
\ let before_lines = line('$') |
\ silent! exec 'silent! g/\(cscope\|\.\(gif\|bmp\|png\|jpg\|swp\)\)/d' |
\ silent! exec 'silent! v/\./d' |
\ let before_lines = before_lines - line('$') |
\ if before_lines > 0 |
\ call confirm( 'Removed ' . before_lines . ' lines from file. ' .
\ 'These were any of the following: ' .
\ "\n".'- image and swap files ' .
\ "\n".'- directories ' .
\ "\n".'- any cscope files.' .
\ "\n\n".'Press u to recover these lines.'
\ ) |
\ endif
" Most often I find I need to recursively look at data
" You cannot use (reports an error opening subdirs):
" cscope -R *.sql
" You must use:
" cscope -R
" But that only gets C/CPP files.
" I have to do this:
" find -name *.sql > cscope.files
" or
" dir /s/b *.pl > cscope.files
" dir /s/b *.pm >> cscope.files
" cscope -b (create the cscope database)
" cscope -C (queries this with case insensitivity)
"
" To open the same options in Vim:
" cs add cscope.out . -C (for case insensitivity)
"
" For help on cscope and Vim:
" :cs
" :h cs
" See below, CSReloadDB, which rebuilds the cscope database
" if cscope.files is available.
let g:cscope_rebuild_on_refresh = 1
let g:cscope_options_default = '-C'
let &cscopeprg = expand('$VIM\Tools\cscope.exe')
" If 'csto' is set to zero, cscope database(s) are searched first,
" followed " by tag file(s) if cscope did not return any matches.
set cscopetagorder=0
" set cscopetag
set nocscopeverbose
" determines how many components of a file's path to display
set cscopepathcomp=3
" Use the quickfix window for the cscope query
set cscopequickfix=s-,c-,d-,i-,t-,e-
" add any database in current directory
if filereadable("cscope.out")
" cscope -C (queries this with case insensitivity)
exec 'cs add '.getcwd().'/cscope.out "" '.g:cscope_options_default
" else add database pointed to by environment
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set csverb
" Find this C symbol (0==s)
nnoremap g<C-\> :silent! cs find 0 <C-R>=expand("<cword>")<CR><CR>:cwindow<CR>
vnoremap <silent> g<c-\> :<C-U>
\:let old_reg=getreg('"')<bar>
\:let old_regmode=getregtype('"')<cr>
\gvy
\:silent! cs find s <C-R>=@"<cr><cr>
\:call setreg('"', old_reg, old_regmode)<cr>:cwindow<CR>
" Find functions call this word (3==c)
nnoremap g<C-]> :silent! cs find c <C-R>=expand("<cword>")<CR><CR>:cwindow<CR>
vnoremap <silent> g<c-]> :<C-U>
\:let old_reg=getreg('"')<bar>
\:let old_regmode=getregtype('"')<cr>
\gvy
\:silent! cs find c <C-R>=@"<cr><cr>
\:call setreg('"', old_reg, old_regmode)<cr>:cwindow<CR>
" Find this text string (4==t)
nnoremap g<C-[> :silent! cs find t <C-R>=expand("<cword>")<CR><CR>:cwindow<CR>
vnoremap <silent> g<c-[> :<C-U>
\:let old_reg=getreg('"')<bar>
\:let old_regmode=getregtype('"')<cr>
\gvy
\:silent! cs find t <C-R>=@"<cr><cr>
\:call setreg('"', old_reg, old_regmode)<cr>:cwindow<CR>
" Find this definition (1==g)
nnoremap g<C-g> :silent! cs find g <C-R>=expand("<cword>")<CR><CR>:cwindow<CR>
vnoremap <silent> g<c-g> :<C-U>
\:let old_reg=getreg('"')<bar>
\:let old_regmode=getregtype('"')<cr>
\gvy
\:silent! cs find g <C-R>=@"<cr><cr>
\:call setreg('"', old_reg, old_regmode)<cr>:cwindow<CR>
" Find this text string (4==t)
" Use input() instead of inputdialog() so you can use <C-R> more
" effectively when pasting in text to search for
" nnoremap g/ :silent! cs find t <C-R>=input("Enter search string:", expand("<cword>"))<CR><CR>:cwindow<CR>
nnoremap g/ :let find_text = input("Enter search string:", expand("<cword>")) <bar>
\ :if find_text != '' \|
\ exec('silent! cs find t '.find_text) \|
\ exec('cwindow') \|
\ endif<CR>
function! CSRefreshAllConns()
" Check if there are any cscope connections
let saveA = @a
redir @a
silent! exec 'cs show'
redir END
let cs_conns = @a
let @a = saveA
if cs_conns !~? 'no cscope connections'
let match_regex = '\(\d\+\s\+\d\+\s\+\S\+\s\+\S\+\)'
let index = match(cs_conns, match_regex)
while index > -1
" Retrieve the name of option
let cs_conn_num = matchstr(cs_conns, '^\d\+', index)
if strlen(cs_conn_num) > 0
let index = (index + strlen(cs_conn_num))
let cs_db_name = matchstr(cs_conns,
\ '\s\+\d\+\s\+\zs\S\+',
\ index
\ )
let index = index + strlen(cs_conn_num)
\ + strlen(cs_db_name)
let cs_db_path = matchstr(cs_conns,
\ '\s\+\zs\S\+',
\ index
\ )
if cs_db_path =~ "<none>" || cs_db_path =~ '""'
let cs_db_path = ''
endif
let index = index + strlen(cs_conn_num)
\ + strlen(cs_db_name)
\ + strlen(cs_db_path)
\ + 1
call CSReloadDB( cs_conn_num, cs_db_name, cs_db_path,
\ g:cscope_options_default )
endif
let index = index + 1
let index = match(cs_conns, match_regex, index)
endwhile
else
if filereadable("cscope.out")
" cscope -C (queries this with case insensitivity)
exec 'cs add '.getcwd().'/cscope.out "" '.g:cscope_options_default
endif
endif
endfunction
function! CSReloadDB( cs_conn_num, cs_db_name, cs_db_path, cs_options )
exec 'cs kill ' . a:cs_conn_num
let cs_db_fullpath = fnamemodify(a:cs_db_name,":p")
let root_file = a:cs_db_path
if root_file == ""
let root_file = fnamemodify(a:cs_db_name,":p")
endif
" If no pre_path was specified (ie . = current directory)
" Then assume the directory has not changed since cscope was started
" let cs_db_path = substitute(root_file, '^\.$',
" \ '\=expand("%:p:h")', '')
" if has('win32')
" let cs_db_fullpath = substitute(cs_db_path, '\S\+\zs\\\?$', '&\', '') .
" \ a:cs_db_name
" else
" let cs_db_fullpath = substitute(cs_db_path, '\S\+\zs\\\?$', '&/', '') .
" \ a:cs_db_name
" endif
if filereadable(cs_db_fullpath)
if g:cscope_rebuild_on_refresh == 1
call CSRebuildDB( cs_db_fullpath, a:cs_options )
endif
let cs_cmd = 'cs add '.
\ cs_db_fullpath.' '.
\ fnamemodify(cs_db_fullpath, ":p:h").' '.
\ a:cs_options
exec cs_cmd
else
echohl WarningMsg
echomsg 'CSReloadDB - Cannot find: '.cs_db_fullpath
echohl None
endif
endfunction
function! CSRebuildDB( cs_db_fullpath, cs_options )
let cscope_files = fnamemodify(a:cs_db_fullpath,":p:h").'\cscope.files'
if filereadable(cscope_files)
let cs_cmd = 'cscope.exe -b '.
\ '-f '.a:cs_db_fullpath.
\ ' -i '.cscope_files
let cs_out = system(cs_cmd)
if v:shell_error
echo cs_out
else
echo 'Rebuilt cscope database: ' . a:cs_db_fullpath
endif
endif
endfunction
command! CSRefresh :call CSRefreshAllConns()
endif
" /*}}}*/
If you have comments (good or bad) or think this would be worth a plugin, let me know.
Please post these suggests to the list.
Once cscope is active, you can also use Dr. Chips plugin to make using it easier:
cecscope : command and menu driven cscope interface
http://www.vim.org/scripts/script.php?script_id=1453
HTH,
Dave
No comments:
Post a Comment