[ intro | quickfix | intra | inter | tips ]
The fixed-width text inside of boxes are lines from a script, .vimrc or the build.xml for Ant. The other fixed width text is meant to be characters typed into Vim while running Vim.
These examples were done on a RedHat Linux 8.0 machine with JDK 1.4.1, Ant 1.5.1 and Vim 6.1.
Instead of lugging punch-cards to the computer lab at 2am to check our code we now have the luxury of immediately building our code and verifying its correctness. The cycle of editing, compiling and editing again still is something of a bottle-neck when it comes to producing code quickly. That's where Vims Quickfix feature comes in. Quickfix can speed up the time it takes you to attempt a compile, read the compiler output, hunt down the offending file, find the line that is giving you trouble, fix it and move on to the next problem. In this section we'll talk about how to get QuickFix up and running.
QuickFix setup is easy. You just need to have a few things in place. We're assuming that you are using Ant to do your builds and you are using javac for the compiler.
We'll add a couple of auto-commands to our .vimrc file that only need to apply if we are working with Java files. The first line tells Ant what you want to do when you type :mak. The :mak command traditionally launches the make command, wich looks for a Makefile in the current directory. What we are doing is invoking Ant and pointing it to our build.xml file that is at the root of our project hierarchy.
The second line tells Vim how error lines look that come out of Ant and javac. Vim parses these lines and gives you information from the compiler as well as figuring out what lines and even column the offending code is on.
Okay with that in place, a working build.xml file and some code that you need to compile, you can start using QuickFix. Like anything in Vim there are lots of interesting options you can find about if you do a :help quickfix in Vim, but for our purposes here there are a handful of things that can get us going quickly.
To actually kick off the build you need to have Vim open, most likely you are editing one of the files that are to be built. Type in :mak and let Vim start the build. You will see normal output from an Ant build come across the screen along with your compile messages.
When the the compilation is done press enter. If there were any errors, you'll see the first one, press enter again and it will take you to where that error is at. So you fix that error, you can kick off the compile again by typing :mak or you can go to the next error that javac found. To go to the next error type :cn
Here is a table of the commands that let you navigate errors inside QuickFix. The c mnemonic on all of the commands is probably a leftover from the original use of the command; to navigate through C compiler error messages.
| ':' command | what it does |
| cn | go to the next error |
| cp | go to the previous error |
| cfirst | go to the first error |
| clast | go to the last error |
| clist | list all of the errors |
There are a lot of options for folding but the simplest way to use it is to have it cue off of your indentation. Here are some typical settings for indentation, I won't explain them because there really aren't reasons to have to modify them on a regular basis.
set foldmethod=indent
set foldlevel=0
set foldnestmax=2
set fillchars=stl:_,stlnc:-,vert:\|,fold:\ ,diff:-
Admittedly the folding feature can, on occasion, seem to get in the way of working with a file. Because of that I have added a mapping to my .vimrc to toggle folding.
map F :let &fen = !&fen
Like most things in Vim, the gf feature is primarily meant to work with the C/ C++ world. With some slight caressing we can get it working for us in the Java space.
First you need to set your path (see :help path). This is pretty much the root directory of your source tree. For our project this is /home/demian/code/jim/source So in Vim you would add a row like the following, one for every source directory that contains files you would like to jump to.
set path+=., set path+=/home/demian/code/jim/src/**,
To get Vim to understand Java import statements instead of C/ C++ include statements we need to add the following two lines to our .vimrc as well. The first line just says that the word 'import' is used, the second line replaces all occurrances of '.' with '/'.
autocmd BufRead *.java set
include=^#\s*import
autocmd BufRead *.java set
includeexpr=substitute(v:fname,'\\.','/','g')
map gf <C-W>f
Okay, so now we can put the cursor on a class name, Vim interprets the import statements and looks at the path you've defined and figures out what file to open. All we have to do is add another simple mapping and Vim will let you put the cursor on a class instance to get the same effect.
map gc gdb<C-W>f
This uses the gd command wich stands for go to definition. This goes to the definition of the instance does a back, so now you're on the class name. After that we just do the same gf to open up the file. Sweet huh?
Since you have added the path, Vim will also let you use the sfind command. You don't even need the class named in your code, now all you have to do is type in the class name and vim will find it in your path. Like this :sfind ClassName, and Vim will open the file in a new buffer for you.
There are a number of ways to create the tags file. I put it as a target within my Ant build script.
<target name="tags">
<exec executable="ctags">
<arg line="--recurse=yes"/>
<arg line="--links=yes"/>
<arg line="--java-types=cimp"/>
<arg line="-f .tags ."/>
<exec>
<target>
It's not enough just to have the tags file sitting around. You have to tell Vim where to find it. I added the following line in my .vimrc to point Vim to the tag file.
set tag=/home/demian/code/jim/.tags
When this is in place you can type ant tags and your tag file will be created. Now that Vim knows where it's at you can now actually use the tags. Go to the src/jim/main/Hello.java file and put the cursor over a class name or function name. Now press [ctrl]-] (that is, control and ']' at the same time). This should jump you to the file containing that artifact. To go back to the original file you press [ctrl]-t. Unfortunately that's not incredibly intuitive.
Okay that was file navigation with the help of tag files. Now we're going to talk about code-completion because it builds on the stuff that we just set up.
To tell Vim how you want to do code completion you just set a few things in your .vimrc.
set complete=i,],.,b,w,t,k,.
set dictionary=~/.vimKeywords
The complete line tells vim where you want to get the code-completion help from. See :help complete for more information. The dictionary file is a place where you can put common strings for code completion, this isn't necessary but might be helpful (see :help dictionary).
Now to actually do the code-completion while you're editing text you start typing and then press [ctrl]-n to go to the next match and [ctrl]-p to go to the previous. To me at least, this is not very intuitive either. So include this handy function in your .vimrc file.
inoremap
inoremap
function! InsertTabWrapper(direction)
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\
elseif "backward" == a:direction
return "\
else
return "\
endif
endfunction
What that function does is make it so that your [tab] button behaves just like it does for other editors that do code completion. Now you can go to the Hello.java file, start typing the name of a function or variable and then press the [tab] button and Vim will complete it for you.
To make sure this isn't an issue, i just paste the current path into the buffer and then turn that into my package statement. Go to where you are going to be putting your package statement and type.
[esc]:r!pwd[enter]
So what this does is just read in the pwd command from the shell. All this is assuming that you're source tree actually matches your package structure.
ab println System.out.println("");
You can even get cute and enter more Vim commands. For example the following abbreviation prints out the code, gets you into command mode, goes back twice and then puts you back into insert mode. That way the cursor is right in the middle of the quotes.
ab println System.out.println("");<esc>hhi
The ugly code is probably within a set of brackets, move your cursor to one of the brackets and, in escape mode, press =% this tells Vim to indent all the lines from this bracket to the other bracket.