TextMate has a nice feature that allows you to execute a script from within the current context and shows you the output in a separate window. This lets you write and test code on the go. I'm almost certain there is a similar feature with MacVim/gVIM, but I'm not sure what it is. Currently I save my buffers to disk, then go to the command line and execute the script in that respect. How do I improve that workflow with vim?
9 Answers
You can do this in vim using the ! command. For instance to count the number of words in the current file you can do:
:! wc %
The % is replaced by the current filename. To run a script you could call the interpreter on the file - for instance if you are writing a perl script:
:! perl %
4 Comments
:w | python % (multiple commmands) And to repeat the last : command:: command: * Type @@ or * Type : and use cursor up @jts: Maybe you'll add this.:! ./% will use the shebang line to determine how to run and executes the file.:!%:p which p stands for full path otherwise I got the error: "shell returned 127"vim tutorial: Mapping keys in Vim
You can map keys so perl executes current script as suggested by jts above.
map <C-p> :w<CR>:!perl %<CR>
will map Ctrl+P to write file and run it by perl
imap <C-p> <Esc>:w<CR>:!perl %<CR>
lets you call the same in insert mode.
You should have .vimrc (_vimrc for Windows) file in your vim/home folder. It has instructions on how vim should behave.
map <C-p> :w<CR>:!perl %<CR> is just instruction to map Ctrl+p to:
a) write current the file :w
b) run command (perl) using % (currently open file) as parameter :!perl %
<CR> after each command stands for "carriage return": an instruction to execute specific command. imap does the same as map but listens Ctrl+p while in insert mode.
All suggestions here merely showcased :!{cmd} %, which passes current buffer to the shell cmd.
But there is another option :write !{cmd}
For example, the effect of the :write !sh command is that each line of the current buffer is executed in the shell.
It is often useful, when for instance you've added a couple of lines to you buffer, and want to see execution result immediately without saving the buffer first.
Also it is possible to execute some range, rather than whole content of the buffer::[range]write !{cmd}
Comments
save the file and call the script using an interpreter
eg.:
:!python %
1 Comment
It sounds like you're looking for !:
:!{cmd}Execute{cmd}with the shell.
You can use % to denote the current filename, if you need to pass it to the script:
!proofread-script %
You can also use ! with a range, to use the command as a filter:
!{motion}{filter} " from normal mode
:{range}!{filter} " from command mode
(In the first case, as with many other commands, when you type the motion, it'll pass you into command mode, converting the motion into a range, e.g. :.,.+2!)
And finally, if you don't actually need to pass input from your file, but want the output in your file, that's essentially a trivial filter, and the fastest way to do it is !!{cmd}. This will replace the current line with the output of the command.
Comments
Put this small snippet in your .vimrc to execute the current file with one keystroke (like F5) and display the result in a new split-pane buffer.
:! is okay but you need to switch to your terminal to see the result.
While you can do that with ctrl-z and bring vim back with fg it still means you need to switch context a lot.
The way this snippet works is by first guessing the executable based on the filetype and then running it with the current file as its argument.
Next a handy utility method takes the output and dumps it into a new buffer.
It's not perfect, but really fast for common workflows.
Here's the snippet copied below:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""""""""""""""""""""""""" RUN CURRENT FILE """""""""""""""""""""""""""""
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Execute current file
nnoremap <F5> :call ExecuteFile()<CR>
" Will attempt to execute the current file based on the `&filetype`
" You need to manually map the filetypes you use most commonly to the
" correct shell command.
function! ExecuteFile()
let filetype_to_command = {
\ 'javascript': 'node',
\ 'coffee': 'coffee',
\ 'python': 'python',
\ 'html': 'open',
\ 'sh': 'sh'
\ }
let cmd = get(filetype_to_command, &filetype, &filetype)
call RunShellCommand(cmd." %s")
endfunction
" Enter any shell command and have the output appear in a new buffer
" For example, to word count the current file:
"
" :Shell wc %s
"
" Thanks to: http://vim.wikia.com/wiki/Display_output_of_shell_commands_in_new_window
command! -complete=shellcmd -nargs=+ Shell call RunShellCommand(<q-args>)
function! RunShellCommand(cmdline)
echo a:cmdline
let expanded_cmdline = a:cmdline
for part in split(a:cmdline, ' ')
if part[0] =~ '\v[%#<]'
let expanded_part = fnameescape(expand(part))
let expanded_cmdline = substitute(expanded_cmdline, part, expanded_part, '')
endif
endfor
botright new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded Form: ' .expanded_cmdline)
call setline(3,substitute(getline(2),'.','=','g'))
execute '$read !'. expanded_cmdline
setlocal nomodifiable
1
endfunction
1 Comment
\ 'sh': 'sh' in the snippet you referenced to \ 'sh': 'bash' . I was trying to learn about the here-string <<< and not getting expected results. Turns out that bash and not sh supports the here-string <<< so I changed the shell for sh scripts.Well it depends on your OS - actually I did not test it on M$ Window$ - but Conque is one of the best plugins around there: http://code.google.com/p/conque/
Actually, it can be better, but works. You can embed a shell window in a vim "window".
:! ruby %to run the script that you're currently writing.