From f046d55f8c9271ea13e61340858df9e11b0e6657 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Sat, 16 May 2015 16:02:43 +0800 Subject: [PATCH 01/19] add interface to control search case sensitivity. --- plugin/cscope.vim | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index cdf923d..9bf55ba 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -19,6 +19,10 @@ if !exists('g:cscope_split_threshold') let g:cscope_split_threshold = 10000 endif +if !exists('g:cscope_search_case_insensitive') + let g:cscope_search_case_insensitive = 0 +endif + function! ToggleLocationList() let l:own = winnr() lw @@ -143,7 +147,11 @@ function! s:_CreateDB(dir, init) echohl WarningMsg | echo "Failed to create cscope database for ".a:dir.", please check if " | echohl None else let s:dbs[a:dir]['dirty'] = 0 - exec 'cs add '.cscope_db + if g:cscope_search_case_insensitive == 1 + exec 'cs add '.cscope_db.' '.a:dir.' -C' + else + exec 'cs add '.cscope_db + endif endif endfunction @@ -177,10 +185,21 @@ endfunction function! s:LoadDB(dir) cs kill -1 - exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'.db' - if filereadable(s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db') - exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db' + + if g:cscope_search_case_insensitive == 1 + exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'.db '.a:dir.' -C' + + if filereadable(s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db') + exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db '.a:dir.' -C' + endif + else + exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'.db' + + if filereadable(s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db') + exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db' + endif endif + let s:dbs[a:dir]['loadtimes'] = s:dbs[a:dir]['loadtimes']+1 call FlushIndex() endfunction From fa9d8f886d6a14addc4bcb91dfd86f66b863f496 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 18 May 2015 13:28:26 +0800 Subject: [PATCH 02/19] add horizontal and vertical window split function. --- plugin/cscope.vim | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 9bf55ba..2b34bfe 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -302,7 +302,9 @@ function! s:preloadDB() endfor endfunction -function! CscopeFind(action, word) +function! CscopeFind(action, word, ...) + " the a:1 is used for window spliting control. + " === let dirtyDirs = [] for d in keys(s:dbs) if s:dbs[d]['dirty'] == 1 @@ -314,9 +316,21 @@ function! CscopeFind(action, word) endif call AutoloadDB(expand('%:p:h')) try - exe ':lcs f '.a:action.' '.a:word - if g:cscope_open_location == 1 - lw + if a:0 == 0 + exe ':lcs f '.a:action.' '.a:word + if g:cscope_open_location == 1 + lw + endif + elseif a:0 == 1 && a:1 == 'horizontal' + exe ':scs f '.a:action.' '.a:word + if g:cscope_open_location == 1 + cw + endif + elseif a:0 == 1 && a:1 == 'vertical' + exe ':vert scs f '.a:action.' '.a:word + if g:cscope_open_location == 1 + cw + endif endif catch echohl WarningMsg | echo 'Can not find '.a:word.' with querytype as '.a:action.'.' | echohl None From 4faecb78f81298017bce3382c0c57589464a26bb Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 18 May 2015 13:49:32 +0800 Subject: [PATCH 03/19] change `Location` window to `Quickfix` window, for 1. It's more easy to navigate search result with shortcuts with quickfix window. 2. Location windows can be used to store file-specific search result, and quickfix is more suitable for global search result, as cscope search result is a global result. --- plugin/cscope.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 2b34bfe..68e380a 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -317,9 +317,9 @@ function! CscopeFind(action, word, ...) call AutoloadDB(expand('%:p:h')) try if a:0 == 0 - exe ':lcs f '.a:action.' '.a:word + exe ':cs f '.a:action.' '.a:word if g:cscope_open_location == 1 - lw + cw endif elseif a:0 == 1 && a:1 == 'horizontal' exe ':scs f '.a:action.' '.a:word From 525ec09ebb519e2360155a00bcc95d03b32453aa Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 18 May 2015 17:50:45 +0800 Subject: [PATCH 04/19] simplified if condition. --- plugin/cscope.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 68e380a..e926bb5 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -321,12 +321,12 @@ function! CscopeFind(action, word, ...) if g:cscope_open_location == 1 cw endif - elseif a:0 == 1 && a:1 == 'horizontal' + elseif a:1 == 'horizontal' exe ':scs f '.a:action.' '.a:word if g:cscope_open_location == 1 cw endif - elseif a:0 == 1 && a:1 == 'vertical' + elseif a:1 == 'vertical' exe ':vert scs f '.a:action.' '.a:word if g:cscope_open_location == 1 cw From 9bf88ef6480347e09d3a68d647f00fe3ac2e7cdf Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 18 May 2015 19:47:47 +0800 Subject: [PATCH 05/19] fixed if condition argument out of range bug. --- plugin/cscope.vim | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index e926bb5..ba1e58a 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -318,19 +318,14 @@ function! CscopeFind(action, word, ...) try if a:0 == 0 exe ':cs f '.a:action.' '.a:word - if g:cscope_open_location == 1 - cw - endif - elseif a:1 == 'horizontal' + elseif a:0 == 1 && a:1 == 'horizontal' exe ':scs f '.a:action.' '.a:word - if g:cscope_open_location == 1 - cw - endif - elseif a:1 == 'vertical' + elseif a:0 == 1 && a:1 == 'vertical' exe ':vert scs f '.a:action.' '.a:word - if g:cscope_open_location == 1 - cw - endif + endif + + if g:cscope_open_location == 1 + cw endif catch echohl WarningMsg | echo 'Can not find '.a:word.' with querytype as '.a:action.'.' | echohl None From ea33f1b7f6d5bec8dfb0bc62ca47c5d76adce76d Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Tue, 19 May 2015 10:14:59 +0800 Subject: [PATCH 06/19] when in CscopeFindInteractive mode, if canceled, there will be an extra `` be inserted to the position where cursor was, this is obviously not desired as it will break the code easily even without notice!! --- plugin/cscope.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index ba1e58a..a92f04e 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -341,7 +341,7 @@ function! CscopeFindInteractive(pat) elseif len(qt) > 0 call CscopeFind(qt, a:pat) endif - call feedkeys("\") + " call feedkeys("\") endfunction function! s:onChange() From 09e9f12b598f446b35a62b84f2b726cf4649d500 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Wed, 20 May 2015 08:17:54 +0800 Subject: [PATCH 07/19] improved condition logical. --- plugin/cscope.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index a92f04e..2ecb679 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -318,9 +318,9 @@ function! CscopeFind(action, word, ...) try if a:0 == 0 exe ':cs f '.a:action.' '.a:word - elseif a:0 == 1 && a:1 == 'horizontal' + elseif a:0 >= 1 && a:1 == 'horizontal' exe ':scs f '.a:action.' '.a:word - elseif a:0 == 1 && a:1 == 'vertical' + elseif a:0 >= 1 && a:1 == 'vertical' exe ':vert scs f '.a:action.' '.a:word endif From a795fa1556b19d3bb58a8c2fb49444cb986d2a6f Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Thu, 21 May 2015 12:23:32 +0800 Subject: [PATCH 08/19] rename CscopeUpdateAllDB() and add CscopeUpdateCurrentDB() --- plugin/cscope.vim | 98 ++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 2ecb679..154cd61 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -2,27 +2,6 @@ " Copyright: Copyright (C) 2012-2015 Brook Hong " License: The MIT License " - -if !exists('g:cscope_silent') - let g:cscope_silent = 0 -endif - -if !exists('g:cscope_auto_update') - let g:cscope_auto_update = 1 -endif - -if !exists('g:cscope_open_location') - let g:cscope_open_location = 1 -endif - -if !exists('g:cscope_split_threshold') - let g:cscope_split_threshold = 10000 -endif - -if !exists('g:cscope_search_case_insensitive') - let g:cscope_search_case_insensitive = 0 -endif - function! ToggleLocationList() let l:own = winnr() lw @@ -38,23 +17,6 @@ function! ToggleLocationList() endif endfunction -if !exists('g:cscope_cmd') - if executable('cscope') - let g:cscope_cmd = 'cscope' - else - echo 'cscope: command not found' - finish - endif -endif - -if !exists('g:cscope_interested_files') - let files = readfile(expand(":p:h")."/interested.txt") - let g:cscope_interested_files = join(map(files, 'v:val."$"'), '\|') -endif - -let s:cscope_vim_dir = substitute($HOME,'\\','/','g')."/.cscope.vim" -let s:index_file = s:cscope_vim_dir.'/index' - function! s:GetBestPath(dir) let f = substitute(a:dir,'\\','/','g') let bestDir = "" @@ -134,14 +96,15 @@ function! s:_CreateDB(dir, init) if ! filereadable(cscope_files) || a:init let cscope_files = s:cscope_vim_dir."/".id.".files" let cscope_db = s:cscope_vim_dir.'/'.id.'.db' - if ! filereadable(cscope_files) - let files = ListFiles(a:dir) - call writefile(files, cscope_files) - endif endif + + " force update file list + let files = ListFiles(a:dir) + call writefile(files, cscope_files) + exec 'cs kill '.cscope_db redir @x - exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f'.cscope_db + exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f '.cscope_db redi END if @x =~ "\nCommand terminated\n" echohl WarningMsg | echo "Failed to create cscope database for ".a:dir.", please check if " | echohl None @@ -357,9 +320,53 @@ function! s:onChange() endif endfunction -function! CscopeUpdateDB() +function! CscopeUpdateAllDB() call updateDBs(keys(s:dbs)) endfunction + +function! CscopeUpdateCurrentDB() + let m_dir = GetBestPath(expand('%:p:h')) + for d in keys(s:dbs) + if d == m_dir + call updateDBs([d]) + endif + endfor +endfunction + +if !exists('g:cscope_silent') + let g:cscope_silent = 0 +endif + +if !exists('g:cscope_auto_update') + let g:cscope_auto_update = 1 +endif + +if !exists('g:cscope_open_location') + let g:cscope_open_location = 1 +endif + +if !exists('g:cscope_split_threshold') + let g:cscope_split_threshold = 10000 +endif + +if !exists('g:cscope_search_case_insensitive') + let g:cscope_search_case_insensitive = 0 +endif + +if !exists('g:cscope_cmd') + if executable('cscope') + let g:cscope_cmd = 'cscope' + else + echo 'cscope: command not found' + finish + endif +endif + +if !exists('g:cscope_interested_files') + let files = readfile(expand(":p:h")."/interested.txt") + let g:cscope_interested_files = join(map(files, 'v:val."$"'), '\|') +endif + if exists('g:cscope_preload_path') call preloadDB() endif @@ -368,6 +375,9 @@ if g:cscope_auto_update == 1 au BufWritePost * call onChange() endif +let s:cscope_vim_dir = substitute($HOME,'\\','/','g')."/.cscope.vim" +let s:index_file = s:cscope_vim_dir.'/index' + set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i- com! -nargs=0 CscopeClear call clearDBs() com! -nargs=0 CscopeList call listDBs() From 87506a240c82b6fbbcc2e56de6ffbf97d2ecf387 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Thu, 21 May 2015 12:42:24 +0800 Subject: [PATCH 09/19] code refactoring --- plugin/cscope.vim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 154cd61..f9de9da 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -104,7 +104,7 @@ function! s:_CreateDB(dir, init) exec 'cs kill '.cscope_db redir @x - exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f '.cscope_db + exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f'.cscope_db redi END if @x =~ "\nCommand terminated\n" echohl WarningMsg | echo "Failed to create cscope database for ".a:dir.", please check if " | echohl None @@ -269,15 +269,19 @@ function! CscopeFind(action, word, ...) " the a:1 is used for window spliting control. " === let dirtyDirs = [] + for d in keys(s:dbs) if s:dbs[d]['dirty'] == 1 call add(dirtyDirs, d) endif endfor + if len(dirtyDirs) > 0 call updateDBs(dirtyDirs) endif + call AutoloadDB(expand('%:p:h')) + try if a:0 == 0 exe ':cs f '.a:action.' '.a:word @@ -297,14 +301,16 @@ endfunction function! CscopeFindInteractive(pat) call inputsave() + let qt = input("\nChoose a querytype for '".a:pat."'(:help cscope-find)\n c: functions calling this function\n d: functions called by this function\n e: this egrep pattern\n f: this file\n g: this definition\n i: files #including this file\n s: this C symbol\n t: this text string\n\n or\n to query `pattern` instead of '".a:pat."' as `querytype`, Ex. `smain` to query a C symbol named 'main'.\n> ") + call inputrestore() + if len(qt) > 1 call CscopeFind(qt[0], qt[1:]) elseif len(qt) > 0 call CscopeFind(qt, a:pat) endif - " call feedkeys("\") endfunction function! s:onChange() @@ -328,7 +334,7 @@ function! CscopeUpdateCurrentDB() let m_dir = GetBestPath(expand('%:p:h')) for d in keys(s:dbs) if d == m_dir - call updateDBs([d]) + call updateDBs([m_dir]) endif endfor endfunction From 2b5a9d67bbd12464f8d195a9f07fee9ecd0399ff Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Sun, 31 May 2015 22:44:24 +0800 Subject: [PATCH 10/19] 1. code refactored. 2. add depedency path feature, which enables multi path for a db. 3. delete some not unuseful features like auto update. --- plugin/cscope.vim | 522 ++++++++++++++++++++++++---------------------- 1 file changed, 267 insertions(+), 255 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index f9de9da..48ebb68 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -1,11 +1,25 @@ -" vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab foldmethod=marker + " vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab foldmethod=marker " Copyright: Copyright (C) 2012-2015 Brook Hong " License: The MIT License " +let s:cscope_vim_db_dir = substitute($HOME,'\\','/','g')."/.cscope.vim" +let s:cscope_vim_db_index_file = s:cscope_vim_db_dir.'/index' +let s:cscope_vim_db_entry_len = 5 +let s:cscope_vim_db_entry_idx_prepend_path = 0 +let s:cscope_vim_db_entry_idx_id = 1 +let s:cscope_vim_db_entry_idx_loadtimes = 2 +let s:cscope_vim_db_entry_idx_dirty = 3 +let s:cscope_vim_db_entry_idx_depedency = 4 +let s:cscope_vim_db_entry_key_id = 'id' +let s:cscope_vim_db_entry_key_loadtimes = 'loadtimes' +let s:cscope_vim_db_entry_key_dirty = 'dirty' +let s:cscope_vim_db_entry_key_depedency = 'depedency' + function! ToggleLocationList() let l:own = winnr() lw let l:cwn = winnr() + if(l:cwn == l:own) if &buftype == 'quickfix' lclose @@ -17,109 +31,93 @@ function! ToggleLocationList() endif endfunction -function! s:GetBestPath(dir) - let f = substitute(a:dir,'\\','/','g') - let bestDir = "" - for d in keys(s:dbs) - if stridx(f, d) == 0 && len(d) > len(bestDir) - let bestDir = d - endif - endfor - return bestDir -endfunction +function! CscopeFind(action, word, ...) + " ============================================ + " the a:1 is used for window spliting control. + " ============================================ + let current_path = expand('%:p:h') + let prepend_path = GetPrependPath(current_path) -function! s:ListFiles(dir) - let d = [] - let f = [] - let cwd = a:dir - let sl = &l:stl - while cwd != '' - let a = split(globpath(cwd, "*"), "\n") - for fn in a - if getftype(fn) == 'dir' - call add(d, fn) - elseif getftype(fn) != 'file' - continue - elseif fn !~? g:cscope_interested_files - continue - else - if stridx(fn, ' ') != -1 - let fn = '"'.fn.'"' - endif - call add(f, fn) - endif - endfor - let cwd = len(d) ? remove(d, 0) : '' - sleep 1m | let &l:stl = 'Found '.len(f).' files, finding in '.cwd | redrawstatus - endwhile - sleep 1m | let &l:stl = sl | redrawstatus - return f -endfunction + if prepend_path == "" + echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None + let prepend_path = input("", current_path, 'dir') -function! s:RmDBfiles() - let odbs = split(globpath(s:cscope_vim_dir, "*"), "\n") - for f in odbs - call delete(f) - endfor -endfunction + if prepend_path != '' + let prepend_path = CheckAbsolutePath(prepend_path, current_path) -function! s:FlushIndex() - let lines = [] - for d in keys(s:dbs) - call add(lines, d.'|'.s:dbs[d]['id'].'|'.s:dbs[d]['loadtimes'].'|'.s:dbs[d]['dirty']) - endfor - call writefile(lines, s:index_file) -endfunction + call InitDB(prepend_path) + call ReloadDB(prepend_path) + endif + else + let id = s:dbs[prepend_path][s:cscope_vim_db_entry_key_id] -function! s:CheckNewFile(dir, newfile) - let id = s:dbs[a:dir]['id'] - let cscope_files = s:cscope_vim_dir."/".id.".files" - let files = readfile(cscope_files) - if len(files) > g:cscope_split_threshold - let cscope_files = s:cscope_vim_dir."/".id."_inc.files" - if filereadable(cscope_files) - let files = readfile(cscope_files) - else - let files = [] + if cscope_connection(2, s:cscope_vim_db_dir.'/'.id.'.db') == 0 + call ReloadDB(prepend_path) endif endif - if count(files, a:newfile) == 0 - call add(files, a:newfile) - call writefile(files, cscope_files) - endif + + try + if a:0 == 0 + exe ':cs f '.a:action.' '.a:word + elseif a:0 >= 1 && a:1 == 'horizontal' + exe ':scs f '.a:action.' '.a:word + elseif a:0 >= 1 && a:1 == 'vertical' + exe ':vert scs f '.a:action.' '.a:word + endif + + if g:cscope_open_location == 1 + cw + endif + catch + echohl WarningMsg | echo 'Can not find '.a:word.' with querytype as '.a:action.'.' | echohl None + endtry endfunction -function! s:_CreateDB(dir, init) - let id = s:dbs[a:dir]['id'] - let cscope_files = s:cscope_vim_dir."/".id."_inc.files" - let cscope_db = s:cscope_vim_dir.'/'.id.'_inc.db' - if ! filereadable(cscope_files) || a:init - let cscope_files = s:cscope_vim_dir."/".id.".files" - let cscope_db = s:cscope_vim_dir.'/'.id.'.db' - endif +function! CscopeFindInteractive(pat) + call inputsave() - " force update file list - let files = ListFiles(a:dir) - call writefile(files, cscope_files) + let qt = input("\nChoose a querytype for '".a:pat."'(:help cscope-find)\n c: functions calling this function\n d: functions called by this function\n e: this egrep pattern\n f: this file\n g: this definition\n i: files #including this file\n s: this C symbol\n t: this text string\n\n or\n to query `pattern` instead of '".a:pat."' as `querytype`, Ex. `smain` to query a C symbol named 'main'.\n> ") - exec 'cs kill '.cscope_db - redir @x - exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f'.cscope_db - redi END - if @x =~ "\nCommand terminated\n" - echohl WarningMsg | echo "Failed to create cscope database for ".a:dir.", please check if " | echohl None + call inputrestore() + + if len(qt) > 1 + call CscopeFind(qt[0], qt[1:]) + elseif len(qt) > 0 + call CscopeFind(qt, a:pat) + endif +endfunction + +function! CscopeUpdateAllDB() + call UpdateDBs(keys(s:dbs)) +endfunction + +function! CscopeUpdateCurrentDB() + "========================== + " (0010) check if current db already exists + " (0020) if exists, update and stop + " (0030) if not exists, build db and stop + "========================== + let current_path = expand('%:p:h') + let prepend_path = GetPrependPath(current_path) + + if prepend_path != "" + call UpdateDBs([prepend_path]) else - let s:dbs[a:dir]['dirty'] = 0 - if g:cscope_search_case_insensitive == 1 - exec 'cs add '.cscope_db.' '.a:dir.' -C' - else - exec 'cs add '.cscope_db + echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None + let prepend_path = input("", current_path, 'dir') + + if prepend_path != '' + let prepend_path = CheckAbsolutePath(prepend_path, current_path) + + call InitDB(prepend_path) + call ReloadDB(prepend_path) endif endif endfunction function! s:CheckAbsolutePath(dir, defaultPath) let d = a:dir + while 1 if !isdirectory(d) echohl WarningMsg | echo "Please input a valid path." | echohl None @@ -131,89 +129,125 @@ function! s:CheckAbsolutePath(dir, defaultPath) break endif endwhile + let d = substitute(d,'\\','/','g') let d = substitute(d,'/\+$','','') - return d -endfunction -function! s:InitDB(dir) - let id = localtime() - let s:dbs[a:dir] = {} - let s:dbs[a:dir]['id'] = id - let s:dbs[a:dir]['loadtimes'] = 0 - let s:dbs[a:dir]['dirty'] = 0 - call _CreateDB(a:dir, 1) - call FlushIndex() + return d endfunction -function! s:LoadDB(dir) +function! s:ClearDBs() cs kill -1 + + let s:dbs = {} - if g:cscope_search_case_insensitive == 1 - exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'.db '.a:dir.' -C' + call RmDBfiles() + call writefile([], s:cscope_vim_db_index_file) +endfunction - if filereadable(s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db') - exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db '.a:dir.' -C' - endif - else - exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'.db' +function! s:CreateDB(prepend_path, init) + let id = s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id] + let depedency = split(s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_depedency], ';') + let cscope_files = s:cscope_vim_db_dir."/".id."_inc.files" + let cscope_db = s:cscope_vim_db_dir.'/'.id.'_inc.db' - if filereadable(s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db') - exe 'cs add '.s:cscope_vim_dir.'/'.s:dbs[a:dir]['id'].'_inc.db' - endif + if ! filereadable(cscope_files) || a:init + let cscope_files = s:cscope_vim_db_dir."/".id.".files" + let cscope_db = s:cscope_vim_db_dir.'/'.id.'.db' endif - let s:dbs[a:dir]['loadtimes'] = s:dbs[a:dir]['loadtimes']+1 - call FlushIndex() -endfunction + " validate depedency + for i in range(len(depedency)) + let depedency[i] = CheckAbsolutePath(depedency[i], "") + endfor -function! s:AutoloadDB(dir) - let m_dir = GetBestPath(a:dir) - if m_dir == "" - echohl WarningMsg | echo "Can not find proper cscope db, please input a path to generate cscope db for." | echohl None - let m_dir = input("", a:dir, 'dir') - if m_dir != '' - let m_dir = CheckAbsolutePath(m_dir, a:dir) - call InitDB(m_dir) - call LoadDB(m_dir) - endif + " force update file list + let files = [] + for d in [a:prepend_path] + depedency + let files += ListFiles(d) + endfor + call writefile(files, cscope_files) + + " build cscope database + exec 'cs kill '.cscope_db + redir @x + exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f'.cscope_db + redir END + + " check build result and add database + if @x =~ "\nCommand terminated\n" + echohl WarningMsg | echo "Failed to create cscope database for ".a:prepend_path.", please check if " | echohl None else - let id = s:dbs[m_dir]['id'] - if cscope_connection(2, s:cscope_vim_dir.'/'.id.'.db') == 0 - call LoadDB(m_dir) + let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_dirty] = 0 + + if g:cscope_search_case_insensitive == 1 + exec 'cs add '.cscope_db.' '.a:prepend_path.' -C' + else + exec 'cs add '.cscope_db endif endif endfunction -function! s:updateDBs(dirs) - for d in a:dirs - call _CreateDB(d, 0) +function! s:FlushIndex() + let lines = [] + + for d in keys(s:dbs) + call add(lines, d.'|'.s:dbs[d][s:cscope_vim_db_entry_key_id].'|'.s:dbs[d][s:cscope_vim_db_entry_key_loadtimes].'|'.s:dbs[d][s:cscope_vim_db_entry_key_dirty].'|'.s:dbs[d][s:cscope_vim_db_entry_key_depedency].'|') endfor - call FlushIndex() + + call writefile(lines, s:cscope_vim_db_index_file) endfunction -function! s:echo(msg) - if g:cscope_silent == 0 - echo a:msg - endif +function! s:GetPrependPath(dir) + let f = substitute(a:dir,'\\','/','g') + let bestDir = "" + + for d in keys(s:dbs) + if stridx(f, d) == 0 && len(d) > len(bestDir) + let bestDir = d + endif + endfor + + return bestDir endfunction -function! s:clearDBs() - cs kill -1 - let s:dbs = {} - call RmDBfiles() - call writefile([], s:index_file) +function! s:InitDB(prepend_path) + " ============================ + " (000) Get depedency path + " (001) Create cscope db entry + " (002) Build cscope db + " (003) Update index file + " ============================ + " (000) Get depedency path + echohl WarningMsg | echo "\nPlease input depedency paths (separated with ';'), if any." | echohl None + let depedency_path = input("", "", 'dir') + + " (001) Create cscope db entry + let s:dbs[a:prepend_path] = {} + let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id] = localtime() + let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_loadtimes] = 0 + let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_dirty] = 0 + let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_depedency] = depedency_path + + " (002) Build cscope db + call CreateDB(a:prepend_path, 1) + + " (003) Update index file + call FlushIndex() endfunction -function! s:listDBs() +function! s:ListDBs() let dirs = keys(s:dbs) + if len(dirs) == 0 echo "You have no cscope dbs now." else let s = [' ID LOADTIMES PATH'] + for d in dirs let id = s:dbs[d]['id'] - if cscope_connection(2, s:cscope_vim_dir.'/'.id.'.db') == 1 + + if cscope_connection(2, s:cscope_vim_db_dir.'/'.id.'.db') == 1 let l = printf("*%d %10d %s", id, s:dbs[d]['loadtimes'], d) else let l = printf(" %d %10d %s", id, s:dbs[d]['loadtimes'], d) @@ -224,137 +258,125 @@ function! s:listDBs() endif endfunction -function! s:loadIndex() - let s:dbs = {} - if ! isdirectory(s:cscope_vim_dir) - call mkdir(s:cscope_vim_dir) - elseif filereadable(s:index_file) - let idx = readfile(s:index_file) - for i in idx - let e = split(i, '|') - if len(e) == 0 - call delete(s:index_file) - call RmDBfiles() +function! s:ListFiles(dir) + let d = [] + let f = [] + let cwd = a:dir + let sl = &l:stl + + while cwd != '' + let a = split(globpath(cwd, "*"), "\n") + + for fn in a + if getftype(fn) == 'dir' + call add(d, fn) + elseif getftype(fn) != 'file' + continue + elseif fn !~? g:cscope_interested_files + continue else - let db_file = s:cscope_vim_dir.'/'.e[1].'.db' - if filereadable(db_file) - if isdirectory(e[0]) - let s:dbs[e[0]] = {} - let s:dbs[e[0]]['id'] = e[1] - let s:dbs[e[0]]['loadtimes'] = e[2] - let s:dbs[e[0]]['dirty'] = (len(e) > 3) ? e[3] :0 - else - call delete(db_file) - endif + if stridx(fn, ' ') != -1 + let fn = '"'.fn.'"' endif + call add(f, fn) endif endfor - else - call RmDBfiles() - endif -endfunction -function! s:preloadDB() - let dirs = split(g:cscope_preload_path, ';') - for m_dir in dirs - let m_dir = CheckAbsolutePath(m_dir, m_dir) - if ! has_key(s:dbs, m_dir) - call InitDB(m_dir) - endif - call LoadDB(m_dir) - endfor -endfunction + let cwd = len(d) ? remove(d, 0) : '' -function! CscopeFind(action, word, ...) - " the a:1 is used for window spliting control. - " === - let dirtyDirs = [] + sleep 1m | let &l:stl = 'Found '.len(f).' files, finding in '.cwd | redrawstatus + endwhile - for d in keys(s:dbs) - if s:dbs[d]['dirty'] == 1 - call add(dirtyDirs, d) - endif - endfor + sleep 1m | let &l:stl = sl | redrawstatus + return f +endfunction - if len(dirtyDirs) > 0 - call updateDBs(dirtyDirs) - endif +function! s:ReloadDB(prepend_path) + cs kill -1 - call AutoloadDB(expand('%:p:h')) + if g:cscope_search_case_insensitive == 1 + exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db '.a:prepend_path.' -C' - try - if a:0 == 0 - exe ':cs f '.a:action.' '.a:word - elseif a:0 >= 1 && a:1 == 'horizontal' - exe ':scs f '.a:action.' '.a:word - elseif a:0 >= 1 && a:1 == 'vertical' - exe ':vert scs f '.a:action.' '.a:word + if filereadable(s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db') + exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db '.a:prepend_path.' -C' endif + else + exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db' - if g:cscope_open_location == 1 - cw + if filereadable(s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db') + exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db' endif - catch - echohl WarningMsg | echo 'Can not find '.a:word.' with querytype as '.a:action.'.' | echohl None - endtry -endfunction - -function! CscopeFindInteractive(pat) - call inputsave() - - let qt = input("\nChoose a querytype for '".a:pat."'(:help cscope-find)\n c: functions calling this function\n d: functions called by this function\n e: this egrep pattern\n f: this file\n g: this definition\n i: files #including this file\n s: this C symbol\n t: this text string\n\n or\n to query `pattern` instead of '".a:pat."' as `querytype`, Ex. `smain` to query a C symbol named 'main'.\n> ") - - call inputrestore() + endif - if len(qt) > 1 - call CscopeFind(qt[0], qt[1:]) - elseif len(qt) > 0 - call CscopeFind(qt, a:pat) - endif + let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_loadtimes] = s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_loadtimes] + 1 + call FlushIndex() endfunction -function! s:onChange() - if expand('%:t') =~? g:cscope_interested_files - let m_dir = GetBestPath(expand('%:p:h')) - if m_dir != "" - let s:dbs[m_dir]['dirty'] = 1 - call FlushIndex() - call CheckNewFile(m_dir, expand('%:p')) - redraw - call echo('Your cscope db will be updated automatically, you can turn off this message by setting g:cscope_silent 1.') - endif +function! s:LoadIndex() + " s:dbs = { 'prepend1': {'id': '', + " 'loadtimes': '', + " 'dirty': 0|1, + " 'depedency': ['', '']}, + " ... + " } + let s:dbs = {} + + if ! isdirectory(s:cscope_vim_db_dir) + call mkdir(s:cscope_vim_db_dir) + elseif filereadable(s:cscope_vim_db_index_file) + let idx = readfile(s:cscope_vim_db_index_file) + + for i in idx + let e = split(i, '|') + + if len(e) != s:cscope_vim_db_entry_len + call RmDBfiles() + else + let db_file = s:cscope_vim_db_dir.'/'.e[s:cscope_vim_db_entry_idx_id].'.db' + let db_file_list = s:cscope_vim_db_dir.'/'.e[s:cscope_vim_db_entry_idx_id].'.files' + + if filereadable(db_file) + if isdirectory(e[s:cscope_vim_db_entry_idx_prepend_path]) + let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]] = {} + let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_id] = e[s:cscope_vim_db_entry_idx_id] + let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_loadtimes] = e[s:cscope_vim_db_entry_idx_loadtimes] + let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_dirty] = e[s:cscope_vim_db_entry_idx_dirty] + let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_depedency] = split(e[s:cscope_vim_db_entry_idx_depedency], ';') + else + call delete(db_file) + call delete(db_file_list) + endif + endif + endif + endfor + else + call RmDBfiles() endif endfunction -function! CscopeUpdateAllDB() - call updateDBs(keys(s:dbs)) -endfunction +function! s:RmDBfiles() + let odbs = split(globpath(s:cscope_vim_db_dir, "*"), "\n") -function! CscopeUpdateCurrentDB() - let m_dir = GetBestPath(expand('%:p:h')) - for d in keys(s:dbs) - if d == m_dir - call updateDBs([m_dir]) - endif + for f in odbs + call delete(f) endfor endfunction -if !exists('g:cscope_silent') - let g:cscope_silent = 0 -endif +function! s:UpdateDBs(prepend_paths) + "====================== + " (0010) re-create db(s), + "====================== + for d in a:prepend_paths + call CreateDB(d, 0) + endfor -if !exists('g:cscope_auto_update') - let g:cscope_auto_update = 1 -endif + call FlushIndex() +endfunction if !exists('g:cscope_open_location') let g:cscope_open_location = 1 endif -if !exists('g:cscope_split_threshold') - let g:cscope_split_threshold = 10000 -endif - if !exists('g:cscope_search_case_insensitive') let g:cscope_search_case_insensitive = 0 endif @@ -373,18 +395,8 @@ if !exists('g:cscope_interested_files') let g:cscope_interested_files = join(map(files, 'v:val."$"'), '\|') endif -if exists('g:cscope_preload_path') - call preloadDB() -endif - -if g:cscope_auto_update == 1 - au BufWritePost * call onChange() -endif - -let s:cscope_vim_dir = substitute($HOME,'\\','/','g')."/.cscope.vim" -let s:index_file = s:cscope_vim_dir.'/index' - set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i- -com! -nargs=0 CscopeClear call clearDBs() -com! -nargs=0 CscopeList call listDBs() -call loadIndex() +com! -nargs=0 CscopeClear call ClearDBs() +com! -nargs=0 CscopeList call ListDBs() +call LoadIndex() + From a8a6a74d10fc044d8c946b5bc5b13dfc757085f7 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 1 Jun 2015 13:22:04 +0800 Subject: [PATCH 11/19] fixed a dependency related issue. --- plugin/cscope.vim | 204 +++++++++++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 95 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 48ebb68..0f122b1 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -4,6 +4,7 @@ " let s:cscope_vim_db_dir = substitute($HOME,'\\','/','g')."/.cscope.vim" let s:cscope_vim_db_index_file = s:cscope_vim_db_dir.'/index' +let s:cscope_vim_db_current_prepend_path = "" let s:cscope_vim_db_entry_len = 5 let s:cscope_vim_db_entry_idx_prepend_path = 0 let s:cscope_vim_db_entry_idx_id = 1 @@ -15,44 +16,43 @@ let s:cscope_vim_db_entry_key_loadtimes = 'loadtimes' let s:cscope_vim_db_entry_key_dirty = 'dirty' let s:cscope_vim_db_entry_key_depedency = 'depedency' -function! ToggleLocationList() - let l:own = winnr() - lw - let l:cwn = winnr() - - if(l:cwn == l:own) - if &buftype == 'quickfix' - lclose - elseif len(getloclist(winnr())) > 0 - lclose - else - echohl WarningMsg | echo "No location list." | echohl None - endif - endif -endfunction - function! CscopeFind(action, word, ...) " ============================================ " the a:1 is used for window spliting control. " ============================================ - let current_path = expand('%:p:h') - let prepend_path = GetPrependPath(current_path) - - if prepend_path == "" - echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None - let prepend_path = input("", current_path, 'dir') - - if prepend_path != '' - let prepend_path = CheckAbsolutePath(prepend_path, current_path) + let l:current_path = tolower(substitute(expand('%:p:h'), '\\', '/', 'g')) + let l:prepend_path = GetPrependPath(l:current_path) + let l:in_dependency = 0 + + " possible reasons for empty prepend path + " - DB not yet built + " - we are in depedency files + if l:prepend_path == "" && s:cscope_vim_db_current_prepend_path != "" + for l:d in split(s:dbs[s:cscope_vim_db_current_prepend_path][s:cscope_vim_db_entry_key_depedency], ';') + let l:d = substitute(l:d, "\/\\s*$", '', 'g') + + if stridx(l:current_path, l:d) == 0 + let l:in_dependency = 1 + break + endif + endfor + endif + + " build a brand new db + if l:prepend_path == "" && l:in_dependency == 0 + let l:prepend_path = InitDB(l:current_path) - call InitDB(prepend_path) - call ReloadDB(prepend_path) + if l:prepend_path != "" + call BuildDB(l:prepend_path, 1) + call LoadDB(l:prepend_path) endif - else - let id = s:dbs[prepend_path][s:cscope_vim_db_entry_key_id] + endif - if cscope_connection(2, s:cscope_vim_db_dir.'/'.id.'.db') == 0 - call ReloadDB(prepend_path) + if l:prepend_path != "" + let l:id = s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_id] + + if cscope_connection(2, s:cscope_vim_db_dir.'/'.l:id.'.db') == 0 + call LoadDB(l:prepend_path) endif endif @@ -97,20 +97,33 @@ function! CscopeUpdateCurrentDB() " (0020) if exists, update and stop " (0030) if not exists, build db and stop "========================== - let current_path = expand('%:p:h') - let prepend_path = GetPrependPath(current_path) + let l:current_path = expand('%:p:h') + let l:prepend_path = GetPrependPath(l:current_path) - if prepend_path != "" - call UpdateDBs([prepend_path]) + if l:prepend_path != "" + call UpdateDBs([l:prepend_path]) else - echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None - let prepend_path = input("", current_path, 'dir') + let l:prepend_path = InitDB(l:current_path) + + if l:prepend_path != "" + call BuildDB(l:prepend_path, 1) + call LoadDB(l:prepend_path) + endif + endif +endfunction - if prepend_path != '' - let prepend_path = CheckAbsolutePath(prepend_path, current_path) +function! ToggleLocationList() + let l:own = winnr() + lw + let l:cwn = winnr() - call InitDB(prepend_path) - call ReloadDB(prepend_path) + if(l:cwn == l:own) + if &buftype == 'quickfix' + lclose + elseif len(getloclist(winnr())) > 0 + lclose + else + echohl WarningMsg | echo "No location list." | echohl None endif endif endfunction @@ -142,28 +155,28 @@ function! s:ClearDBs() let s:dbs = {} call RmDBfiles() - call writefile([], s:cscope_vim_db_index_file) + " call writefile([], s:cscope_vim_db_index_file) endfunction -function! s:CreateDB(prepend_path, init) - let id = s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id] - let depedency = split(s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_depedency], ';') - let cscope_files = s:cscope_vim_db_dir."/".id."_inc.files" - let cscope_db = s:cscope_vim_db_dir.'/'.id.'_inc.db' +function! s:BuildDB(prepend_path, init) + let l:id = s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id] + let l:depedency = split(s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_depedency], ';') + let l:cscope_files = s:cscope_vim_db_dir."/".id."_inc.files" + let l:cscope_db = s:cscope_vim_db_dir.'/'.id.'_inc.db' if ! filereadable(cscope_files) || a:init - let cscope_files = s:cscope_vim_db_dir."/".id.".files" - let cscope_db = s:cscope_vim_db_dir.'/'.id.'.db' + let l:cscope_files = s:cscope_vim_db_dir."/".id.".files" + let l:cscope_db = s:cscope_vim_db_dir.'/'.id.'.db' endif " validate depedency - for i in range(len(depedency)) - let depedency[i] = CheckAbsolutePath(depedency[i], "") + for i in range(len(l:depedency)) + let l:depedency[i] = CheckAbsolutePath(l:depedency[i], "") endfor " force update file list let files = [] - for d in [a:prepend_path] + depedency + for d in [a:prepend_path] + l:depedency let files += ListFiles(d) endfor call writefile(files, cscope_files) @@ -179,23 +192,19 @@ function! s:CreateDB(prepend_path, init) echohl WarningMsg | echo "Failed to create cscope database for ".a:prepend_path.", please check if " | echohl None else let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_dirty] = 0 - - if g:cscope_search_case_insensitive == 1 - exec 'cs add '.cscope_db.' '.a:prepend_path.' -C' - else - exec 'cs add '.cscope_db - endif endif + + call FlushIndex() endfunction function! s:FlushIndex() - let lines = [] + let l:lines = [] for d in keys(s:dbs) - call add(lines, d.'|'.s:dbs[d][s:cscope_vim_db_entry_key_id].'|'.s:dbs[d][s:cscope_vim_db_entry_key_loadtimes].'|'.s:dbs[d][s:cscope_vim_db_entry_key_dirty].'|'.s:dbs[d][s:cscope_vim_db_entry_key_depedency].'|') + call add(l:lines, d.'|'.s:dbs[d][s:cscope_vim_db_entry_key_id].'|'.s:dbs[d][s:cscope_vim_db_entry_key_loadtimes].'|'.s:dbs[d][s:cscope_vim_db_entry_key_dirty].'|'.s:dbs[d][s:cscope_vim_db_entry_key_depedency].'|') endfor - call writefile(lines, s:cscope_vim_db_index_file) + call writefile(l:lines, s:cscope_vim_db_index_file) endfunction function! s:GetPrependPath(dir) @@ -211,29 +220,28 @@ function! s:GetPrependPath(dir) return bestDir endfunction -function! s:InitDB(prepend_path) - " ============================ - " (000) Get depedency path - " (001) Create cscope db entry - " (002) Build cscope db - " (003) Update index file - " ============================ - " (000) Get depedency path - echohl WarningMsg | echo "\nPlease input depedency paths (separated with ';'), if any." | echohl None - let depedency_path = input("", "", 'dir') - - " (001) Create cscope db entry - let s:dbs[a:prepend_path] = {} - let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id] = localtime() - let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_loadtimes] = 0 - let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_dirty] = 0 - let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_depedency] = depedency_path - - " (002) Build cscope db - call CreateDB(a:prepend_path, 1) - - " (003) Update index file - call FlushIndex() +function! s:InitDB(current_path) + echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None + let l:prepend_path = input("", a:current_path, 'dir') + + if l:prepend_path != '' + let prepend_path = CheckAbsolutePath(l:prepend_path, a:current_path) + + echohl WarningMsg | echo "\nPlease input depedency paths (separated with ';'), if any." | echohl None + let l:depedency_path = input("", "", 'dir') + + let s:dbs[l:prepend_path] = {} + let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_id] = localtime() + let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_loadtimes] = 0 + let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_dirty] = 0 + let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_depedency] = tolower(substitute(l:depedency_path,'\\','/','g')) + + call FlushIndex() + + return l:prepend_path + else + echohl WarningMsg | echo "Error: path can not be empty." | echohl None + endif endfunction function! s:ListDBs() @@ -252,8 +260,10 @@ function! s:ListDBs() else let l = printf(" %d %10d %s", id, s:dbs[d]['loadtimes'], d) endif + call add(s, l) endfor + echo join(s, "\n") endif endfunction @@ -291,24 +301,30 @@ function! s:ListFiles(dir) return f endfunction -function! s:ReloadDB(prepend_path) +function! s:LoadDB(prepend_path) cs kill -1 if g:cscope_search_case_insensitive == 1 exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db '.a:prepend_path.' -C' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db added.' if filereadable(s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db') exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db '.a:prepend_path.' -C' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db added.' endif else exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db added.' if filereadable(s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db') exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db added.' endif endif let s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_loadtimes] = s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_loadtimes] + 1 + let s:cscope_vim_db_current_prepend_path = a:prepend_path + call FlushIndex() endfunction @@ -316,7 +332,7 @@ function! s:LoadIndex() " s:dbs = { 'prepend1': {'id': '', " 'loadtimes': '', " 'dirty': 0|1, - " 'depedency': ['', '']}, + " 'depedency': '...;...'}, " ... " } let s:dbs = {} @@ -332,19 +348,19 @@ function! s:LoadIndex() if len(e) != s:cscope_vim_db_entry_len call RmDBfiles() else - let db_file = s:cscope_vim_db_dir.'/'.e[s:cscope_vim_db_entry_idx_id].'.db' - let db_file_list = s:cscope_vim_db_dir.'/'.e[s:cscope_vim_db_entry_idx_id].'.files' + let l:db_file = s:cscope_vim_db_dir.'/'.e[s:cscope_vim_db_entry_idx_id].'.db' + let l:db_file_list = s:cscope_vim_db_dir.'/'.e[s:cscope_vim_db_entry_idx_id].'.files' - if filereadable(db_file) + if filereadable(l:db_file) if isdirectory(e[s:cscope_vim_db_entry_idx_prepend_path]) let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]] = {} let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_id] = e[s:cscope_vim_db_entry_idx_id] let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_loadtimes] = e[s:cscope_vim_db_entry_idx_loadtimes] let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_dirty] = e[s:cscope_vim_db_entry_idx_dirty] - let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_depedency] = split(e[s:cscope_vim_db_entry_idx_depedency], ';') + let s:dbs[e[s:cscope_vim_db_entry_idx_prepend_path]][s:cscope_vim_db_entry_key_depedency] = e[s:cscope_vim_db_entry_idx_depedency] else - call delete(db_file) - call delete(db_file_list) + call delete(l:db_file) + call delete(l:db_file_list) endif endif endif @@ -367,10 +383,8 @@ function! s:UpdateDBs(prepend_paths) " (0010) re-create db(s), "====================== for d in a:prepend_paths - call CreateDB(d, 0) + call BuildDB(d, 0) endfor - - call FlushIndex() endfunction if !exists('g:cscope_open_location') From fcd0e97778efc6b9c1f855fe66f477d0441db925 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 1 Jun 2015 14:11:09 +0800 Subject: [PATCH 12/19] fixed a string comparison issue --- plugin/cscope.vim | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 0f122b1..cde985b 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -92,11 +92,6 @@ function! CscopeUpdateAllDB() endfunction function! CscopeUpdateCurrentDB() - "========================== - " (0010) check if current db already exists - " (0020) if exists, update and stop - " (0030) if not exists, build db and stop - "========================== let l:current_path = expand('%:p:h') let l:prepend_path = GetPrependPath(l:current_path) @@ -208,7 +203,7 @@ function! s:FlushIndex() endfunction function! s:GetPrependPath(dir) - let f = substitute(a:dir,'\\','/','g') + let f = tolower(substitute(a:dir,'\\','/','g')) let bestDir = "" for d in keys(s:dbs) @@ -222,19 +217,19 @@ endfunction function! s:InitDB(current_path) echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None - let l:prepend_path = input("", a:current_path, 'dir') + let l:prepend_path = tolower(substitute(input("", a:current_path, 'dir'),'\\','/','g')) if l:prepend_path != '' let prepend_path = CheckAbsolutePath(l:prepend_path, a:current_path) echohl WarningMsg | echo "\nPlease input depedency paths (separated with ';'), if any." | echohl None - let l:depedency_path = input("", "", 'dir') + let l:depedency_path = tolower(substitute(input("", "", 'dir'),'\\','/','g')) let s:dbs[l:prepend_path] = {} let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_id] = localtime() let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_loadtimes] = 0 let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_dirty] = 0 - let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_depedency] = tolower(substitute(l:depedency_path,'\\','/','g')) + let s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_depedency] = l:depedency_path call FlushIndex() From e3bf13534a09e0d51cdca6376cbf78d6e3e3d14b Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Sat, 6 Jun 2015 23:39:05 +0800 Subject: [PATCH 13/19] regular integration --- plugin/cscope.vim | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index cde985b..36c3f71 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -144,13 +144,17 @@ function! s:CheckAbsolutePath(dir, defaultPath) return d endfunction -function! s:ClearDBs() +" @param clearWhich: -1 all database +" 0 the current database +function! s:ClearDBs(clearWhich) cs kill -1 - let s:dbs = {} + if a:clearWhich == -1 + let s:dbs = {} + call RmDBfiles() + call writefile([], s:cscope_vim_db_index_file) + endif - call RmDBfiles() - " call writefile([], s:cscope_vim_db_index_file) endfunction function! s:BuildDB(prepend_path, init) @@ -405,7 +409,8 @@ if !exists('g:cscope_interested_files') endif set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i- -com! -nargs=0 CscopeClear call ClearDBs() +com! -nargs=0 CscopeClearAllDB call ClearDBs(-1) +com! -nargs=0 CscopeClearCurrentDB call ClearDBs(0) com! -nargs=0 CscopeList call ListDBs() call LoadIndex() From 74eeca271371fc82e678f63ea6a8001a82b6cdfa Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Thu, 18 Jun 2015 12:21:54 +0800 Subject: [PATCH 14/19] add status prints --- plugin/cscope.vim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 36c3f71..e493e4f 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -305,19 +305,19 @@ function! s:LoadDB(prepend_path) if g:cscope_search_case_insensitive == 1 exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db '.a:prepend_path.' -C' - echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db added.' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db added, searching case insensitively.' if filereadable(s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db') exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db '.a:prepend_path.' -C' - echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db added.' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db added, searching case insensitively.' endif else exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db' - echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db added.' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'.db added, searching case sensitively.' if filereadable(s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db') exe 'cs add '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db' - echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db added.' + echo 'cscope db '.s:cscope_vim_db_dir.'/'.s:dbs[a:prepend_path][s:cscope_vim_db_entry_key_id].'_inc.db added, searching case sensitively.' endif endif From 4dbf51a0b551d87414a669ac927b01a467defea0 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Mon, 22 Jun 2015 22:37:38 +0800 Subject: [PATCH 15/19] add rebuild current db --- plugin/cscope.vim | 70 +++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index e493e4f..b17cf4f 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -17,9 +17,6 @@ let s:cscope_vim_db_entry_key_dirty = 'dirty' let s:cscope_vim_db_entry_key_depedency = 'depedency' function! CscopeFind(action, word, ...) - " ============================================ - " the a:1 is used for window spliting control. - " ============================================ let l:current_path = tolower(substitute(expand('%:p:h'), '\\', '/', 'g')) let l:prepend_path = GetPrependPath(l:current_path) let l:in_dependency = 0 @@ -87,16 +84,18 @@ function! CscopeFindInteractive(pat) endif endfunction -function! CscopeUpdateAllDB() - call UpdateDBs(keys(s:dbs)) +function! s:CscopeUpdateAllDB() + for d in keys(s:dbs) + call BuildDB(d, 0) + endfor endfunction -function! CscopeUpdateCurrentDB() +function! s:CscopeUpdateCurrentDB() let l:current_path = expand('%:p:h') let l:prepend_path = GetPrependPath(l:current_path) if l:prepend_path != "" - call UpdateDBs([l:prepend_path]) + call BuildDB(l:prepend_path, 0) else let l:prepend_path = InitDB(l:current_path) @@ -107,19 +106,15 @@ function! CscopeUpdateCurrentDB() endif endfunction -function! ToggleLocationList() - let l:own = winnr() - lw - let l:cwn = winnr() +function! s:CscopeRebuildCurrentDB() + call ClearDBs(0) - if(l:cwn == l:own) - if &buftype == 'quickfix' - lclose - elseif len(getloclist(winnr())) > 0 - lclose - else - echohl WarningMsg | echo "No location list." | echohl None - endif + let l:current_path = expand('%:p:h') + let l:prepend_path = InitDB(l:current_path) + + if l:prepend_path != "" + call BuildDB(l:prepend_path, 1) + call LoadDB(l:prepend_path) endif endfunction @@ -153,8 +148,22 @@ function! s:ClearDBs(clearWhich) let s:dbs = {} call RmDBfiles() call writefile([], s:cscope_vim_db_index_file) - endif + elseif a:clearWhich == 0 + let l:current_path = expand('%:p:h') + let l:prepend_path = GetPrependPath(l:current_path) + + if l:prepend_path != "" + let l:current_db_files = split(globpath(s:cscope_vim_db_dir, s:dbs[l:prepend_path][s:cscope_vim_db_entry_key_id]."*"), "\n") + + for f in l:current_db_files + call delete(f) + endfor + + unlet s:dbs[l:prepend_path] + call FlushIndex() + endif + endif endfunction function! s:BuildDB(prepend_path, init) @@ -220,7 +229,7 @@ function! s:GetPrependPath(dir) endfunction function! s:InitDB(current_path) - echohl WarningMsg | echo "Can not find a proper cscope db, please input a path to generate one." | echohl None + echohl WarningMsg | echo "Please input a path to generate cscope database." | echohl None let l:prepend_path = tolower(substitute(input("", a:current_path, 'dir'),'\\','/','g')) if l:prepend_path != '' @@ -377,15 +386,6 @@ function! s:RmDBfiles() endfor endfunction -function! s:UpdateDBs(prepend_paths) - "====================== - " (0010) re-create db(s), - "====================== - for d in a:prepend_paths - call BuildDB(d, 0) - endfor -endfunction - if !exists('g:cscope_open_location') let g:cscope_open_location = 1 endif @@ -408,9 +408,13 @@ if !exists('g:cscope_interested_files') let g:cscope_interested_files = join(map(files, 'v:val."$"'), '\|') endif +command! -nargs=0 CscopeClearAllDB call ClearDBs(-1) +command! -nargs=0 CscopeClearCurrentDB call ClearDBs(0) +command! -nargs=0 CscopeList call ListDBs() +command! -nargs=0 CscopeRebuildCurrentDB call CscopeRebuildCurrentDB() +command! -nargs=0 CscopeUpdateAllDB call CscopeUpdateAllDB() +command! -nargs=0 CscopeUpdateCurrentDB call CscopeUpdateCurrentDB() + set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i- -com! -nargs=0 CscopeClearAllDB call ClearDBs(-1) -com! -nargs=0 CscopeClearCurrentDB call ClearDBs(0) -com! -nargs=0 CscopeList call ListDBs() call LoadIndex() From 6b9ab2f8efe9fc87314d62091d230cc938977998 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Tue, 23 Jun 2015 10:44:27 +0800 Subject: [PATCH 16/19] fixed unaligned indentation. --- plugin/cscope.vim | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index b17cf4f..2bf018e 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -1,4 +1,3 @@ - " vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab foldmethod=marker " Copyright: Copyright (C) 2012-2015 Brook Hong " License: The MIT License " @@ -71,17 +70,17 @@ function! CscopeFind(action, word, ...) endfunction function! CscopeFindInteractive(pat) - call inputsave() + call inputsave() - let qt = input("\nChoose a querytype for '".a:pat."'(:help cscope-find)\n c: functions calling this function\n d: functions called by this function\n e: this egrep pattern\n f: this file\n g: this definition\n i: files #including this file\n s: this C symbol\n t: this text string\n\n or\n to query `pattern` instead of '".a:pat."' as `querytype`, Ex. `smain` to query a C symbol named 'main'.\n> ") + let qt = input("\nChoose a querytype for '".a:pat."'(:help cscope-find)\n c: functions calling this function\n d: functions called by this function\n e: this egrep pattern\n f: this file\n g: this definition\n i: files #including this file\n s: this C symbol\n t: this text string\n\n or\n to query `pattern` instead of '".a:pat."' as `querytype`, Ex. `smain` to query a C symbol named 'main'.\n> ") - call inputrestore() + call inputrestore() - if len(qt) > 1 - call CscopeFind(qt[0], qt[1:]) - elseif len(qt) > 0 - call CscopeFind(qt, a:pat) - endif + if len(qt) > 1 + call CscopeFind(qt[0], qt[1:]) + elseif len(qt) > 0 + call CscopeFind(qt, a:pat) + endif endfunction function! s:CscopeUpdateAllDB() From 37180416d805b16293657db352da0e4f7618b11e Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Thu, 25 Jun 2015 15:54:22 +0800 Subject: [PATCH 17/19] use location window instead --- plugin/cscope.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 2bf018e..ed5b802 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -54,7 +54,7 @@ function! CscopeFind(action, word, ...) try if a:0 == 0 - exe ':cs f '.a:action.' '.a:word + exe ':lcs f '.a:action.' '.a:word elseif a:0 >= 1 && a:1 == 'horizontal' exe ':scs f '.a:action.' '.a:word elseif a:0 >= 1 && a:1 == 'vertical' From b91e9de73d2378ec181bfe7e0dba7d11899177c2 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Thu, 25 Jun 2015 16:03:18 +0800 Subject: [PATCH 18/19] revert --- plugin/cscope.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index ed5b802..2bf018e 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -54,7 +54,7 @@ function! CscopeFind(action, word, ...) try if a:0 == 0 - exe ':lcs f '.a:action.' '.a:word + exe ':cs f '.a:action.' '.a:word elseif a:0 >= 1 && a:1 == 'horizontal' exe ':scs f '.a:action.' '.a:word elseif a:0 >= 1 && a:1 == 'vertical' From 81c25e41cbb16676b49e0701e5f1b53d5c2b4328 Mon Sep 17 00:00:00 2001 From: "j5shi@live.com" Date: Tue, 30 Jun 2015 17:29:28 +0800 Subject: [PATCH 19/19] fixed a bug in generating cscope database in case the current dir was not the prepand path. --- plugin/cscope.vim | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plugin/cscope.vim b/plugin/cscope.vim index 2bf018e..fed6f64 100755 --- a/plugin/cscope.vim +++ b/plugin/cscope.vim @@ -54,11 +54,11 @@ function! CscopeFind(action, word, ...) try if a:0 == 0 - exe ':cs f '.a:action.' '.a:word + exe 'cs f '.a:action.' '.a:word elseif a:0 >= 1 && a:1 == 'horizontal' - exe ':scs f '.a:action.' '.a:word + exe 'scs f '.a:action.' '.a:word elseif a:0 >= 1 && a:1 == 'vertical' - exe ':vert scs f '.a:action.' '.a:word + exe 'vert scs f '.a:action.' '.a:word endif if g:cscope_open_location == 1 @@ -188,10 +188,14 @@ function! s:BuildDB(prepend_path, init) endfor call writefile(files, cscope_files) - " build cscope database + " build cscope database, must build in the + " prepend path otherwise there might be error + " in generating database, e.g. invalid path for + " symbols. + exec 'chdir '.a:prepend_path exec 'cs kill '.cscope_db redir @x - exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f'.cscope_db + exec 'silent !'.g:cscope_cmd.' -b -i '.cscope_files.' -f '.cscope_db redir END " check build result and add database