在Vim中运行Python代码

问题:在Vim中运行Python代码

我正在使用Vim编写Python代码,每次我想运行我的代码时,都在Vim中键入以下代码:

:w !python

这令人沮丧,所以我一直在寻找一种更快的方法来在Vim中运行Python代码。从终端执行Python脚本吗?我正在使用Linux。

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.


回答 0

如何将-添加autocmd到您的~/.vimrc-file,创建映射:

autocmd FileType python map <buffer> <F9> :w<CR>:exec '!python3' shellescape(@%, 1)<CR>
autocmd FileType python imap <buffer> <F9> <esc>:w<CR>:exec '!python3' shellescape(@%, 1)<CR>

然后您可以按<F9>来执行当前缓冲区python

说明:

  • autocmd:Vim将在其上自动执行的命令{event}(此处:如果您打开python文件)
  • [i]map:创建<F9>在插入/普通模式下的键盘快捷键
  • <buffer>:如果打开了多个缓冲区/文件:只需使用活动的缓冲区/文件
  • <esc>:离开插入模式
  • :w<CR>:保存文件
  • !:在您的shell中运行以下命令(尝试:!ls
  • %:替换为活动缓冲区的文件名。但是由于它可以包含空格和其他“坏”的东西,所以最好不要写:python %,而要使用:
  • shellescape:转义特殊字符。该1用反斜杠手段

TL; DR:第一行将在正常模式下工作,一旦按下<F9>它,首先保存文件,然后使用python运行文件。第二个做同样的事情,但是先离开插入模式

How about adding an autocmd to your ~/.vimrc-file, creating a mapping:

autocmd FileType python map <buffer> <F9> :w<CR>:exec '!python3' shellescape(@%, 1)<CR>
autocmd FileType python imap <buffer> <F9> <esc>:w<CR>:exec '!python3' shellescape(@%, 1)<CR>

then you could press <F9> to execute the current buffer with python

Explanation:

  • autocmd: command that Vim will execute automatically on {event} (here: if you open a python file)
  • [i]map: creates a keyboard shortcut to <F9> in insert/normal mode
  • <buffer>: If multiple buffers/files are open: just use the active one
  • <esc>: leaving insert mode
  • :w<CR>: saves your file
  • !: runs the following command in your shell (try :!ls)
  • %: is replaced by the filename of your active buffer. But since it can contain things like whitespace and other “bad” stuff it is better practise not to write :python %, but use:
  • shellescape: escape the special characters. The 1 means with a backslash

TL;DR: The first line will work in normal mode and once you press <F9> it first saves your file and then run the file with python. The second does the same thing, but leaves insert mode first


回答 1

只需按<esc>并输入以下内容即可进入普通模式:

! clear; python %

逐步说明:

! 允许您运行终端命令

clear 将清空您的终端屏幕

; 结束第一个命令,使您可以引入第二个命令

python将使用python运行脚本(ruby例如可以替换为脚本 )

%合并当前文件名,并将其作为参数传递给 python命令

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 with ruby for example)

% concats the current filename, passing it as a parameter to the python command


回答 2

我的.vimrc文件中有这个:

imap <F5> <Esc>:w<CR>:!clear;python %<CR>

完成Python脚本的编辑后,只需按<F5>。保存脚本,然后在空白屏幕中执行。

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.


回答 3

我更喜欢将Python输出重定向到新的Vim窗口(如果该窗口保持打开状态,则下次使用此函数执行Python代码时更新其内容):

" 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

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

回答 4

基于前面的答案,如果您希望在查看代码输出时看到代码,则可以找到:ter:terminal)命令。

autocmd Filetype python nnoremap <buffer> <F5> :w<CR>:ter python2 "%"<CR>
autocmd Filetype python nnoremap <buffer> <F6> :w<CR>:vert ter python3 "%"<CR>

vert在第二行中使用时,代码以垂直分割而不是水平分割运行。

不利的是,如果不关闭代码运行所在的拆分窗口,则在多次运行后您将有很多拆分(这在原始的python IDLE中不会发生,在该Python IDLE中重复使用了相同的输出窗口)。

(我将这些行留在里面/home/user/.vimrc

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)


回答 5

请记住,您可以使用来重复上次使用的命令@:,因此您只需要重复这两个字符即可。

