Skip to content

Commit

Permalink
Add cscope layer (liuchengxu#287)
Browse files Browse the repository at this point in the history
* Add cscope layer

Fix liuchengxu#130

* Add tips for cscope

* Change to nnoremap

* Update CHANGELOG.md

* Add async support for vim8

* Add async support for neovim

* Add is_building check

* A bit of refactor
  • Loading branch information
liuchengxu authored and Alvin committed Jan 31, 2019
1 parent f5ed03e commit a8ca002
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CHANGELOG

- `core/autoload/spacevim/plug/youcompleteme.vim`: keep the config.vim of `ycmd` layer as concise as possible.
- defer loading `YouCompleteMe` via `timer` if possible.
- cscope layer. Fix #130.

### Changed

Expand Down
10 changes: 9 additions & 1 deletion core/autoload/spacevim/plug/leaderGuide.vim
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@ let g:spacevim#plug#leaderGuide#lmap['b'] = {
\ '?' : ['Buffers', 'fzf-buffer'],
\ }
let g:spacevim#plug#leaderGuide#lmap['c'] = {
\ 'name' : '+comment',
\ 'name' : '+cscope',
\ 's' : ['call spacevim#vim#cscope#Find("symbol")', 'find-this-symbol'],
\ 'g' : ['call spacevim#vim#cscope#Find("global")', 'global-definition'],
\ 'c' : ['call spacevim#vim#cscope#Find("calls")', 'find-functions-calling-this-function'],
\ 't' : ['call spacevim#vim#cscope#Find("text")', 'text'],
\ 'e' : ['call spacevim#vim#cscope#Find("egrep")', 'egrep'],
\ 'f' : ['call spacevim#vim#cscope#Find("file")', 'find-this-file'],
\ 'i' : ['call spacevim#vim#cscope#Find("includes")', 'find-files-#include-this-file'],
\ 'd' : ['call spacevim#vim#cscope#Find("called")', 'find-functions-called-by-this-function'],
\ }
let g:spacevim#plug#leaderGuide#lmap['d'] = [ 'call feedkeys("\<C-d>")', 'scroll-down' ]
let g:spacevim#plug#leaderGuide#lmap['e'] = {
Expand Down
14 changes: 14 additions & 0 deletions core/autoload/spacevim/util.vim
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,17 @@ function! spacevim#util#ToggleHiddleAll()
setlocal showmode ruler showcmd laststatus=2 cmdheight=1
endif
endfunction

function! spacevim#util#RootDirectory()
if exists('*FindRootDirectory')
let root_dir = FindRootDirectory()
else
let git_dir = system('git rev-parse --git-dir')
if !v:shell_error
let root_dir = substitute(fnamemodify(git_dir, ':p:h'), ' ', '\\ ', 'g')
else
let root_dir = ''
endif
endif
return root_dir == '' ? getcwd() : root_dir
endfunction
107 changes: 107 additions & 0 deletions core/autoload/spacevim/vim/cscope.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
let s:is_building = 0

" Use s:add_db for both async callback and sync mode
function! s:add_db(channel)
" add any database in current directory
let db = findfile('cscope.out', '.;')
" :h cscope-suggestions
set nocsverb
if !empty(db)
" FIXME: when building cscope using job api at the first time, cscope.in.out won't be generated.
" Thus it raises errors when running `cs add`, use try-catch to rebuild cscope.
try
silent cs reset
silent! execute 'cs add' db
catch
call s:build_async(g:spacevim_cscope_cmd)
endtry
" else add database pointed to by environment
elseif !empty($CSCOPE_DB)
silent cs reset
silent! execute 'cs add' $CSCOPE_DB
else
call s:build_async(g:spacevim_cscope_cmd)
endif
set csverb
let s:is_building = 0
echo "\r\r"
endfunction

function! s:build_sync(...)
for cmd in a:000
call system(cmd)
endfor
call s:add_db('')
endfunction

function! s:on_exit_cb(job_id, data, event) dict
call s:add_db('')
endfunction

function! s:build_async(cmd)
let g:spacevim_cscope_cmd = a:cmd
if g:spacevim_nvim
let job = jobstart(['bash', '-c', a:cmd], { 'on_exit': function('s:on_exit_cb') })
else
let job = job_start(['bash', '-c', a:cmd], { 'close_cb': function('s:add_db') })
endif
endfunction

function! s:build()
let s:is_building = 1
let root_dir = spacevim#util#RootDirectory()
let exts = empty(a:000) ?
\ ['java', 'c', 'h', 'cc', 'hh', 'cpp', 'hpp'] : a:000

let tmp = tempname()
let cmd = "find ".root_dir." " . join(map(exts, "\"-name '*.\" . v:val . \"'\""), ' -o ')
let cmd1 = cmd.' | grep -v /test/ > '.tmp
let cmd2 = 'cscope -b -q -i'.tmp
try
if exists('*job_start') || exists('*jobstart')
call s:build_async(cmd1 . ' && ' . cmd2)
else
call s:build_sync(cmd1, cmd2)
endif
finally
silent! call delete(tmp)
endtry
endfunction

