Everytime after load a cscope.out in Vim, I need to change Vim's "pwd" to the same directory as cscope.out file is under, which might be due to that cscope use relative path when generating tag file. So if there is a way to force cscope to use absolute path in its tag file - cscope.out, then it will be regardless of whether the pwd of your Vim session is the same as the directory that cscope.out file is under.
You can ask vim to interpret the paths in cscope.out relative to the location of the cscope.out file by setting the cscoperelative option.
From :help 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).
Examples
: set csre
: set nocsre
When importing cscope.out, you can supply the prefix, i.e.
:cscope add /path/to/cscope.out /path/to/src/code
Then your searches will turn up like:
Cscope Tag: foobar
# line filename / context / line
1 21 /path/to/src/code/foobar_file.c
The cscope tutorial has a very simple workaround for this problem:
11.Try setting the $CSCOPE_DB environment variable to point to a Cscope database you create, so you won't always need to launch Vim in
the same directory as the database. This is particularly useful for
projects where code is split into multiple subdirectories. Note: for
this to work, you should build the database with absolute pathnames:
cd to /, and do
find /my/project/dir -name '*.c' -o -name '*.h' > /foo/cscope.files
Then run Cscope in the same directory as the cscope.files file (or use
'cscope -i /foo/cscope.files'), then set and export the $CSCOPE_DB
variable, pointing it to the cscope.out file that results):
cd /foo
cscope -b
CSCOPE_DB=/foo/cscope.out; export CSCOPE_DB
(The last command above is for Bourne/Korn/Bash shells: I've forgotten
how to export variables in csh-based shells, since I avoid them like
the plague).
You should now be able to run 'vim -t foo' in any directory on your
machine and have Vim jump right to the definition of 'foo'. I tend to
write little shell scripts (that just define and export CSCOPE_DB) for
all my different projects, which lets me switch between them with a
simple 'source projectA' command.
You can create your cscope.files using absolute paths to your files, here is my scripts to generate my cscope databases
#!/bin/sh
find $PWD -name '*.[ch]' -exec echo \"{}\" \; | sort -u > cscope.files
cscope -bvq
Then just vim cscope.files and maybe :cs add cscope.out, although my cscope plugin does that automatically. Then I search for the files I am interested in and jump to them with gf.
#Aaron H. is right.
For my configuration I used the cscope_maps.vim plugin and modified the following lines:
40 " add any cscope database in current directory
41 if filereadable("/usr/project/cscope.out")
42 cs add /usr/project/cscope.out /usr/project
43 " else add the database pointed to by environment variable
44 elseif $CSCOPE_DB != ""
45 cs add $CSCOPE_DB
46 endif
Where "/usr/project" is the location of the cscope.out file and the absolute path I want to use.
Note: since I am not senior enough to add comments yet:
Aaron and Neha's answers were useful to me to learn more about the entire system, but the best and most direct answer to the question is currently in 3rd place and is Shayan's.
The asker was more asking about getting absolute pathnames by cscope, not working around it using (the very capable and powerful) vim.
Note2: There is another way to make a single change in vim and accomplish the same as what Neha did.
:set cscopeprg=cscope -P path_to_relative_base
I like Neha's better, but this way is closer to modifying cscope rather than vim settings, if this is what you want. And this is the only way that allows you to move the cscope db to anywhere.
Related
It is several years I am programming with vim and I used ctags.
I am working with a reasonably large C/C++ package and I need to find definition of functions. I usually use grep + ctags.
Recently I tried to use cscope instead of ctags and installed it with Vundle.
I see the following error for some of my files
E568: duplicate cscope database not added
I searched the web and found this:
https://blogs.oracle.com/natarajan/entry/avoiding_duplicate_cscope_database_error
It doesn't work.
How can I fix this?
Expanding on Artem's answer:
The Vim help for cscopeverbose is as follows:
If 'cscopeverbose' is not set (the default), messages will not be printed
indicating success or failure when adding a cscope database. Ideally, you
should reset this option in your .vimrc before adding any cscope databases,
and after adding them, set it. From then on, when you add more databases
within Vim, you will get a (hopefully) useful message should the database fail
to be added.
The problem here is that (a) there are multiple scripts attempting to load the cscope.out file and (b) they're not following the best practices of disabling the "verbose" cscope warnings before loading the file then re-enabling it afterwards, as suggested by the help text above.
The full error output should tell you which script is triggering this warning; for me it looked like this:
Error detected while processing /home/me_and/.vim/plugin/cscope_maps.vim:
line 42:
E568: duplicate cscope database not added
The fix was then to edit the ~/.vim/plugin/cscope_maps.vim file to add set nocscopeverbose immediately before the cs add ... lines. My version of this file already had set cscopeverbose immediately after, but if yours doesn't you should add that too.
Found the solution which worked for me (here: http://thoughtsolo.blogspot.com/2014/02/cscope-issue-duplicate-cscope-database.html):
Just add this line "set nocscopeverbose " to your ~/.vimrc file.
As per the blog, "This error pops up when VIM is already compiled with 'CSCOPE' module and you have also installed "cscopemenu.vim"". I assume that you have a vim executable with has been configured with --enable-cscope option.
Here's what I do:
Download cscope source and build it, install the executable in a directory which is available in your PATH
Download vim source code and configure it with --enable-cscope, build the source and install the executable
Download cscope_maps.vim and place it under $HOME/.vim/plugin directory. This contains cscope settings for vim.
Create cscope database out of the source and header files. You may do something like the following
find $PROJECT_HOME -name *.c -o -name "*.cpp" -o -name "*.cc" -o -name "*.h" -o -name "*.hpp" > cscope.files
cscope -qbR -i cscope.files
You can add these commands in an alias and excute the alias every time you want to update your cscope database. These two commands create finally create cscope.out database file.
Update .vimrc file to have the following
if has("cscope")
set csprg=<location to cscope executable>
set csto=0
cs add <location to cscope.out>
endif
I hope after doing these steps you should be able to use cscope with vim easily.
Note that if you are working on multiple projects, you should be able to add appropriate environment variables to enable vim to pick the correct cscope database.
To answer your second question, may I suggest using tagbar. This will list your function names in the current source or header file. You can install it using Vundle. Add the following line to your .vimrc
Plugin 'majutsushi/tagbar'
Add this to your .vimrc to toggle tagbar view
nmap <F4> :TagbarToggle<CR>
Note that F4 is just an example and you may use any binding to do the same.
I am using cscope on a project which locates in author/trunk/ .
Under "author" directory cscope -R worked well and generated cscope.out. However when using same commmand on a subdirectory like author/trunk/../dhcp, no cscope .out was generated ,and had "no cscope connection" when I wanted to search in one file
So what should I do now ,THanks
First, I recommend using cscope -bkqR instead of the simpler cscope -R.
Second, I think you need to start cscope in the same directory where cscope.out is located or you'll get the error you mentioned. At least, this is true for vim.
I have a project as follows:
/dir
dir1
dir2 -> symbolic-link to /otherdir
file1
tags *
I want vim to use THIS tags file which includes tags for files in dir1 and dir2.
When I edit file1, VIM cannot find the correct tags file.
I have the following setup in .vimrc:
set tags=tags;/
Is there a way to keep this file structure without explicitly telling VIM the absolute path to tags?
You can append to the same ctags other tags, so for example if you want to ctag everything inside dir1 you would execute:
ctags -R *
and if you want to add some other tags from dir two:
ctags -R -a ~/path/to/dir2/*
-a is for appending.
Now what I do to always have my ctags no matter where I open my vim, is to add this line in my .vimrc:
set tags+=./tags;$HOME
this will look for tags in the current directory and will go down recursively to your home folder, if you would like it to search until the root folder or less just change $HOME for / or /path/to/root/project/
With this line in my ~/.vimrc and a similar layout as yours, tags related features (:ts, <C-]>, etc.) use the same tags file situated at the root of dir, alongside dir1 and dir2.
set tags=./tags,tags;$HOME
The tags file is first searched in the current file's directory, then in the cwd, then upwards until it reaches $HOME.
What does :echo tagfiles() say when you are editing file1? Here it says ['/home/romainl/Desktop/dir0/tags'].
EDIT
Throwing a symlink doesn't seem to change anything.
ENDEDIT
I think it's just a question of being in the right directory. When you start working in this project, use :cd /dir to get into the directory with the tags file, and make sure the autochdir option is turned off. Then when you edit a file inside dir2, the working directory will still be dir, and it will still find the same tags file.
If, on the other end, you end up with dir/dir2 as your working directory, that will actually mean you're in /otherdir, so when Vim looks for the tags file from there, it can't find it in that directory or in / . I suspect that's what's happening to you now.
You can see what directory you're in at any time with the :pwd command, just like in the shell.
I'm new to vim and wanted to get ctags integration working so I can more easily navigate a large java project.
I've pulled down the zip from source forge and extracted it but from here I'm not sure how to get it working with vim
Any help for a novice vim user would be great!
As nobody has given one critical function in these answers, I'll provide one more slightly superior answer.
The easiest way to use ctags with vim is by calling:
ctags -R *
from the root of your source repository. This will generate a tags file in that same directory.
In your ~/.vimrc file, add this short block:
" ctags optimization
set autochdir
set tags=tags;
" denotes a comment. set autochdir tells vim that if it doesn't find a tags file in the $PWD it will look in the directory parent for the tags file, recursively. set tags=tags; tells vim that the name of your tags file will always be the same as the default tags file generated by ctags.
So long as you run ctags -R * in your root source directory the first time and occasionally to update it (if you pull new changes from others) then you'll always have a fast and intuitive ctags symbol lookup in vim.
Using exuberant ctags, I use something like this in my project's base directory (excluding the "log" directory):
ctags -R --exclude=log *
You have to run the ctags command with the source files as arguments. This will create a tags file containing all information. Then you can open a file with vim, and e.g. press Ctrl-] when on a line with a function to jump to the code of that function. If vi isn't started in the same directory as the tag file, you can set it with :set tags=<file>
This is what I'm doing:
ctags -n -f [OUTPUT] [SOURCE] to generate the tags (NOTE: the -n applies to me but may not be necessary for your usage)
exec "set tags=" . [OUTPUT] inside of .vimrc to let vim become of aware of the tags
EDIT: I'm using
Exuberant Ctags 5.5.2
VIM 6.1
Additional info:
See ctags usages here
Tips and tricks from SO
look at this article: vim-easytags. i haven't tried this, but it looks quite good. manually creating and updating tags was really annoying. hope this will help. :)
I have a folder containing hundreds of TTL (TeraTermLanguage) files.
Now I wanted indent all these files.
I have created teraterm.vim for indentation and I open a file using VIM and do "gg=G" and whole file gets indented properly.
But is there any way, where I can indent all the files in folder.
I wanted to do with help of Shell. But in VIM I couldnt pass file indent command as the argument to VIM.
Please suggest which is the best way I can do indentation to all the files in VIM.
Much simpler than scripting vim from the bash command line is to use vimscript from inside of vim (or perhaps a much simpler one-liner for scripting vim from the command line). I personally prefer using the arg list for all multi-file manipulation. For example:
:args ~/src/myproject/**/*.ttl | argdo execute "normal gg=G" | update
args sets the arglist, using wildcards (** will match the current directory as well as subdirectories)
| lets us run multiple commands on one line
argdo runs the following commands on each arg (it will swallow up the second |)
execute prevents normal from swallowing up the next pipe.
normal runs the following normal mode commands (what you were working with in the first place)
update is like :w, but only saves when the buffer is modified.
This :args ... | argdo ... | update pattern is very useful for any sort of project wide file manipulation (e.g. search and replace via %s/foo/bar/ge or setting uniform fileformat or fileencoding).
(other people prefer a similar pattern using the buffer list and :bufdo, but with the arg list I don't need to worry about closing current buffers or opening up new vim session.)
Open up a terminal. Type:
$ vim -w indentme.scr foo.c
Then, type this exactly (in command mode):
gg=G:wq
This will close vim, saving the process of indenting all lines in the file to a Vim script called indentme.scr.
Note: indentme.scr will contain a record of all key commands typed, so when you are done indenting the file, don't spend a lot of time using the arrow keys to look around the file, because this will lead to a much larger script and will severely slow down batch operations.
Now, in order to indent all the lines in a file, just type the following command:
$ vim -s indentme.scr unindented-file.c
Vim will flash open-shut (if you're on a fast computer and not editing a huge file), indenting all lines, then saving the file in-place.
Unfortunately, this will only work on one file at a time, but you can scale the functionality easily using sh's for loop:
for filename in *.ttl ; do
vim -s indentme.scr "$filename"
done
Note: This will save-over any file. Unless set bk is in your ~/.vimrc, don't expect a backup to be saved.
I went off of amphetamachine's solution. However, I needed to recursively search through multiple directories. Here's the solution that I used:
$ find . -type f -name '*.ttl' -exec vim -s indentme.scr "{}" \;
Taking reference from the above answers I would like to make this complete.
I will start from the scratch so that a beginner can understand.
Step-1
Install astyle (tool used for formatting ) by using the following command
Open up a terminal. Type:
sudo apt-get install astyle
Step-2 Make sure you have vim installed on your system.Run the below commands from the directory in which your code files are.The below command will create a script that we intend to run recursively so as to beautify each and every file in our directory.(as mentioned in the above answer)
vim -w indentme.scr foo.c
Step-3 Then, type this exactly (in command mode) and press enter
:%!astyle
Step-4Then type this exactly (in command mode) and press enter
:wq
Step-5 Last run this recursively by the following command:
find . -type f -name '*.cpp' -exec vim -s indentme.scr "{}" \;
All your cpp files will be formatted properly.