或者,您可以将字符串保存w !python到其中一个寄存器中("a例如),然后单击:<C-R>a<CR>以将寄存器的内容插入a命令行并运行它。

或者你可以做我想做的,并映射<leader>z:!python %<CR>运行当前文件。

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.


回答 6

如果您不想:exec python file.py每次看到“ ”打印,请使用以下命令:

nnoremap <F9> :echo system('python2 "' . expand('%') . '"')<cr>
nnoremap <F10> :echo system('python3 "' . expand('%') . '"')<cr>

它也没有弄乱我的电源线/ vim-航空公司状态栏。

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.


回答 7

插件:jupyter-vim

因此,您可以向正在运行的行(替换)发送行(<leader>E),视觉选择()<leader>ejupyter-clientipython

我更喜欢将编辑器和解释器分开(每个都在其外壳中)。假设您发送了错误的输入阅读命令…

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 …


回答 8

对于一般用途(基于,从vim运行python / haskell / ruby​​ / C ++ … filetype),有一个不错的插件,称为vim-quickrun。默认情况下,它支持多种编程语言。它也很容易配置,因此可以根据需要为任何文件类型定义首选行为。github仓库没有花哨的自述文件,但doc文件对此进行了很好的记录。

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.


回答 9

可接受的答案对我有用(在Linux上),但是我希望此命令在运行之前也可以保存缓冲区,因此我对其进行了一些修改:

nnoremap <buffer> <F9> :w <bar> :exec '!python' shellescape(@%, 1)<cr>

:w <bar>然后保存缓冲中运行的代码。

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.


回答 10

一种简单的方法是:在正常模式下键入内容,然后按键盘上的向上箭头键,然后按Enter。这将在VIM上重复最后键入的命令。

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.


回答 11

如果您想快速跳回:w命令,可以输入以下内容:w,然后按向上箭头。它只会循环搜索以开头的命令w

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.


回答 12

我的.vimrc上有这个:

"map <F9> :w<CR>:!python %<CR>"

这将保存当前缓冲区并仅使用Esc + F9执行代码

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


回答 13

您也可以使用skywind3000 / asyncrun.vim。它类似于@FocusedWolf列出的内容。

You can use skywind3000/asyncrun.vim as well. It is similar to what @FocusedWolf has listed.


回答 14

您可以使用augroup命令通过1个键盘绑定扩展到任何语言,例如:

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 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


回答 15

考虑使用shebang行,这样您就可以使用任何语言,而不仅限于Python。

添加shebang:

将此添加到脚本的第一行:

#!/usr/bin/env python3

或者,如果您使用的是Python 2:

#!/usr/bin/env python2

Vim键盘映射:

将此添加到您的~/.vimrc

nmap <F7> :w<cr>:!clear;"%:p"<cr>

使文件可执行:

输入Vim:

:!chmod +x %

或在终端:

chmod +x script_name.py

说明:

在正常模式下按F7时,Vim会尝试将当前文件作为bash脚本执行。然后,bash解释器将看到shebang行并了解该文件应传递给Python(或在需要时传递给其他程序)。

另外,您将能够使用其名称从终端运行脚本:

./script_name.py

而不是这种方式(也可以):

python3 script_name.py

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

回答 16

此.vimrc映射需要Conque Shell,但它会复制Geany(和其他X编辑器)的行为:

  • 按一个键执行
  • 在gnome-terminal中执行
  • 等待确认退出
  • 窗口在退出时自动关闭

    :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; \" "')

This .vimrc mapping needs Conque Shell, but it replicates Geany (and other X editors’) behaviour:

  • Press a key to execute
  • Executes in gnome-terminal
  • Waits for confirmation to exit
  • 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; \" "')


回答 17

将光标放在代码中的某个位置。右键单击并选择“选择”选项之一以突出显示您的代码。然后按Ctrl:您将看到新的提示“ <,>”

现在输入!python,看看是否可行。

我只是花几天的时间来找出同样的问题!!!我使用了编码:

s='My name'
print (s) 

拔完头发后,我终于弄对了!

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!


回答 18

不要将命令映射放入您的中.vimrc,而是将映射放入~/.vim/ftplugin/python.vim文件中(Windows $HOME\vimfiles\ftplugin\python.vim)。如果您没有此文件或目录,请进行创建。这样,仅当您打开.py文件或任何带有的文件时,才会映射键filetype=python,因为您将仅在Python脚本上运行此命令。

对于实际的映射,我希望能够在脚本运行时在Vim中进行编辑。从@cazyas的答案出发,我在ftplugin\python.vimWindows中有以下内容:

noremap <F5> <Esc>:w<CR>:!START /B python %<CR>

这将在后台运行当前的Python脚本。对于Linux,只需将其更改为:

noremap <F5> <Esc>:w<CR>:!python % &<CR>

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>

回答 19

" 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>
" 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>