Executando código Python no Vim

103

Estou escrevendo código Python usando o Vim e sempre que quero executar meu código, digito dentro do Vim:

:w !python

Isso é frustrante, então eu estava procurando um método mais rápido para executar o código Python dentro do Vim. Executando scripts Python de um terminal, talvez? Estou usando o Linux.

multigoodverso
fonte

Respostas:

144

Que tal adicionar um autocmdao seu ~/.vimrc-arquivo, criando um mapeamento:

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>

então você pode pressionar <F9>para executar o buffer atual compython

Explicação:

  • autocmd: comando que o Vim executará automaticamente {event}(aqui: se você abrir um arquivo python)
  • [i]map: cria um atalho de teclado para <F9>o modo de inserção / normal
  • <buffer>: Se vários buffers / arquivos estiverem abertos: basta usar o ativo
  • <esc>: saindo do modo de inserção
  • :w<CR>: salva seu arquivo
  • !: executa o seguinte comando em seu shell (tente :!ls)
  • %: é substituído pelo nome do arquivo de seu buffer ativo. Mas, uma vez que pode conter coisas como espaços em branco e outras coisas "ruins", é melhor não escrever :python %, mas usar:
  • shellescape: escapar dos caracteres especiais. O 1meio com uma barra invertida

TL; DR: A primeira linha funcionará no modo normal e, uma vez pressionada <F9>, primeiro salva seu arquivo e, em seguida, executa o arquivo com o python. O segundo faz a mesma coisa, mas sai do modo de inserção primeiro

Kent
fonte
6
Você pode expandir sua resposta e explicar onde devo adicionar essa linha. Dentro de um arquivo de configuração do Vim, talvez? Eu sou um newby.
multigoodverse
5
@ArditSulce em seu arquivo vimrc, adicione uma linha:autocmd FileType python nnoremap <buffer> ....
Kent,
2
Se você estiver no sistema operacional x (e presumo que seja unix), ".vimrc" está no diretório inicial. Você pode verificar isso digitando ': versão' no modo de comando para ter certeza de que verá uma linha chamada 'arquivo vimrc do usuário: "..."'
ThinkBonobo
Existe uma maneira de salvar e executar o mesmo arquivo, em vez de apenas executá-lo
Bharat
5
nnoremap <buffer> <F9> :!python %<cr>parece funcionar no Vim 7.4.1689. Para que serve a shellescape?
Matt Kleinsmith,
31

Basta ir para o modo normal pressionando <esc>e digite:

! clear; python %

insira a descrição da imagem aqui

Explicação passo a passo:

! permite que você execute um comando de terminal

clear irá esvaziar a tela do seu terminal

; termina o primeiro comando, permitindo que você introduza um segundo comando

pythonusará python para executar seu script (ele pode ser substituído por, rubypor exemplo)

%concatam o nome do arquivo atual, passando-o como um parâmetro para o pythoncomando

Flavio Wuensche
fonte
27

Eu tenho isso em meu arquivo .vimrc:

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

Quando termino de editar um script Python, simplesmente pressiono <F5>. O script é salvo e executado em uma tela em branco.

czayas
fonte
Obrigado! Funciona muito bem. Eu me pergunto como posso definir o atalho para mtecla mais ,tecla em vez de F5tecla?
Jay Wong
Não estou vendo como isso salva o arquivo primeiro?
Thomas Browne
Desculpe, esqueci de adicionar ": w". Eu corrigi e adicionei <Esc> também.
czayas 01 de
1
Deve-se observar que ele é executado no Insertmodo. Para execução no Normalmodo, use em nmapvez de imap.
Marcin
16

Eu prefiro a saída do Python redirecionada para uma nova janela do Vim (e se essa janela for deixada aberta, atualize seu conteúdo na próxima vez que você executar o código Python com esta função):

" 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
FocusedWolf
fonte
Devo inserir esse direito no meu .vimrc? Se não, como devo dar este script ao vim? (Noob aqui)
Benjamin Chausse
1
@BenjaminChausse Desculpe pela demora na resposta. Fiz um teste com um .vimrc que continha exclusivamente esse código e funcionou pelo que pude perceber. Meu teste se limitou a abrir um arquivo .py e pressionar F5, o que resultou na saída do python em uma janela separada do vim. "como devo dar este script ao vim?". Depende do seu sistema operacional. Estou usando o Windows, então tenho um arquivo de texto C: \ Arquivos de Programas (x86) \ Vim \ .vimrc que contém esse código (você também pode chamá-lo de "_vimrc" no Windows). No Linux ou Mac, você teria um arquivo de texto .vimrc em sua pasta pessoal, por exemplo, ~ / .vimrc
FocusedWolf
2
Embora reconheçamos que isso pode ter demandado muito trabalho para criar, colocar links do paypal em uma resposta não é realmente apropriado.
Martijn Pieters
10

Com base nas respostas anteriores, se você gosta de ver o código enquanto observa sua saída, o comando find :ter( :terminal) pode ser útil.

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

Usar vertna segunda linha executa o código em divisão vertical em vez de horizontal.

O negativo disso é que, se você não fechar a janela dividida onde o código foi executado, você terá muitas divisões após várias execuções (o que não acontece no IDLE original do python, onde a mesma janela de saída é reutilizada).

(Eu mantenho essas linhas dentro /home/user/.vimrc)

Segunda-feira
fonte
5

Lembre-se de que você pode repetir o último comando usado com @:, portanto, tudo o que você precisa repetir são esses dois caracteres.

