How to ignore struct declarations and consider only definitions in cscope? - vim

I always use vim + cscope to check symbol definition, and I find cscope always take declaration like:
struct sk_buff;
as a definition, which make vim always show a long list files to choose. Indeed, I only want the definition:
struct sk_buff {
...
};
Seems ctags can resolve this problem, but can cscope handle this? Or somethings I'm wrong.
I checked the cscope source, and I find it's hard to modify the lex and yacc source from beginning.

You are correct, you cannot do this just with cscope.
I use cscope+ctags with vim every day on both small and large projects as well.
I've found the most productive way to use these tools is to use them both from within vim and with the cscope_maps.vim plugin.
This may not help you but it's helped me int he past, check this site for information on using them together. I'll warn you that if you use the cscope_maps.vim plugin you'll probably want to edit it and comment out the "set cscopetag" option.

Related

Vim c++ indexing that differentiates between symbols with same names

I've been trying out vim with exuberant tags and cscope but when listing the usages of a variable it also lists variables with the same name that aren't really the symbol I'm looking at. For example if I want to jump to the declaration or other usages of a variable called "temp", it will give me all variables called "temp" in the whole repo. Am I using tags and cscope wrong or is there another plugin I should be using instead?
Ctags and cscope use parsers and even regular expressions to find symbols in files. They "understand" syntax, in a way, but they don't understand code so they have no idea about what specific function is called where.
Consequently…
that relationship is not encoded in the resulting database,
and it is lost to any program using ctags or cscope.
If you want a tool that knows exactly which temp is referenced, then you don't want csope or ctags. You want something based on a compiler, like clang.

Vim: How to go to the declaration of a C++ method using ctags

How do I jump to the declaration of a C++ method instead of the definition using :tag or C-]? I tried
ctags * --C++-kinds=+p
to generate the tags file but :tselect still does not list any declarations, only definitions. The header files are hpp files and source files are cpp files, all in the same directory.
I have seen this answer but it does not answer my question, except for a comment from where I got the above idea (--<LANG>-kinds).
I'm using the following options: --c++-kinds=+pf --fields=+imaSft --extras=+q. Among many other things, I see function definitions and function declarations.
I handle everything automatically in a plugin I've been maintaining for quite some time.
On the same subject, see also:
Jump to function definition in vim
Vim Plugin to Resolve a Member Function More Efficiently Using Ctags
BTW, I highly recommend using universal-ctags (the maintained fork) instead of exhuberant ctags (the venerable and unmaintained project) when trying to generate tags for C++.

Making AutoComplPop search entire project (or open buffers)?

