diff --git a/autoload/SpaceVim/api/unicode/box.vim b/autoload/SpaceVim/api/unicode/box.vim index 555d72c8c..e81f3ad1a 100644 --- a/autoload/SpaceVim/api/unicode/box.vim +++ b/autoload/SpaceVim/api/unicode/box.vim @@ -21,6 +21,7 @@ scriptencoding utf-8 let s:self = {} let s:self._json = SpaceVim#api#import('data#json') let s:self._string = SpaceVim#api#import('data#string') +let s:self.box_width = 40 " http://jrgraphix.net/r/Unicode/2500-257F " http://www.alanflavell.org.uk/unicode/unidata.html @@ -58,16 +59,16 @@ function! s:self.drawing_table(json, ...) abort let items = self._json.json_decode(a:json) let col = len(keys(items[0])) let top_line = top_left_corner - \ . repeat(repeat(top_bottom_side, 15) . top_middle, col - 1) - \ . repeat(top_bottom_side, 15) + \ . repeat(repeat(top_bottom_side, self.box_width) . top_middle, col - 1) + \ . repeat(top_bottom_side, self.box_width) \ . top_right_corner let middle_line = left_middle - \ . repeat(repeat(top_bottom_side, 15) . middle, col - 1) - \ . repeat(top_bottom_side, 15) + \ . repeat(repeat(top_bottom_side, self.box_width) . middle, col - 1) + \ . repeat(top_bottom_side, self.box_width) \ . right_middle let bottom_line = bottom_left_corner - \ . repeat(repeat(top_bottom_side, 15) . bottom_middle, col - 1) - \ . repeat(top_bottom_side, 15) + \ . repeat(repeat(top_bottom_side, self.box_width) . bottom_middle, col - 1) + \ . repeat(top_bottom_side, self.box_width) \ . bottom_right_corner call add(table, top_line) let tytle = side @@ -77,14 +78,14 @@ function! s:self.drawing_table(json, ...) abort let keys = a:1 endif for key in keys - let tytle .= self._string.fill(key , 15) . side + let tytle .= self._string.fill_middle(key , self.box_width) . side endfor call add(table, tytle) call add(table, middle_line) for item in items let value_line = side for key in keys - let value_line .= self._string.fill(item[key], 15) . side + let value_line .= self._string.fill(item[key], self.box_width) . side endfor call add(table, value_line) call add(table, middle_line) diff --git a/autoload/SpaceVim/layers/cscope.vim b/autoload/SpaceVim/layers/cscope.vim index 76c7f3465..0f9d29a5f 100644 --- a/autoload/SpaceVim/layers/cscope.vim +++ b/autoload/SpaceVim/layers/cscope.vim @@ -38,3 +38,29 @@ function! SpaceVim#layers#cscope#health() abort call SpaceVim#layers#cscope#config() return 1 endfunction + +function! SpaceVim#layers#cscope#set_variable(var) abort + + let g:cscope_cmd = get(a:var, + \ 'cscope_command', + \ 'cscope') + let g:cscope_auto_update = get(a:var, + \ 'auto_update', + \ 1) + let g:cscope_open_location = get(a:var, + \ 'open_location', + \ 1) + let g:cscope_preload_path = get(a:var, + \ 'preload_path', + \ '') + +endfunction + +function! SpaceVim#layers#cscope#get_options() abort + + return ['cscope_command', + \ 'auto_update', + \ 'open_location', + \ 'preload_path'] + +endfunction diff --git a/bundle/cscope.vim/autoload/cscope.vim b/bundle/cscope.vim/autoload/cscope.vim index ae40d2986..ad16e73a1 100644 --- a/bundle/cscope.vim/autoload/cscope.vim +++ b/bundle/cscope.vim/autoload/cscope.vim @@ -45,19 +45,18 @@ set cpo&vim " where to store cscope file? -function! s:echo(msg) abort - echon a:msg -endfunction - +let s:logger = SpaceVim#logger#derive('cscope') +let s:notify = SpaceVim#api#import('notify') +let s:notify.timeout = 5000 +let s:box = SpaceVim#api#import('unicode#box') +let s:box.box_width = 40 let s:FILE = SpaceVim#api#import('file') +let s:JOB = SpaceVim#api#import('job') let s:JSON = SpaceVim#api#import('data#json') let s:cscope_cache_dir = s:FILE.unify_path('~/.cache/SpaceVim/cscope/') let s:cscope_db_index = s:cscope_cache_dir.'index' let s:dbs = {} - - - "" " search your {word} with {action} in the database suitable for current " file. @@ -65,7 +64,7 @@ function! cscope#find(action, word) abort let dirtyDirs = [] for d in keys(s:dbs) if s:dbs[d]['dirty'] == 1 - call add(dirtyDirs, s:dbs[d].root) + call add(dirtyDirs, d) endif endfor if len(dirtyDirs) > 0 @@ -79,8 +78,14 @@ function! cscope#find(action, word) abort lw endif catch - echohl WarningMsg | echo 'Can not find '.a:word.' with querytype as '.a:action.'.' | echohl None + let message = 'Can not find '.a:word.' with querytype as '.a:action.'.' + let s:notify.notify_max_width = strwidth(message) + 10 + call s:notify.notify(message, 'WarningMsg') endtry + elseif dbl == 2 " the database does not init, the process has been started. + let message = 'start to init database, please try later!' + let s:notify.notify_max_width = strwidth(message) + 10 + call s:notify.notify(message, 'WarningMsg') endif endfunction @@ -93,8 +98,8 @@ endfunction function! s:CheckNewFile(dir, newfile) abort + let id = s:dbs[a:dir]['id'] let dir = s:FILE.path_to_fname(a:dir) - let id = s:dbs[dir]['id'] let cscope_files = s:cscope_cache_dir. dir .'/cscope.files' let files = readfile(cscope_files) " @todo support threshold @@ -117,41 +122,52 @@ function! s:FlushIndex() abort endfunction -function! s:ListFiles(dir) abort - let d = [] - let f = [] - let cwd = a:dir - try - while cwd != '' - let a = split(globpath(cwd, '*'), "\n") - for fn in a - if getftype(fn) ==# 'dir' - if !exists('g:cscope_ignored_dir') || fn !~? g:cscope_ignored_dir - call add(d, fn) - endif - elseif getftype(fn) !=# 'file' - continue - else - if stridx(fn, ' ') !=# -1 - let fn = '"'.fn.'"' - endif - call add(f, fn) - endif - endfor - let cwd = len(d) ? remove(d, 0) : '' - endwhile - catch /^Vim:Interrupt$/ - catch - echo 'caught' v:exception - endtry - return f +function! s:on_list_file_exit(id, date, event) abort + +endfunction + + +let s:list_files_process = {} + +function! s:list_files_stdout(id, data, event) abort + call extend(s:list_files_process['jobid' . a:id].cscope_files, a:data) +endfunction + +function! s:list_files_exit(id, date, event) abort + if a:date == 0 + call writefile(s:list_files_process['jobid' . a:id].cscope_files, + \ s:list_files_process['jobid' . a:id].cscope_files_path + \ ) + call s:run_create_database_job(s:list_files_process['jobid' . a:id].dir, + \ s:list_files_process['jobid' . a:id].cscope_files_path, + \ s:list_files_process['jobid' . a:id].cscope_db, + \ s:list_files_process['jobid' . a:id].load, + \ ) + else + call s:logger.warn('failed to list files in dir:' . s:list_files_process['jobid' . a:id].dir) + endif +endfunction + +function! s:list_project_files(dir, cscope_files, cscope_db, load) abort + let jobid = s:JOB.start(['rg', '--color=never', '--files', a:dir], { + \ 'on_stdout' : function('s:list_files_stdout'), + \ 'on_exit' : function('s:list_files_exit') + \ }) + let s:list_files_process['jobid' . jobid] = { + \ 'jobid' : jobid, + \ 'dir' : a:dir, + \ 'cscope_files' : [], + \ 'cscope_db' : a:cscope_db, + \ 'load' : a:load, + \ 'cscope_files_path' : a:cscope_files + \ } endfunction "" " update all existing cscope databases in case that you disable cscope database " auto update. function! cscope#update_databeses() abort - call s:updateDBs(map(keys(s:dbs), 's:dbs[v:val].root')) + call s:updateDBs(keys(s:dbs)) endfunction @@ -159,12 +175,13 @@ endfunction " Create databases for current project function! cscope#create_databeses() abort let dir = SpaceVim#plugins#projectmanager#current_root() - call s:InitDB(dir) + call s:init_database(dir, 0) endfunction " 0 -- loaded " 1 -- cancelled +" 2 -- init db function! s:AutoloadDB(dir) abort let ret = 0 let m_dir = s:GetBestPath(a:dir) @@ -173,8 +190,8 @@ function! s:AutoloadDB(dir) abort let m_dir = input('', a:dir, 'dir') if m_dir !=# '' let m_dir = s:CheckAbsolutePath(m_dir, a:dir) - call s:InitDB(m_dir) - call s:LoadDB(m_dir) + call s:init_database(m_dir, 1) + let ret = 2 else let ret = 1 endif @@ -189,9 +206,8 @@ endfunction function! s:updateDBs(dirs) abort for d in a:dirs - call s:CreateDB(d, 0) + call s:create_database(d, 0, 0) endfor - call s:FlushIndex() endfunction @@ -201,21 +217,24 @@ function! cscope#clear_databases(...) abort silent cs kill -1 if a:0 == 0 let s:dbs = {} + call s:notify.notify('All databases cleared!', 'String') call s:RmDBfiles() else let dir = s:FILE.path_to_fname(a:1) - let id = s:dbs[dir]['id'] call delete(s:cscope_cache_dir. dir . '/cscope.files') call delete(s:cscope_cache_dir. dir . '/cscope.db') - unlet s:dbs[dir] - call s:echo('database cleared: ' . s:cscope_cache_dir. dir .'/cscope.db') + unlet s:dbs[a:1] + let message = 'databases cleared:' . a:1 + let s:notify.notify_max_width = strwidth(message) + 10 + call s:notify.notify(message, 'WarningMsg') + call s:logger.info('database cleared: ' . s:cscope_cache_dir. dir .'/cscope.db') call s:FlushIndex() endif endfunction " complete function for command :CscopeClear function! cscope#listDirs(A,L,P) abort - return map(keys(s:dbs), 's:dbs[v:val].root') + return keys(s:dbs) endfunction function! ToggleLocationList() abort @@ -234,11 +253,11 @@ function! ToggleLocationList() abort endfunction function! s:GetBestPath(dir) abort - let f = s:FILE.path_to_fname(a:dir) + let f = a:dir let bestDir = '' for d in keys(s:dbs) if stridx(f, d) == 0 && len(d) > len(bestDir) - return s:dbs[d].root + return d endif endfor return '' @@ -268,24 +287,27 @@ endfunction " 2. loadtimes: " 3. dirty: " 4. root: path of the project +" +" the argv: dir, load? +" +" if load == 1, the database will be loaded after init -function! s:InitDB(dir) abort +function! s:init_database(dir, load) abort + call s:logger.debug('start to init database for:' . a:dir) let id = localtime() - let dir = s:FILE.path_to_fname(a:dir) - let s:dbs[dir] = {} - let s:dbs[dir]['id'] = id - let s:dbs[dir]['loadtimes'] = 0 - let s:dbs[dir]['dirty'] = 0 - let s:dbs[dir]['root'] = a:dir - call s:CreateDB(a:dir, 1) - call s:FlushIndex() + 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 + let s:dbs[a:dir]['root'] = a:dir + call s:create_database(a:dir, 1, a:load) endfunction function! s:add_databases(db) abort exe 'silent cs add ' . a:db if cscope_connection(2, a:db) == 1 - call s:echo('cscope added: ' . a:db) + call s:logger.info('cscope added: ' . a:db) return 0 else return 1 @@ -296,26 +318,35 @@ function! s:LoadDB(dir) abort let dir = s:FILE.path_to_fname(a:dir) silent cs kill -1 call s:add_databases(s:cscope_cache_dir . dir .'/cscope.db') - let s:dbs[dir]['loadtimes'] = s:dbs[dir]['loadtimes'] + 1 + let s:dbs[a:dir]['loadtimes'] = s:dbs[a:dir]['loadtimes'] + 1 call s:FlushIndex() endfunction function! cscope#list_databases() abort let dirs = keys(s:dbs) + let databases = [] if len(dirs) == 0 - echo 'You have no cscope dbs now.' + call s:notify.notify('no cscope dbs now.', 'WarningMsg') + call s:notify.notify('Press SPC m c i to init.', 'WarningMsg') else - let s = [' PROJECT_ROOT LOADTIMES'] for d in dirs let id = s:dbs[d]['id'] if cscope_connection(2, s:cscope_cache_dir. d . '/cscope.db') == 1 - let l = printf('* %s %d', s:dbs[d].root, s:dbs[d]['loadtimes']) + " let l = printf('* %s %d', s:dbs[d].root, ) + let l = { + \ 'project' : '* ' .d, + \ 'loadtimes' : s:dbs[d]['loadtimes'] + \ } else - let l = printf(' %s %d', s:dbs[d].root, s:dbs[d]['loadtimes']) + let l = { + \ 'project' : ' ' .d, + \ 'loadtimes' : s:dbs[d]['loadtimes'] + \ } endif - call add(s, l) + call add(databases, l) endfor - echo join(s, "\n") + let table = s:box.drawing_table(s:JSON.json_encode(databases), ['project', 'loadtimes']) + echo join(table, "\n") endif endfunction @@ -336,9 +367,8 @@ function! cscope#preloadDB() abort let m_dir = s:CheckAbsolutePath(m_dir, m_dir) let m_key = s:FILE.path_to_fname(m_dir) if !has_key(s:dbs, m_key) - call s:InitDB(m_dir) + call s:init_database(m_dir, 1) endif - call s:LoadDB(m_dir) endfor endfunction @@ -364,33 +394,58 @@ function! cscope#onChange() abort endif endfunction -function! s:CreateDB(dir, init) abort +function! s:on_create_db_exit(id, data, event) abort + let d = s:create_db_process['jobid' . a:id].dir + if a:data !=# 0 + echohl WarningMsg | echo 'Failed to create cscope database for ' . d | echohl None + else + let s:dbs[d]['dirty'] = 0 + let message = 'database created for: ' . d + let s:notify.notify_max_width = strwidth(message) + 10 + call s:notify.notify(message, 'WarningMsg') + if s:create_db_process['jobid' . a:id].load + call s:LoadDB(d) + else + call s:FlushIndex() + endif + endif +endfunction + + +let s:create_db_process = {} + + +" argvs: +" dir: the path of project +" init: init database? +" load: load after init +function! s:create_database(dir, init, load) abort let dir = s:FILE.path_to_fname(a:dir) - let id = s:dbs[dir]['id'] let cscope_files = s:cscope_cache_dir . dir . '/cscope.files' let cscope_db = s:cscope_cache_dir . dir . '/cscope.db' - if ! isdirectory(s:cscope_cache_dir . dir) - call mkdir(s:cscope_cache_dir . dir) - endif - if !filereadable(cscope_files) || a:init - let files = s:ListFiles(a:dir) - call writefile(files, cscope_files) - endif try exec 'silent cs kill '.cscope_db catch endtry - let save_x = @x - 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 | echohl None - else - let s:dbs[dir]['dirty'] = 0 - call s:echo('database created: ' . cscope_db) + if !isdirectory(s:cscope_cache_dir . dir) + call mkdir(s:cscope_cache_dir . dir) endif - let @x = save_x + if !filereadable(cscope_files) || a:init + call s:list_project_files(a:dir, cscope_files, cscope_db, a:load) + endif +endfunction + +function! s:run_create_database_job(dir, cscope_files, cscope_db, load) abort + let jobid = s:JOB.start([g:cscope_cmd, '-b', '-i', a:cscope_files, '-f', a:cscope_db], { + \ 'on_exit' : function('s:on_create_db_exit') + \ }) + let s:create_db_process['jobid' . jobid] = { + \ 'jobid' : jobid, + \ 'dir' : a:dir, + \ 'load' : a:load, + \ 'cscope_db' : a:cscope_db, + \ } + endfunction "" diff --git a/bundle/cscope.vim/autoload/cscope/logger.vim b/bundle/cscope.vim/autoload/cscope/logger.vim deleted file mode 100644 index 431408af1..000000000 --- a/bundle/cscope.vim/autoload/cscope/logger.vim +++ /dev/null @@ -1,35 +0,0 @@ -let s:LOG = SpaceVim#api#import('logger') - -call s:LOG.set_name('cscope.vim') -call s:LOG.set_level(1) -call s:LOG.set_silent(1) -call s:LOG.set_verbose(1) - -function! cscope#logger#info(msg) - - call s:LOG.info(a:msg) - -endfunction - - -function! cscope#logger#view() - let info = "### cscope.vim runtime log :\n\n" - let info .= "```log\n" - - let info .= s:LOG.view(s:LOG.level) - - let info .= "\n```\n" - tabnew +setl\ nobuflisted - nnoremap q :bd! - for msg in split(info, "\n") - call append(line('$'), msg) - endfor - normal! "_dd - setl nomodifiable - setl buftype=nofile - setl filetype=markdown -endfunction - -function! cscope#logger#clear() abort - call s:LOG.clear(1) -endfunction diff --git a/bundle/cscope.vim/doc/cscope.vim.txt b/bundle/cscope.vim/doc/cscope.vim.txt index b0861bd9f..d0f51849f 100644 --- a/bundle/cscope.vim/doc/cscope.vim.txt +++ b/bundle/cscope.vim/doc/cscope.vim.txt @@ -4,10 +4,9 @@ Shidong Wang *cscope.vim* ============================================================================== CONTENTS *cscope.vim-contents* 1. Introduction...........................................|cscope.vim-intro| - 2. Configuration.........................................|cscope.vim-config| - 3. Commands............................................|cscope.vim-commands| - 4. KEY MAPPINGS....................................|cscope.vim-key-mappings| - 5. FAQ......................................................|cscope.vim-faq| + 2. Commands............................................|cscope.vim-commands| + 3. KEY MAPPINGS....................................|cscope.vim-key-mappings| + 4. FAQ......................................................|cscope.vim-faq| ============================================================================== INTRODUCTION *cscope.vim-intro* @@ -34,12 +33,6 @@ database. Cscove frees you from creating/connecting/updating cscope database, let you focus on code browsing. -============================================================================== -CONFIGURATION *cscope.vim-config* - - *g:cscope_silent* -Silent or not when run cscope command. by default it is 1. - ============================================================================== COMMANDS *cscope.vim-commands* diff --git a/bundle/cscope.vim/plugin/cscope.vim b/bundle/cscope.vim/plugin/cscope.vim index e3a30ce0a..e8731a44e 100644 --- a/bundle/cscope.vim/plugin/cscope.vim +++ b/bundle/cscope.vim/plugin/cscope.vim @@ -7,8 +7,6 @@ "============================================================================= if !exists('g:cscope_silent') - "" - " Silent or not when run cscope command. by default it is 1. let g:cscope_silent = 1 endif @@ -41,7 +39,7 @@ com! -nargs=? -complete=customlist,cscope#listDirs CscopeClear call cscope#clear " List all the cscope databases. com! -nargs=0 CscopeList call cscope#list_databases() -if exists('g:cscope_preload_path') +if exists('g:cscope_preload_path') && !empty(g:cscope_preload_path) call cscope#preloadDB() endif diff --git a/docs/cn/layers/cscope.md b/docs/cn/layers/cscope.md index cd2785ea3..fa59e0091 100644 --- a/docs/cn/layers/cscope.md +++ b/docs/cn/layers/cscope.md @@ -9,10 +9,10 @@ lang: zh - [模块描述](#模块描述) -- [模块特性](#模块特性) - [安装依赖及启用模块](#安装依赖及启用模块) - [安装 cscope](#安装-cscope) - [启用模块](#启用模块) +- [模块选项](#模块选项) - [快捷键](#快捷键) @@ -23,11 +23,6 @@ lang: zh 如果想要了解更多关于 cscope 和其它类似工具之间的区别,请阅读 [Comparison with Similar Tools](https://github.com/oracle/opengrok/wiki/Comparison-with-Similar-Tools) -## 模块特性 - -- 通过 cscope 为 C 和 C++ 建立索引,并提供查询功能 -- 通过 Pycscope 为 Python 建立索引,并提供查询功能 - ## 安装依赖及启用模块 ### 安装 cscope @@ -53,6 +48,13 @@ scoop install cscope name = "cscope" ``` +## 模块选项 + +- `cscope_command`: 设置 `cscope` 可执行命令的路径。 +- `auto_update`: 启用/禁用数据库自动更新,若启用,则在保存文件时自动更新数据库。 +- `open_location`: 启用/禁用自动打开搜索结果列表。 +- `preload_path`: 设置预加载的数据量路径。 + ## 快捷键 | 快捷键 | 功能描述 | diff --git a/docs/layers/cscope.md b/docs/layers/cscope.md index 268c9b59a..c34357676 100644 --- a/docs/layers/cscope.md +++ b/docs/layers/cscope.md @@ -7,26 +7,21 @@ description: "cscope layer provides a smart cscope and pycscope helper for Space -- [Description](#description) -- [Features](#features) +- [Intro](#intro) - [Install](#install) - [cscope](#cscope) - [layer](#layer) +- [Layer options](#layer-options) - [Key bindings](#key-bindings) -## Description +## Intro This layer provides a smart [Cscope](http://cscope.sourceforge.net/) and [PyCscope](https://github.com/portante/pycscope) helper for SpaceVim. For more info about the differences between Cscope and other similar tools, please read [Comparison with Similar Tools](https://github.com/oracle/opengrok/wiki/Comparison-with-Similar-Tools) -## Features - -- Tag indexing and searching for C-C++ via Cscope -- Tag indexing and searching for python via PyCscope - ## Install ### cscope @@ -50,6 +45,14 @@ To use this configuration layer, add it to your configuration file. name = "cscope" ``` +## Layer options + +- `cscope_command`: set the command or path of `cscope` executable. +- `auto_update`: enable/disable auto udpate when saving files. +- `open_location`: enable/disable open location list after searching. +- `preload_path`: set the proload paths. + + ## Key bindings | Key Binding | Description |