Ou você pode salvar a string w !pythonem um dos registradores (como "apor exemplo) e então clicar :<C-R>a<CR>para inserir o conteúdo do registrador ana linha de comando e executá-lo.

Ou você pode fazer o que faço e mapear <leader>zpara :!python %<CR>executar o arquivo atual.

TankorSmash
fonte
3

Se você não quiser ver " :exec python file.py" impresso todas as vezes, use isto:

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

Não bagunçou minha barra de status powerline / vim-flight também.

Jabba
fonte
3

Plugin: jupyter-vim

Assim, você pode enviar linhas ( <leader>E), seleção visual ( <leader>e) para uma execução jupyter-client(a substituição de ipython)

insira a descrição da imagem aqui

Eu prefiro separar o editor e o interpretador (cada um em seu shell). Imagine que você envia um comando de leitura de entrada incorreto ...

Tinmarino
fonte
2

Para uso genérico (execute python / haskell / ruby ​​/ C ++ ... do vim baseado no filetype), há um bom plugin chamado vim-quickrun . Ele suporta muitas linguagens de programação por padrão. Também é facilmente configurável, portanto, é possível definir comportamentos preferenciais para qualquer tipo de arquivo, se necessário. O repo github não tem um leia-me sofisticado, mas está bem documentado com o arquivo doc.

Yosh
fonte
2

A resposta aceita funciona para mim (no Linux), mas eu queria que esse comando também salvasse o buffer antes de executar, então modifiquei um pouco:

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

O :w <bar>salva o buffer ENTÃO executa o código nele.

Alijah O'Connor
fonte
1

Um método simples seria digitar :no modo normal e, em seguida, pressionar a tecla de seta para cima no teclado e pressionar Enter. Isso repetirá os últimos comandos digitados no VIM.

multigoodverso
fonte
Você pode fazer uma pesquisa incremental digitando os caracteres iniciais do comando antes de pressionar a seta para cima. Se muitos comandos atrás eu fiz um! python%, eu poderia:! em seguida, pressione a seta para cima para percorrer apenas os comandos que começam com!
shmup
1

Se você quiser voltar rapidamente aos :wcomandos, uma coisa legal é digitar :we pressionar a seta para cima. Só percorrerá os comandos que começam com w.

shmup
fonte
1

Eu tenho isso no meu .vimrc:

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

que salva o buffer atual e executa o código pressionando apenas Esc + F9

Derwin
fonte
1

Você pode usar skywind3000 / asyncrun.vim também. É semelhante ao que @FocusedWolf listou.

Mike
fonte
1

Você pode estender para qualquer idioma com 1 atalho de teclado com o comando augroup, por exemplo:

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
Đạt Nguyễn Thành
fonte
1

Pense em usar a linha shebang, para que seja capaz de usá-la com qualquer linguagem, não apenas Python.

Adicionando shebang:

Adicione isto à primeira linha do seu script:

#!/usr/bin/env python3

ou isto, se você estiver usando Python 2:

#!/usr/bin/env python2

Mapa de teclado do Vim:

Adicione isto ao seu ~/.vimrc:

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

Tornar o arquivo executável:

Digite no Vim:

:!chmod +x %

ou no terminal:

chmod +x script_name.py

Explicação:

Quando F7 é pressionado no modo normal, o Vim tentará executar o arquivo atual como um script bash. Então o interpretador bash verá a linha shebang e entenderá que este arquivo deve ser passado para Python (ou qualquer outro programa, se necessário).

Além disso, você poderá executar seu script a partir do terminal usando seu nome:

./script_name.py

em vez desta forma (isso também funcionará):

python3 script_name.py
Саша Кошкин
fonte
0

Este mapeamento .vimrc precisa do Conque Shell , mas replica o comportamento do Geany (e de outros editores X):

  • Pressione uma tecla para executar
  • Executa no gnome-terminal
  • Aguarda confirmação para sair
  • A janela fecha automaticamente na saída

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

user2587717
fonte
0

Coloque o cursor em algum lugar do código. Clique com o botão direito e escolha uma das opções "Selecionar" para destacar seu código. Em seguida, pressione Ctrl: e você verá o novo prompt '<,>'

Agora digite! Python e veja se funciona.

Passei dias tentando resolver o mesmo problema !!! Eu usei a codificação:

s='My name'
print (s) 

Depois de arrancar todo o meu cabelo, finalmente acertei!

Bob Cressman
fonte
5
Usando o mouse de maneira diferente do vim
0xc0de
1
Mas é possível fazer :% !python. %significa apenas todas as linhas.
T.Chmelevskij
0

Em vez de colocar o mapeamento de comando em seu .vimrc, coloque o mapeamento em seu ~/.vim/ftplugin/python.vimarquivo (Windows $HOME\vimfiles\ftplugin\python.vim). Se você não tiver esse arquivo ou diretórios, basta criá-los. Desta forma, a chave só é mapeada quando você abre um .pyarquivo ou qualquer arquivo comfiletype=python , uma vez que você só executará este comando em scripts Python.

Para o mapeamento real, gosto de poder editar no Vim enquanto o script é executado. Saindo da resposta de @cazyas, tenho o seguinte no meu ftplugin\python.vim(Windows):

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

Isso executará o script Python atual em segundo plano. Para Linux, basta alterá-lo para:

noremap <F5> <Esc>:w<CR>:!python % &<CR>
jpyams
fonte
0
" 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>
Neo Mosaid
fonte