I am writing Python code using Vim, and every time I want to run my code, I type this inside Vim:
:w !python
This gets frustrating, so I was looking for a quicker method to run Python code inside Vim. Executing Python scripts from a terminal maybe? I am using Linux.
" run current python file to new buffer
function! RunPython()
let s:current_file = expand("%")
enew|silent execute ".!python " . shellescape(s:current_file, 1)
setlocal buftype=nofile bufhidden=wipe noswapfile nowrap
setlocal nobuflisted
endfunction
autocmd FileType python nnoremap <Leader>c :call RunPython()<CR>
For generic use (run python/haskell/ruby/C++... from vim based on the filetype
), there's a nice plugin called vim-quickrun. It supports many programming languages by default. It is easily configurable, too, so one can define preferred behaviours for any filetype if needed. The github repo does not have a fancy readme, but it is well documented with the doc file.
If you don't want to see ":exec python file.py
" printed each time, use this:
nnoremap <F9> :echo system('python2 "' . expand('%') . '"')<cr>
nnoremap <F10> :echo system('python3 "' . expand('%') . '"')<cr>
It didn't mess up my powerline / vim-airline statusbar either.
cd
vim .vimrc
nmap <F4> <Esc>:w<CR>:!clear;python %<CR>
ZZ
The next time you want to run your code, just press F4
in "normal mode". If you want to run your code in "insert mode", replace nmap
with imap
.
If you want to quickly jump back through your :w
commands, a cool thing is to type :w
and then press your up arrow. It will only cycle through commands that start with w
.
You can extends for any language with 1 keybinding with augroup command, for example:
augroup rungroup
autocmd!
autocmd BufRead,BufNewFile *.go nnoremap <F5> :exec '!go run' shellescape(@%, 1)<cr>
autocmd BufRead,BufNewFile *.py nnoremap <F5> :exec '!python' shellescape(@%, 1)<cr>
augroup END
You can use skywind3000/asyncrun.vim as well. It is similar to what @FocusedWolf has listed.
Think about using shebang line, so you will be able to use it with still any language, not only Python.
Adding shebang:
Add this to first line of your script:
#!/usr/bin/env python3
or this, if you are using Python 2:
#!/usr/bin/env python2
Vim keymap:
Add this to your ~/.vimrc
:
nmap <F7> :w<cr>:!clear;"%:p"<cr>
Make file executable:
Type in Vim:
:!chmod +x %
or in terminal:
chmod +x script_name.py
Explanation:
When F7 is pressed in normal mode, Vim will try to execute current file as bash script. Then bash interpreter will see shebang line and understand, that this file should be passed to Python (or any other programm if needed).
Also you will be able to run your script from terminal using it's name:
./script_name.py
instead of this way (that will work too):
python3 script_name.py
This .vimrc mapping needs Conque Shell, but it replicates Geany (and other X editors') behaviour:
Window closes automatically on exit
:let dummy = conque_term#subprocess('gnome-terminal -e "bash -c \"python ' . expand("%") . '; answer=\\\"z\\\"; while [ $answer != \\\"q\\\" ]; do printf \\\"\nexited with code $?, press (q) to quit: \\\"; read -n 1 answer; done; \" "')
The accepted answer works for me (on Linux), but I wanted this command to also save the buffer before running, so I modified it slightly:
nnoremap <buffer> <F9> :w <bar> :exec '!python' shellescape(@%, 1)<cr>
The :w <bar>
saves the buffer THEN runs the code in it.
Building on the previous answers, if you like to see the code while looking at its' output you could find :ter
(:terminal
) command useful.
autocmd Filetype python nnoremap <buffer> <F5> :w<CR>:ter python2 "%"<CR>
autocmd Filetype python nnoremap <buffer> <F6> :w<CR>:vert ter python3 "%"<CR>
Using vert
in the second line runs the code in vertical split instead of horizontal.
The negative of it is that if you don't close the split-window where the code ran you will have many splits after multiple runs (which doesn't happen in original python IDLE where the same output window is reused).
(I keep these lines inside /home/user/.vimrc
)
I prefer Python output redirected to a new Vim window (and if that window is left open then update its content the next time you execute Python code with this function):
" Bind F5 to save file if modified and execute python script in a buffer.
nnoremap <silent> <F5> :call SaveAndExecutePython()<CR>
vnoremap <silent> <F5> :<C-u>call SaveAndExecutePython()<CR>
function! SaveAndExecutePython()
" SOURCE [reusable window]: https://github.com/fatih/vim-go/blob/master/autoload/go/ui.vim
" save and reload current file
silent execute "update | edit"
" get file path of current file
let s:current_buffer_file_path = expand("%")
let s:output_buffer_name = "Python"
let s:output_buffer_filetype = "output"
" reuse existing buffer window if it exists otherwise create a new one
if !exists("s:buf_nr") || !bufexists(s:buf_nr)
silent execute 'botright new ' . s:output_buffer_name
let s:buf_nr = bufnr('%')
elseif bufwinnr(s:buf_nr) == -1
silent execute 'botright new'
silent execute s:buf_nr . 'buffer'
elseif bufwinnr(s:buf_nr) != bufwinnr('%')
silent execute bufwinnr(s:buf_nr) . 'wincmd w'
endif
silent execute "setlocal filetype=" . s:output_buffer_filetype
setlocal bufhidden=delete
setlocal buftype=nofile
setlocal noswapfile
setlocal nobuflisted
setlocal winfixheight
setlocal cursorline " make it easy to distinguish
setlocal nonumber
setlocal norelativenumber
setlocal showbreak=""
" clear the buffer
setlocal noreadonly
setlocal modifiable
%delete _
" add the console output
silent execute ".!python " . shellescape(s:current_buffer_file_path, 1)
" resize window to content length
" Note: This is annoying because if you print a lot of lines then your code buffer is forced to a height of one line every time you run this function.
" However without this line the buffer starts off as a default size and if you resize the buffer then it keeps that custom size after repeated runs of this function.
" But if you close the output buffer then it returns to using the default size when its recreated
"execute 'resize' . line('$')
" make the buffer non modifiable
setlocal readonly
setlocal nomodifiable
endfunction
Just go to normal mode by pressing <esc>
and type:
! clear; python %
Step by step explanation:
!
allows you to run a terminal command
clear
will empty your terminal screen
;
ends the first command, allowing you to introduce a second command
python
will use python to run your script (it could be replaced withruby
for example)
%
concats the current filename, passing it as a parameter to thepython
command
Plugin: jupyter-vim
So you can send lines (<leader>E
), visual selection (<leader>e
) to a running jupyter-client
(the replacement of ipython
)
I prefer to separate editor and interpreter (each one in its shell). Imagine you send a bad input reading command ...
Instead of putting the command mapping in your .vimrc
, put the mapping in your ~/.vim/ftplugin/python.vim
file (Windows $HOME\vimfiles\ftplugin\python.vim
). If you don't have this file or directories, just make them. This way the key is only mapped when you open a .py
file or any file with filetype=python
, since you'll only be running this command on Python scripts.
For the actual mapping, I like to be able to edit in Vim while the script runs. Going off of @cazyas' answer, I have the following in my ftplugin\python.vim
(Windows):
noremap <F5> <Esc>:w<CR>:!START /B python %<CR>
This will run the current Python script in the background. For Linux just change it to this:
noremap <F5> <Esc>:w<CR>:!python % &<CR>
Put your cursor in the code somewhere. Right click and choose one of the "Select" choices to highlight your code. Then press Ctrl : and you will see the new prompt '<, >'
Now type !python and see if that works.
I just spend days trying to figure out the same problem!!! I used the coding:
s='My name'
print (s)
After I pulled out all my hair, I finally got it right!
I have this on my .vimrc:
"map <F9> :w<CR>:!python %<CR>"
which saves the current buffer and execute the code with presing only Esc + F9
Keep in mind that you're able to repeat the last used command with @:
, so that's all you'd need to repeat are those two character.
Or you could save the string w !python
into one of the registers (like "a
for example) and then hit :<C-R>a<CR>
to insert the contents of register a
into the commandline and run it.
Or you can do what I do and map <leader>z
to :!python %<CR>
to run the current file.
A simple method would be to type :
while in normal mode, and then press the up arrow key on the keyboard and press Enter. This will repeat the last typed commands on VIM.
I have this in my .vimrc file:
imap <F5> <Esc>:w<CR>:!clear;python %<CR>
When I'm done editing a Python script, I just press <F5>
. The script is saved and then executed in a blank screen.
I use
:! [filename.py]; python %
That's what works for me
Source: Stackoverflow.com