How can I script vim to run perltidy on a buffer?

perl, vim

Solution

After trying @hobbs answer I noticed that when filtering the entire buffer through `perltidy` the cursor returned to byte 1, and I had to make a mental note of the original line number so I could go back after `:Tidy` completed.

So building on @hobbs' and @Ignacio's answers, I added the following to my `.vimrc`:

"define :Tidy command to run perltidy on visual selection || entire buffer"
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy

"run :Tidy on entire buffer and return cursor to (approximate) original position"
fun DoTidy()
    let l = line(".")
    let c = col(".")
    :Tidy
    call cursor(l, c)
endfun

"shortcut for normal mode to run on entire buffer then return to current line"
au Filetype perl nmap <F2> :call DoTidy()<CR>

"shortcut for visual mode to run on the current visual selection"
au Filetype perl vmap <F2> :Tidy<CR>

(closing `"` added to comments for SO syntax highlighting purposes (not required, but valid vim syntax))

`DoTidy()` will return the cursor to its original position plus or minus at most `X` bytes, where `X` is the number of bytes added/removed by `perltidy` relative to the original cursor position. But this is fairly trivial as long as you keep things tidy :).

[Vim version: 7.2]

EDIT: Updated `DoTidy()` to incorporate @mikew's comment for readability and for compatibility with Vim 7.0

Problem

At my current job, we have coding-style standards that are different from the ones I normally follow. Fortunately, we have a canned RC file for `perltidy` that I can apply to reformat files before I submit them to our review process. I have code for emacs that I use to run a command over a buffer and replace the buffer with the output, which I have adapted for this. But I sometimes alternate between emacs and vim, and would like to have the same capabilities there. I'm sure that this or something similar is simple and had been done and re-done many times over. But I've not had much luck finding any examples of vim-script that seem to do what I need. Which is, in essence, to be able to hit a key combo (like Ctrl-F6, what I use in emacs) and have the buffer be reformatted in-place by `perltidy`. While I'm a comfortable vim-user, I'm completely clueless at writing this sort of thing for vim.

Original source