I started using AutoComplPop for automatic code completions. It works great on the single file I am editing, but if file1 is making a reference to a method defined in file2, it doesn't find it.
The docs don't specify if there is a way to make it search a whole project directory, or even just all open buffers, so I can't tell if this is simply not something the plugin does, or if I need to enable something.
I was testing it out on two Ruby files, if that's relevant. Thanks!
Looks like that the cause of the problem is that ACP set the complete option for its purposes to .,w,b,k (see line #125 in autocomplpop/plugin/acp.vim),
call l9#defineVariableDefault('g:acp_completeOption', '.,w,b,k')
while the default value that is used when pressing \<C-n> is .,w,b,u,t,i. And it appears that the very last letter i actually makes the difference: for some reason vim would not use word from an include file opened in a buffer to complete words in another buffer. So, b option is not enough, i must also be included. Adding the following line into my .vimrc helped
let g:acp_completeOption = '.,w,b,u,t,i'
At least it worked for C++ files, but I'm not sure it fixes the problem for the case of Ruby scripts.
Depending on what is on the left of the cursor, ACP (like all the alternatives) decides what completion mechanism to use.
But ACP only uses Vim's default completion mechanisms: if <C-x><C-o> and <C-n>/<C-p> don't provide what you are looking for, ACP won't help. Try them out first.
Oh cool, this plugin looks a lot like neocomplcache but maybe cleaner...looks a little old. Little concerning that there are so many open tickets on that project and no updates in two years.
Anyway, according to the documentation it doesn't...really...say. Very likely its one of the following things:
Your pwd. If the root directory for your source is some/path then that should also be your current working directory. Try typing :cd some/path to see if that makes a difference.
The runtime path rtp. See if adding the directory with your source files to &rtp does the trick.
The path. Same deal as the &rtp setting.
Very likely this plugin is just falling back on the built in ruby omni completion functions bundled with vim. Try help ft-ruby-omni.
I just had the same problem, and I actually found a solution for this.
Apparently you have to set in your .vimrc file the following:
let g:acp_behaviorKeywordCommand = "\<C-x>\<C-i>"
This will make acp look in every file included by your source for completions, as if you were actually typing <C-p>. However, it is slow, after trying it I decided to revert using <C-p> when there are no matches and default behaviour in the other cases.

Search tags only in current file

I am using ":ta " to jump to a method.
For example i got two classes named A.java and B.java. They both have a foo() method and B.java have another method called fooBar(). Then i open A.java and input :ta foo then press TAB then i will got two completion : foo and fooBar. But what i want to jump now is just tag in current file, i don't like tag in other file to display.
And i found tagslist does very good in this job. So if i can use the tag generated by taglist to search from, it will be very nice.
Depending on how many times you call your methods a couple of * may be enough.
Without using tags, gd can be used to go to the local declaration of the method under your cursor. I tend to choose the most low-tech solution usually, so I would go with this one.
But ctags is also able to generate tags for a single file only or for an arbitrary selection of files. It can be done in a few steps but it's definetely not as straightforward as what you are accustomed to do…
Create a file with the name(s) of the file(s) you want to scan. Let's say it's called files.txt and it's located at the root of your working directory.
Generate your tags file using the -L <file> argument: ctags -L files.txt.
At this point you should have a tags file containing only the tags present in the file(s) specified at step 1.
Generating different tags files for the whole project and for single files may be useful, here. A short script generating a tags file named after the current file and making it the sole tags source may make the whole thing easier.
EDIT
Actually, TagList and TagBar don't generate tags files. The output of the ctags <options> command they run is used internally and parsed with all kinds of regexp to filter by scope or filename or whatever.
Unfortunately this cannot be done using ctags. Ctags does not respect context, it is a pure list of all possible "functions". Try to open a tag file with an editor (e.g. vim) and you will see it is just a list of "functions" (in case of Java they are "methods"). Example:
getDesc src/com/redhat/rhn/internal/doclet/Handler.java /^ public String getDesc() {$/;" m class:Handler
getDoc src/com/redhat/rhn/internal/doclet/ApiCall.java /^ public String getDoc() {$/;" m class:ApiCall
Vim just search the file "as is" without giving it any context - it just search for a "function". It is able to search for files, classes, methods, enums etc. Tags format is described in more detail here: http://ctags.sourceforge.net/FORMAT
In Vim you have few possibilities. There are several plugins that gives Vim some context sensitivity, but you cannot use tags for that. Vim itself has a feature called OmniComplete and there are few plugins dedicated for Java. Then you can use Ctrl-X Ctrl-O to start a completition. I recommend you to map this to a different key (maybe Ctrl-Space if you like). More info about Java OmniComplete plugins here:
Vim omnicompletion for Java
Eclim (http://eclim.org/) is very comperhensive, but difficult to setup (you need to run Eclipse in the background). JDE script is easier and also robust (http://www.vim.org/scripts/script.php?script_id=1213). And please note IntelliJ IDEA Community Edition (free) also has a very nice Vim plugin that is free to use. But I understand you - Vim is Vim.
Good luck!
Not exactly an answer to your question, but it seems like there's no way to do exactly what you need, so, i would recommend you the following: for your Java development in Vim, try eclim.
This tool helps you to use your favorite text editor Vim with power of an Eclipse (IDE).
I can't find analogue for tab-completion of :ta, but i know a smart analogue for g] : this is a command :JavaSearchContext. You can map it to something.
For example, if you have two classes A and B, and you have method foo() in each class, then g] will ask you every time you want to jump to foo(), but :JavaSearchContext will always jump to the proper declaration of foo().
Of course, there are many other features.

Is it possible to format C++ code with VIM?

I am rather new to VIM. I got some source code and this is a mess. At a first sight I would like at least to get a clear and organised view of the code, so I like to get it rightly formatted, I mean indented depending on the depth of the functions and so.
I wonder if it can be done with VIM, and otherwise which other commandline tools for that can you recommend.
Thanks
While vim is a true Swiss-knife I still prefer external tools for some jobs. This approach is some times much more intuitive and easy to remember than using the built-in equivalent.
In the case of indenting, I filter the whole file buffer through astyle. The astyle parameters are much easier to grasp in a couple of minutes, especially if you are not a vim guru. Also astyle provides much more flexibility in fine-tuning the output.
First install astyle:# apt-get install astyle
Then inside vim:
:%!astyle (simple case - astyle default mode is C/C++)
or
:%!astyle --mode=c --style=ansi -s2 (ansi C++ style, use two spaces per indent level)
or
:1,40!astyle --mode=c --style=ansi (ansi C++ style, filter only lines 1-40)
you can do the following:
gg=G
I would highly recommend clang-format nowadays. It allows simple integration of clang-format into Vim, once you have clang-format installed:
http://clang.llvm.org/docs/ClangFormat.html#vim-integration
It is the only code beautifier that really understands your C++ code, and it is really intelligent to beautify the code more like a human being than a machine. E.g.:
void TestFunction(int argument1, int argument2,
int argument3);
void TestFunctionVeryLongName(int argument1,
int argument2,
int argument3);
void TestFunctionWithRidiculouslyLongName(
int argument1, int argument2, int argument3);
Vim will definitely do this, although the results may not be perfect:
First, select the entire file in visual mode: ggVG
Then hit = to reindent everything.
You can learn more about the equal command with: :help =
There is also a Vim plugin relying on clang-format: vim-clang-format
Then you can simply map the formatting command to whatever suits you.
There is a vim plugin that enables formatting on your code from within vim. It's called vim-autoformat and you can download it here:
https://github.com/vim-autoformat/vim-autoformat
It integrates external code-formatting programs into vim. For example, if you want to format C, C++, C# or Java code, you need to install the program astyle, and vim sets it as the format program automatically.
I don't write C++ code, but I write some Java code.
Instead, Vim supports the formatting of some common languages.
I have set up a short cut for me to format the whole code in the buffer.
It will return to the line I just edited :)
" format the file
map <leader>fm gg=G'.
A generic solution along the lines of m000's idea is to use UniversalIndentGUI as an external tool.
Just had to solve this exact problem, so I thought I'd contribute to save others some time.
You can use gg=G to indent your code. But things get hard to understand the moment you want to tweak how that auto-indenting happens. Therefore, if you only care that errant whitespace is removed and don't really care about formatting style, gg=G is the quickest way to go about it, because its built-in.
If you do want to control the style (for example, you're trying to make your code conform to a style guide), then you're going to need an external tool to process your file. You can invoke that tool from within vim with: :%!<toolname> <options>. This pipes the file through the tool and re-loads the processed result. (You can obviously use this for anything else you want to do to your file too)
So the next question is, what external tool should you choose? Regardless, the method is the same:
Install the tool of choice
Make sure its in your path
Add a line to your vimrc file that creates a shortcut key to use so you save time
Use it.
Now, which tool you use depends on the style you're trying to replicate. If you're trying to replicate a widely used style, then chances are astyle is all you need.
If you're trying to replicate a custom style, then you will need two things:
UniversalIndentGui - a front end that lets you play around with various options and live-preview their effect on the source file
A set of source code formatting tools installed and in your path
Between uncrustify and greatcode, you should be able to completely replicate the style you want.
Actually, I lied. There is another way and its called clang-format. However, you're going to want to read the documentation on it and its still in early stages so some options don't work very well. It is a beautiful tool though (definitely the smartest of the lot because constructs an AST of your code) and it is even available for Windows.
If you're going to take the time to read the manual, you also want to check out GNU Indent.
Of course, there is the last way, which is actually taking the time to learn vim's indent rules and writing one for your style. It will take time, but it will work with gg=G.
Some notes on astyle vs uncrustify vs greatcode:
Astyle is good for general formatting, but can't do things like align the declaration of variables and re-style comments very well.
Uncrustify can do a LOT of stuff that astyle can't, but be prepared to spend an hour playing around until you've found the correct combination of options you need. (Or if you feel like wasting a lot of time, use genetic algorithms to figure out the best combination of options for your style and when you do share the code and give me a link so I can use it too :) )
Note that you don't have to choose one tool. With vim, you can map one keystroke to execute several commands in succession, so theoretically you could use a combination of these tools to get exactly what you're looking for.
Last but not least, here's an excerpt from my .vimrc file, where I have mapped F12 to invoke astyle with some options:
"A2 = attached brackets
"-s8 indent 8 spaces
"-xc attached braces to class declarations
"-xj remove braces for single statement ifs and elses
"-c convert tabs to spaces in the non-indentation part of the line
map <F12> :%!astyle -A2 -s8 -xc -xj -c<CR>
Don't judge me on the style. Just use the tool to reproduce what you want.

Resources