function! spacevim#vim#cscope#Build(...)
call s:build()
endfunction

function! spacevim#vim#cscope#UpdateDB()
if filereadable('cscope.out')
call s:build()
endif
endfunction

function! s:find(type)
if a:type == 'symbol'
:cs find s <cword>
elseif a:type == 'global'
:cs find g <cword>
elseif a:type == 'calls'
:cs find c <cword>
elseif a:type == 'text'
:cs find t <cword>
elseif a:type == 'egrep'
:cs find e <cword>
elseif a:type == 'file'
:cs find f <cfile>
elseif a:type == 'includes'
:cs find i <cfile>
elseif a:type == 'called'
:cs find d <cword>
endif
endfunction

function! spacevim#vim#cscope#Find(type)
if s:is_building
call spacevim#util#info('still building the cscope database, please wait for seconds...')
return
endif
call s:find(a:type)
endfunction
5 changes: 5 additions & 0 deletions core/ftplugin/qf.vim
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
nnoremap <buffer> q :cclose<bar>:lclose<CR>
nnoremap <buffer> <CR> <CR>
if exists('*SetMyStatusline')
call SetMyStatusline('')
endif
44 changes: 44 additions & 0 deletions layers/+tools/cscope/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# cscope layer

## Table of Contents

<!-- vim-markdown-toc GFM -->

* [Description](#description)
* [Install](#install)
* [Key Bindings](#key-bindings)
* [Tips](#tips)

<!-- vim-markdown-toc -->

## Description

This layer adds supports for cscope.

## Install

To use this configuration layer, add it to your `~/.spacevim`.

## Key Bindings

Key Binding | Mode | Description
:---: | :---: | :---:
<kbd>SPC c s</kbd> | Normal | find all references to the token under cursor
<kbd>SPC c g</kbd> | Normal | find global definition(s) of the token under cursor
<kbd>SPC c c</kbd> | Normal | find all calls to the function name under cursor
<kbd>SPC c t</kbd> | Normal | find all instances of the text under cursor
<kbd>SPC c e</kbd> | Normal | egrep search for the word under cursor
<kbd>SPC c f</kbd> | Normal | open the filename under cursor
<kbd>SPC c i</kbd> | Normal | find files that include the filename under cursor
<kbd>SPC c d</kbd> | Normal | find functions that function under cursor calls

## Tips

Use `:cc 2` (or any other number) to jump to, in this case, the second error in the quickfix window.

Put these settings in `UserConfig()` to configure cscope automatically when editing related files.

```vim
autocmd BufNewFile,BufRead *.c,*.h,*.hpp,*.cpp call spacevim#vim#cscope#Build()
autocmd BufNewFile,BufWritePost *.c,*.h,*.hpp,*.cpp call spacevim#vim#cscope#UpdateDB()
```
37 changes: 37 additions & 0 deletions layers/+tools/cscope/config.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
" :h cscope
"
" USAGE :cs find {querytype} {name}
"
" 0 or s: Find this C symbol
" 1 or g: Find this definition
" 2 or d: Find functions called by this function
" 3 or c: Find functions calling this function
" 4 or t: Find this text string
" 6 or e: Find this egrep pattern
" 7 or f: Find this file
" 8 or i: Find files #including this file
" 9 or a: Find places where this symbol is assigned a value

" 's' symbol: find all references to the token under cursor
" 'g' global: find global definition(s) of the token under cursor
" 'c' calls: find all calls to the function name under cursor
" 't' text: find all instances of the text under cursor
" 'e' egrep: egrep search for the word under cursor
" 'f' file: open the filename under cursor
" 'i' includes: find files that include the filename under cursor
" 'd' called: find functions that function under cursor calls

" cscope databases are searched first, followed by tag files if cscope did not return any matches.
set csto=0
" always search cscope database as well as tag files.
set cscopetag
set cscopequickfix=s-,c-,d-,i-,t-,e-,a-

nnoremap <leader>cs :call spacevim#vim#cscope#Find('symbol')<CR>
nnoremap <leader>cg :call spacevim#vim#cscope#Find('global')<CR>
nnoremap <leader>cc :call spacevim#vim#cscope#Find('calls')<CR>
nnoremap <leader>ct :call spacevim#vim#cscope#Find('text')<CR>
nnoremap <leader>ce :call spacevim#vim#cscope#Find('egrep')<CR>
nnoremap <leader>cf :call spacevim#vim#cscope#Find('file')<CR>
nnoremap <leader>ci :call spacevim#vim#cscope#Find('includes')<CR>
nnoremap <leader>cd :call spacevim#vim#cscope#Find('called')<CR>
1 change: 1 addition & 0 deletions layers/+tools/cscope/packages.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MP 'romainl/vim-qf'

0 comments on commit a8ca002

Please sign in to comment.