Chris Sutter writes:
I have a script and mapping in my ~/.vimrc:
function! CheckForShebang()
if (match( getline(1) , '^\#!') == 0)
map <F5> :!./%<CR>
else
unmap <F%>
end
endfunction
map <F5> :call CheckForShebang()
This way, if i'm editing a script with a shebang at the top and i hit <F5>, it maps <F5> to run the script (if not, <F5> is unmapped, so that it doesn't keep checking if I hit it again). I always found myself mapping <F5> by hand to run the current script while i was editting/debugging and I'd frequently lose track of whether I had mapped it or not. You could, of course, replace <F5> with your favorite run/compile/debug/etc key, it just happens to be my standard (from my QBasic days hehe).
Thanks for the tip Chris!
Wednesday, April 29, 2009
Subscribe to:
Post Comments (Atom)
14 comments:
You are missing the end of the if else construction. spaces added to fake out html filter.
function! CheckForShebang()
if (match( getline(1) , '^\#!') == 0)
map < F5 > :!./%< CR >
else
unmap < F% >
end
endfunction
map < F5 > :call CheckForShebang()
I like.
I randomly hit my "run" key whenever I stop to think; this will prevent it from throwing errors at me when i am editing documentation/etc. (I replaced the unamp with an echo as I oft do multiple file types in one session.)
In the current form, you need to press F5, Enter and F5 again to execute the script.I made a little modification so that when you press on F5 for the first time, the script is executed :
function! CheckForShebang()
if (match( getline(1) , '^\#!') == 0)
map < F5 > :!./%< CR >
:!./%
else
unmap < F% >
endif
endfunction
map < F5 > :call CheckForShebang()< CR >
Hi,
Just to let you know that when reading your blog through googlereader, the block you posted as code appears with a white font and white background - quite impossible to read :)
@Buster Dog
oops! thanks for catching that. fixed.
:map < expr > < F5 > CheckForShebang()
is probably the easiest way to do the original mapping.
You could use an event to do the mapping a bit better and localize the mapping to the buffer as well.
au BufEnter * call CheckForShebang()
and in CheckForShebang() change the "map" to "map <buffer>" to make the mapping local to that buffer (actually "nmap <silent> <buffer>" is probably what you really want). You also can get rid of the "unmap" because it's buffer-local and you're not screwing around with any global mapping that you have to unmap later.
And you can go further and map the "concept" of "use F5 to run the file in the buffer" to do different things depending on the file type.
Let's say you want to do that, so the function name is no longer very appropriate, so call it, MapF5ToExecuteFileInBuffer() instead. Now you can have that function do the following:
- map #! files to just execute them straight if on Unix (with a possible automatic chmod u+x) or run them through the appropriate interpreter if you're on Windows (assuming the files don't execute nicely on Windows as it is)
- have Rakefiles run through rake (instead of ruby)
- have vimscripts run through a separate copy of VIM
- etc...
All of this is done magically by hitting the same key for all things. You get the same functionality in a more reusable concept that maps to any file type but does the same logical operation.
Enjoy :)
@derek I tried doing the modifications you suggested but I keep getting errors. Could you post the modified function ? That would be great.
I hadn't actually written before, but I've actually tested what's below and it works for me:
function! MapF5ToExecuteFileInBuffer()
if match(getline(1), '^\#!') == 0
nmap <silent> <buffer> <F5> :!./%<cr>
elseif " some other interesting condition here
" do a different type of mapping
endif
endfunction
augroup derek_buffer_mapping
au! BufEnter * call MapF5ToExecuteFileInBuffer()
augroup END
Now if you edit a file and put a #! at the top then the next time you enter the buffer it will do the mapping.
Agreed... "the next time you enter the buffer!?!?", I hear you scream. Yup, that sucks :) Ok... a better event to attach this to is probably "BufWritePre" instead of "BufEnter". Or do both... but the "BufWritePre" or "BufWriteCmd" or "BufWritePost"... all of those should be just fine. The idea is that you can't execute it until you've written it.
@derek Thanks it works just fine!
Great tip! I'll use this one daily.
Yes fixed - now dark grey text on black background.... :)
Just as google mailing list mentioned it i figured i'd append here...
In the elseif of the function above; do something like...
:map < F5 > :make %< \|!./% << CR >
to also compile with the same keypress (I'm sure this needs some fudging also)
Hey, I changed your script a little so that it also works if the script is lacking executable permissions:
function! CheckForShebang()
if (match( getline(1) , '^\#!') == 0)
let b:interpreter = getline(1)[2:]
map <F5> :exec "!".b:interpreter." %"<CR>
else
unmap <F5>
end
endfunction
Post a Comment