How to execute file that I\'m editing in Vi(m) and get output in split window (like in SciTE)?
Of course I could execute it like that:
:!scriptname
<
To access the current buffer's filename, use %
. To get it into a variable you can use the expand()
function. To open a new window with a new buffer, use :new
or :vnew
. To pipe the output from a command into the current buffer, use :.!
. Putting it all together:
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
obviously replacing ruby
with whatever command you want. I used execute
so I could surround the filename with quotation marks, so it'll work if the filename has spaces in it.
Vim 8 has an interactive terminal built in. To run the current bash script in a split pane:
:terminal bash %
or for short
:ter bash %
%
expands to the current file name.
From :help terminal
:
The terminal feature is optional, use this to check if your Vim has it:
echo has('terminal')
If the result is "1" you have it.
I use a slightly more intrusive mechanism through maps:
map ;e :w<CR>:exe ":!python " . getreg("%") . "" <CR>
Just makes it so I don't have to save, then go. Just go.
Vim has !
("bang") command which executes shell command directly from VIM window. Moreover it allows launching sequence of commands that are connected with pipe and read stdout.
For example:
! node %
is equivalent to opening command prompt window and launching commands:
cd my_current_directory
node my_current_file
See "Vim tips: Working with external commands" for details.
Based on @SethKriticos and @Cyril answers I now use the following:
function! Setup_ExecNDisplay()
execute "w"
execute "silent !chmod +x %:p"
let n=expand('%:t')
execute "silent !%:p 2>&1 | tee ~/.vim/output_".n
" I prefer vsplit
"execute "split ~/.vim/output_".n
execute "vsplit ~/.vim/output_".n
execute "redraw!"
set autoread
endfunction
function! ExecNDisplay()
execute "w"
let n=expand('%:t')
execute "silent !%:p 2>&1 | tee ~/.vim/output_".n
" I use set autoread
"execute "1 . 'wincmd e'"
endfunction
:nmap <F9> :call Setup_ExecNDisplay()<CR>
:nmap <F2> :call ExecNDisplay()<CR>
Use F9 to setup the new window and F2 to execute your script and tee to your output file.
I also added the script name to the output file name, so that you can use this for multiple scripts at the same time.
In your .vimrc
you can paste this function
function! s:ExecuteInShell(command)
let command = join(map(split(a:command), 'expand(v:val)'))
let winnr = bufwinnr('^' . command . '$')
silent! execute ':w'
silent! execute winnr < 0 ? 'vnew ' . fnameescape(command) : winnr . 'wincmd w'
setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
silent! execute 'silent %!'. command
silent! redraw
silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
silent! execute 'wincmd w'
" echo 'Shell command ' . command . ' executed.'
endfunction
command! -complete=shellcmd -nargs=+ Shell call s:ExecuteInShell(<q-args>)
cabbrev shell Shell
After that, in vim
run command :shell python ~/p.py
as example. And you will get the output in splitted window.
+ After changes in p.py
as example you will run the same command again, this function will not create new window again, it will display the result in the previous(same) splitted window.