If_cscop

Nvim :help pages, generated from source using the tree-sitter-vimdoc parser.


Cscope Cscope is a "code intelligence" tool that helps you navigate C programs. It can also perform some refactoring tasks, such as renaming a global variable in all source files. Think of it as "ctags on steroids".
See cscope-usage for a quickstart.

Cscope introduction cscope-intro

Cscope is designed to answer questions like: Where is this symbol used? Where is it defined? Where did this variable get its value? What is this global symbol's definition? Where is this function in the source files? What functions call this function? What functions are called by this function? Where does the message "out of space" come from? Where is this source file in the directory structure? What files include this header file?
Cscope answers these questions from a symbol database that it builds the first time it is used on the source files. On a subsequent call, cscope rebuilds the database only if a source file has changed or the list of source files is different. When the database is rebuilt the data for the unchanged files is copied from the old database, which makes rebuilding much faster than the initial build.
See cscope-usage to get started.

Cscope commands cscope-commands

:cscope :cs :scs :scscope E259 E262 E560 E561 All cscope commands are accessed through suboptions to the cscope commands. :cscope or :cs is the main command :scscope or :scs does the same and splits the window :lcscope or :lcs uses the location list, see :lcscope
The available subcommands are:
E563 E564 E566 E568 E622 E623 E625 E626 E609 add : Add a new cscope database/connection.
USAGE :cs add {file|dir} [pre-path] [flags]
[pre-path] is the pathname used with the -P command to cscope.
[flags] are any additional flags you want to pass to cscope.
EXAMPLES
:cscope add /usr/local/cdb/cscope.out
:cscope add /projects/vim/cscope.out /usr/local/vim
:cscope add cscope.out /usr/local/vim -C
cscope-find cs-find E567 find : Query cscope. All cscope query options are available except option #5 ("Change this grep pattern").
USAGE :cs find {querytype} {name}
{querytype} corresponds to the actual cscope line interface numbers as well as default nvi commands:
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
For all types, except 4 and 6, leading white space for {name} is removed. For 4 and 6 there is exactly one space between {querytype} and {name}. Further white space is included in {name}.
EXAMPLES
:cscope find c vim_free
:cscope find 3  vim_free
These two examples perform the same query: functions calling "vim_free".
:cscope find t initOnce
:cscope find t  initOnce
The first one searches for the text "initOnce", the second one for " initOnce".
:cscope find 0 DEFAULT_TERM
Executing this example on the source code for Vim 5.1 produces the following output:
Cscope tag: DEFAULT_TERM # line filename / context / line 1 1009 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"amiga" 2 1013 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"win32" 3 1017 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"pcterm" 4 1021 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"ansi" 5 1025 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"vt52" 6 1029 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"os2ansi" 7 1033 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"ansi" 8 1037 vim-5.1-gtk/src/term.c <<GLOBAL>> # undef DEFAULT_TERM 9 1038 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"beos-ansi" 10 1042 vim-5.1-gtk/src/term.c <<GLOBAL>> #define DEFAULT_TERM (char_u)"mac-ansi" 11 1335 vim-5.1-gtk/src/term.c <<set_termname>> term = DEFAULT_TERM; 12 1459 vim-5.1-gtk/src/term.c <<set_termname>> if (STRCMP(term, DEFAULT_TERM)) 13 1826 vim-5.1-gtk/src/term.c <<termcapinit>> term = DEFAULT_TERM; 14 1833 vim-5.1-gtk/src/term.c <<termcapinit>> term = DEFAULT_TERM; 15 3635 vim-5.1-gtk/src/term.c <<update_tcap>> p = find_builtin_term(DEFAULT_TERM); Enter nr of choice (<CR> to abort):
The output shows several pieces of information: 1. The tag number (there are 15 in this example). 2. The line number where the tag occurs. 3. The filename where the tag occurs. 4. The context of the tag (e.g., global, or the function name). 5. The line from the file itself.
help : Show a brief synopsis.
USAGE :cs help
E261 kill : Kill a cscope connection (or kill all cscope connections).
USAGE :cs kill {num|partial_name}
To kill a cscope connection, the connection number or a partial name must be specified. The partial name is simply any part of the pathname of the cscope database. Kill a cscope connection using the partial name with caution!
If the specified connection number is -1, then _ALL_ cscope connections will be killed.
reset : Reinit all cscope connections.
USAGE :cs reset
show : Show cscope connections.
USAGE :cs show
:lcscope :lcs This command is same as the ":cscope" command, except when the 'cscopequickfix' option is set, the location list for the current window is used instead of the quickfix list to show the cscope results.
:cstag E257 E562 If you use cscope as well as ctags, :cstag allows you to search one or the other before making a jump. For example, you can choose to first search your cscope database(s) for a match, and if one is not found, then your tags file(s) will be searched. The order in which this happens is determined by the value of csto. See cscope-options for more details.
:cstag performs the equivalent of ":cs find g" on the identifier when searching through the cscope database(s).
:cstag performs the equivalent of :tjump on the identifier when searching through your tags file(s).

Cscope options cscope-options

