using Vim gd on project with multiple code folders - vim

I am using vim to edit Fortran 90 code. The code is structured in the following manner:
./srcs - contains main code file
./libs - contains some module file
If I open the main file in vim and then find some interesting function and press "gD" vim cannot find this function since it does not know where to search. If I copy all the source files to one folder this option does work.
My questions are:
How do I tell vim where my code is.
Can you suggest for a quick manner on how to work with this kind of folder without repeating the use of solution (1).

In this case you might be better off using exuberant ctags.
After installing this program, run ctags -R in the top level directory of your project. Then use e.g. set tags=tags; in your .vimrc to tell vim where your tag file is.
Once this is set up, you can use tag searching.

Related

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.

How to find all occurrences of a variable in Vim?

In vim, how to I find all occurrences of a variable in files under a certain directory?
I know vimgrep works sometimes, but it looks for text only and doesn't work if other classes have variables of the same name and I only want the variable under a specific class.
What should I do? Or should I get an IDE instead?
Why would you want to use another IDE when you already have one? Vim is an IDE that is configurable and usable for different languages..
You could use cscope to build a database of your code. This database
Allows searching code for:
all references to a symbol
global definitions
functions called by a function
functions calling a function
text string
regular expression pattern
a file
files including a file
Further features of Cscope:
Curses based (text screen)
An information database is generated for faster searches and later reference
The fuzzy parser supports C, but is flexible enough to be useful for C++ and Java, and for use as a generalized 'grep database' (use it to browse large text documents!)
Has a command line mode for inclusion in scripts or as a backend to a GUI/frontend
Runs on all flavors of Unix, plus most monopoly-controlled operating systems.
Once your database is created, you could browse through the usages of your variables, functions, etc.
Edit (slightly off-topic):
another cool thing that's quite handy when working with Vim on code is the taglist plugin that uses Ctags:
The "Tag List" plugin is a source code browser plugin for Vim and
provides an overview of the structure of source code files and allows
you to efficiently browse through source code files for different
programming languages.
cscope step by step example
Go to the base directory of your project, and run:
cscope -Rb
This generates a cscope.out file which contains the parsed information. Generation is reasonably fast, even for huge projects like the Linux kernel.
Note that cscope is not designed to work with other languages other than C. Sometimes it does work for other C-like syntax languages like Python, and you can force it to recognize those files with hacks such as cscope -Rb -s * and others mentioned at: Using cscope to browse Python code with VIM? but it won't work as well as for C.
Open vim, and run:
:cs add cscope.out
:cs find s my_func
s is a mnemonic for symbol. The other cscope provided queries are also possible.
The cscope interface (ouside Vim) also has a variable assignment query (subset of symbol occurrences) which Vim does not seem to offer (?)
This adds a list of the callers to the quickfix list, which you can open with:
:copen
Go to the line that interests you and hit enter to jump there.
See also:
automatically add the nearest database (parent directories) when you enter a file: how to auto load cscope.out in vim
for function calls: How to find the callers and callee of a function in C code in vi/vim?

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.

How to add new snippets to snipMate in VIM

Ive just started using the sniptMate plugin for VIM and love it, however, since my collection of snippets isn't huge, I'd like to be able to add new snippets dynamically rather than opening the snippets file and creating a new snippet as I am in the middle of development.
As I am coding something I realize that some specific piece of code can be saved as a snippet to save me trouble of typing the bloat code again, at this time I want to be able to add a snippet without opening the snippet file for the language I am using at the time.
If you are using pathogen, you can write your own snippets without polluting the original ones. To do this, add your snippets to ~/.vim/bundle/mysnippets/snippets/*.snippets. FYI, mysnippets can be any name.
Moreover, it's a convention to add a _.snippets file in that directory where you add snippets which should be available everywhere irrespective of the filetype.
I'm not sure it's meant to be done like this but you can try calling the MakeSnip function from within file you're currently working on. For example:
:call MakeSnip(&ft, "foo", "<foo>${1}</foo>")
&ft will pass the filetype of the file you're currently editing, "foo" is the trigger and "<foo>${1}</foo>" is the replacement text.
Of course, snippets created like this won't persist. So why not have the snippets file open in another buffer, define new snippets there as necessary, then do:
:call ReloadSnippets(&ft)
and your new snippet will be available. You could even define an autocmd to call the ReloadSnippets function when you write the snippets file.
You can put your own snippets in ~/.vim/after/snippets/ or whatever the equivalent on Windows is... read :h snipMate for the filename syntax.
Just place your own snippets (given you want to use them in all files you edit) here:
~/.vim/after/snippets/_.snippets
For example:
snippet test
{"foo": "${1}", "bar": "${2}"}
Snippets for Snipmate are usually stored in the ".vim" directory in the snippets folder.
You can pretty easily edit the snippet file for the language you are working on.
If you use vundle to manage your plugins on Windows and you have installed
vim-snipMate & vim-snippets
If you want to add your customization, say to 'html' filetype, you just go to this folder:
$HOME/vimfiles/bundle/vim-snippets/snippets/
create a new file and name it in this format:
html_bsmith.snippets
(it must be underscore after html, see :help snipmate)
Then vim will load your file automatically.
If you customization can be used anywhere, just put it in the existing file:
_.snippets

How to tame vim's ":find" command

Say, I have files foo.js and bar.css in my project. There is a ":find" command in vim, which find files, matching string. But this command, alas, has some limitations. For example, if I launch this way - "vim", or even this way - "vim ." - there's nothing to be find in js subdirectory. But if I launch vim this way - "vim js/any_file_other_than_foo.js", then calling ":find foo.js" works pretty well.
Since it is not intuitive (i'm working in the same directory, "pwd" returns the same path), my first question is - can anybody explain how to circumvent this issue? And, even broader, is there any way to type something like find foo - and open first file, which name matches pattern foo.
thanks in advance.
You could try
:e[dit] **/*foo* and then press 'tab' to move to the first match.
the ** is a directory globbing pattern, while * is character matching.
If you were so inclined, you could write a simple fuzzy finder command, for more information you can check out the vim tips wiki: http://vim.wikia.com/wiki/Find_files_in_subdirectories
Vim's :find works by searching each directory in the path variable (and ignores pwd). By default, it does not search recursively. That's why find is only working for you when you open a js file. The '.' in path refers to the directory for the current file -- not pwd.
You can change path to include your desired directories:
set path+=$PROJECT/js
See :help path.
One of the magic bits to use is to add ** to a path to search that path recursively:
" search recursively in my project
set path+=$PROJECT/**
" search recursively from the current file's directory
set path+=./**
See :help file-searching for more magic.
A nice plugin that accomplishes a similar effect is Command-T.
The Command-T plug-in provides an
extremely fast, intuitive mechanism
for opening files with a minimal
number of keystrokes. It's named
"Command-T" because it is inspired by
the "Go to File" window bound to
Command-T in TextMate.
Files are selected by typing
characters that appear in their paths,
and are ordered by an algorithm which
knows that characters that appear in
certain locations (for example,
immediately after a path separator)
should be given more weight.should be given more weight.
Here is a screencast of Command-T in action.

Resources