Vim, Ctags and Cscope
You have been given a project folder with the code spread over multiple files (maybe even nested in sub-folders). Now, you wish to add a new feature to this project. But before you can start scribbling down your algorithm and making changes, you need to understand the code. Vim coupled with Ctags and Cscope can help you do exactly that. Ctags helps you jump from function/symbol instances to their definitions and Cscope does the opposite i.e. you can see the entire call hierarchy of a particular function (where all the function is called). The tutorials for setting up Cscope were a bit tricky and I wanted to document my set of steps here. So here is how to set up your tools:
- The Vim editor
Install using:sudo apt-get install vim
I am assuming you know how to use vim. If not then there are plenty of tutorials on the internet to get you started with vim.
- Ctags
sudo apt-get install exuberant-ctags
After installing ctags, navigate inside the project folder and do
ctags -R ./*
This will generate tags (they help you find the function definitions from their instances) for your entire code. Now from this same directory (do not change your directory), open a code file in vim
vim ./main.c
Say inside your main code you see a call to function “calculate” which is defined in some other file in your current folder (or sub-folder). Then move your cursor over “calculate” and press the CTRL; while keeping CTRL pressed hit ] key. You’ll find yourself in the function definition of “calculate”. We’ll call this pressing of CTRL and then ] key while holding CTRL down as CTRL+]. To go back use CTRL+t.
- Cscope
Install cscopesudo apt-get install cscope
Now open/create a “.vimrc” file in you home directory using:
vim ~/.vimrc
Append the following in this file
if has("cscope") set csprg=/usr/bin/cscope set csto=0 set cst set nocsverb " add any database in current directory if filereadable("cscope.out") cs add cscope.out " else add database pointed to by environment elseif $CSCOPE_DB != "" cs add $CSCOPE_DB endif endif nmap <C-\>s :cs find s =expand("") nmap <C-\>g :cs find g =expand("") nmap <C-\>c :cs find c =expand("") nmap <C-\>t :cs find t =expand("") nmap <C-\>e :cs find e =expand("") nmap <C-\>f :cs find f =expand("") nmap <C-\>i :cs find i ^=expand("")$ nmap <C-\>d :cs find d =expand("") set nohlsearch
In your code folder do
cscope -Rb
Open a file, say main.c and take your cursor on a function name and press CTRL; while holding down CTRL press \ key, now release both and hit c. So the combo will be CTRL+\ (release both) c. It should now show you where all this function has been called. If the list is long, hit q and type the number where you want to go. To return from here use CTRL+t. In order to look for a symbol (variable name) use the combo CTRL+\ (release both) s. You can make out the other combos from the nmap statements in the .vimrc file.
These tools can prove to be extremely useful in case you are working on a server or a machine with limited resources. Alternatively you can use Eclipse with the CDT bundle.
If you wish to use Eclipse with the CDT bundle to explore/edit code which is on a remote system then you can mount the remote directory using the command:
sshfs login@remote.server.ip:/path/to/remote/directory /path/to/local/directory/or/mount/point
fusermount -u /path/to/mount/point/for/unmounting
Another alternative to access remote files using eclipse would be to install the Eclipse RSE plugin. For this, simply search for eclipse RSE and download the latest stable release. Copy the contents of features and plugins directory into corresponding eclipse folder (eclipse installation folder in windows and .eclipse folder at linux home). Launch eclipse now and then Window -> Show view -> Other -> Remote systems -> remote systems. Right click local and select New -> connection. Enter IP, select ssh.files, processes.shell.linux, ssh.shells, ssh.terminals. Finish. Select sftp files, My Home. Enter password when prompted! Voila, you can now access files over network. What’s more, you can right click ssh terminals and select launch terminal within eclipse to compile/test your code.
Appendix
My Vim cheat sheet: This is a list of commands which I most frequently use on vim
i to insert
:wq save and quit
:tabe path/filename to open in new tab
:set mouse =a to use mouse
:tabn or :tabp to move between tabs or simply click
:wa save all open tabs
/string to search
gg move to top
GG move to bottom
A append at end of line
yy copy/yank one line
y3 copy 3lines
p paste at end of current line
Cut a section of words:- v to begin selecting, d to end and cut, p to paste