Use the :set command to set all cscope options. Ideally, you would do this in one of your startup files (e.g., vimrc). Some cscope related variables are only valid within init.vim. Setting them after vim has started will have no effect!
cscopeprg csprg 'cscopeprg' specifies the command to execute cscope. The default is "cscope". For example:
:set csprg=/usr/local/bin/cscope
cscopequickfix csqf E469 'cscopequickfix' specifies whether to use quickfix window to show cscope results. This is a list of comma-separated values. Each item consists of cscope-find command (s, g, d, c, t, e, f, i or a) and flag (+, - or 0). '+' indicates that results must be appended to quickfix window, '-' implies previous results clearance, '0' or command absence - don't use quickfix. Search is performed from start until first command occurrence. The default value is "" (don't use quickfix anyway). The following value seems to be useful:
:set cscopequickfix=s-,c-,d-,i-,t-,e-,a-
cscopetag cst If 'cscopetag' is set, the commands ":tag" and CTRL-] as well as "vim -t" will always use :cstag instead of the default :tag behavior. Effectively, by setting 'cst', you will always search your cscope databases as well as your tag files. The default is off.
cscoperelative csre If 'cscoperelative' is set, then in absence of a prefix given to cscope (prefix is the argument of -P option of cscope), basename of cscope.out location (usually the project root directory) will be used as the prefix to construct an absolute path. The default is off. Note: This option is only effective when cscope (cscopeprg) is initialized without a prefix path (-P).
cscopetagorder csto The value of 'csto' determines the order in which :cstag performs a search. If 'csto' is set to zero, cscope database(s) are searched first, followed by tag file(s) if cscope did not return any matches. If 'csto' is set to one, tag file(s) are searched before cscope database(s). The default is zero.
cscopepathcomp cspc 'cscopepathcomp' determines how many components of a file's path to display. With the default value of zero the entire path will be displayed. The value one will display only the filename with no path. Other values display that many components. For example:
:set cscopepathcomp=3
will display the last 3 components of the file's path, including the file name itself.

Using cscope in Nvim cscope-usage cscope-howtouse

To get started, build the cscope database in your project root directory:
cscope -bcqR
See the cscope manpage for details:
:Man cscope
By default the cscope database file is named "cscope.out". After building the database, connect to it from Nvim:
:cscope add cscope.out
That establishes a cscope connection for Nvim to use. You can check the result with ":cs show". It will show something like:
# pid database name prepend path 0 28806 cscope.out <none>
Once a cscope connection is established, you can make queries to cscope and the results will be printed. Queries are made using the command ":cs find". For example:
:cs find g ALIGN_SIZE
To make this easier you can configure mappings, see cscope-suggestions.
If the results return only one match, you will automatically be taken to it. If there is more than one match, you will be given a selection screen to pick the match you want to go to. After you have jumped to the new location, simply hit Ctrl-T to get back to the previous one.

Limitations cscope-limitations

Hard-coded limitation: doing a :tjump when :cstag searches the tag files is not configurable (e.g., you can't do a tselect instead).

Sample config cscope-suggestions

Copy this into your init.vim (adjust paths for your system):
if has("cscope")
        set csprg=/usr/local/bin/cscope
        set csto=0
        set cst
        " add any database in current directory
        if filereadable("cscope.out")
            silent cs add cscope.out
        " else add database pointed to by environment
        elseif $CSCOPE_DB != ""
            silent cs add $CSCOPE_DB
        endif
endif
By setting 'cscopetag', we have effectively replaced all instances of the :tag command with :cstag. This includes :tag, Ctrl-], and "vim -t". In doing this, the regular tag command not only searches your ctags generated tag files, but your cscope databases as well.
Some users may want to keep the regular tag behavior and have a different shortcut to access :cstag. For example, one could map Ctrl-_ (underscore) to :cstag with the following command:
map <C-_> :cstag <C-R>=expand("<cword>")<CR><CR>
A couple of very commonly used cscope queries (using ":cs find") is to find all functions calling a certain function and to find all occurrences of a particular C symbol. To do this, you can use these mappings as an example:
map g<C-]> :cs find 3 <C-R>=expand("<cword>")<CR><CR>
map g<C-\> :cs find 0 <C-R>=expand("<cword>")<CR><CR>
These mappings for Ctrl-] (right bracket) and Ctrl-\ (backslash) allow you to place your cursor over the function name or C symbol and quickly query cscope for any matches.
Or you may use the following scheme, inspired by Vim/Cscope tutorial from Cscope Home Page (http://cscope.sourceforge.net/):
nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>a :cs find a <C-R>=expand("<cword>")<CR><CR>

" Using 'CTRL-spacebar' then a search type makes the vim window
" split horizontally, with search result displayed in
" the new window.

nmap <C-Space>s :scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>g :scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>c :scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>t :scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>e :scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>f :scs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-Space>i :scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-Space>d :scs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>a :scs find a <C-R>=expand("<cword>")<CR><CR>

" Hitting CTRL-space *twice* before the search type does a vertical
" split instead of a horizontal one

nmap <C-Space><C-Space>s
        \:vert scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>g
        \:vert scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>c
        \:vert scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>t
        \:vert scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>e
        \:vert scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>i
        \:vert scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-Space><C-Space>d
        \:vert scs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>a
        \:vert scs find a <C-R>=expand("<cword>")<CR><CR>
Main
Commands index
Quick reference