Showing posts with label vim tip. Show all posts
Showing posts with label vim tip. Show all posts

Wednesday, September 2, 2009

Vim Tip: Debug Path

I work for a company whose code is in thousands of files in hundreds of directories. We have multiple VCS repositories. Function libraries, class files, HTML, XSL--a convoluted maze to navigate, especially when trying to debug something.

Whenever I'm debugging, I may follow the rabbit hole from function to function, through various libraries and classes, only to find that I'd taken a wrong turn somewhere and come to a dead end. I then either have to sift through the multiple tabs I've opened to find where I should pick up the search again, or, if I've been closing files along the way, I have to start the search from the beginning. This is annoying and time-consuming.

I decided to write a simple vim script to save my cursor's current line, along with the file name and line number, to a file in my home directory. I can then continually save lines as I follow a path through the code. If, at any time, I hit a dead end, I simply go through this "trace" file and find where to pick up the search again. Combined with vim's "gf" command, this file is very useful!

Here's the code you can add to your own .vimrc file:

nmap <F8> <ESC>:call WriteTrace()<CR>

function WriteTrace()
let lineNum = line('.')
let lineFile = bufname('%')
let lineVal = getline(lineNum)

let allLines = readfile("$HOME/trace.txt")
let allLines = add(allLines,lineFile.":".lineNum)
let allLines = add(allLines,lineVal)
let allLines = add(allLines,"")

call writefile(allLines,"$HOME/trace.txt")
endfunction

In the code above, F8 will save the line under the cursor, but the nmap can be changed to map to any key, of course.

Thursday, August 20, 2009

Vim Tip: Session Management

Instead of having another gigantic essay "Vim Tips, part 2," I decided to just address interesting tid-bits of my .vimrc file one at a time. First up: sessions!

Vim sessions are rudimentary but can easily be enhanced to make working on a project or multiple projects more convenient. I'm a big fan of tabs, so I'll often have several tabs open at a time. When I return to work the next day, I'd like to pick up where I left off as seamlessly as possible. Also, if I get pulled away on something else temporarily, I'd like to be able to save my current state, jump to the task at hand, and save its session, as well, in case I have to go back to it again after it's complete.

To this end, I've put the following in my .vimrc file:

nmap <F3> <ESC>:call LoadSession()<CR>
" don't store any options in sessions
if version >= 700
set sessionoptions=blank,buffers,curdir,tabpages,winpos,folds
endif

" automatically update session, if loaded
let s:sessionloaded = 0
function LoadSession()
source Session.vim
let s:sessionloaded = 1
endfunction
function SaveSession()
if s:sessionloaded == 1
mksession!
end
endfunction
autocmd VimLeave * call SaveSession()

To start a session in vim, use the following:

:mksession

This will create a Session.vim file in your CWD. Now, next time you open vim, you can simply hit F3 and your session will be restored. Of course, this little snippet does more than just ":source Session.vim".

When you hit F3, my script sets a flag that means we're currently using a saved session. When you quit vim, it will automatically re-save your session, so when you restore it next time (by hitting F3 again), vim will be returned to the exact state it was in when you quit. It's a very simple hack, but it saves a lot of time.

One improvement I'd like to make is to be able, somehow, to select which session file to use. Suppose I have Project1.vim and Project2.vim ("Session.vim" is the default name, but isn't required). I'd like to be able to select which project I'm working on, and the appropriate session file would be loaded.