Esecuzione di codice Python in Vim


104

Sto scrivendo codice Python usando Vim e ogni volta che voglio eseguire il mio codice, lo digito all'interno di Vim:

:w !python

Questo diventa frustrante, quindi stavo cercando un metodo più rapido per eseguire codice Python all'interno di Vim. Forse si eseguono script Python da un terminale? Sto usando Linux.

Risposte:


145

Che ne dici di aggiungere un autocmdal tuo ~/.vimrcfile, creando una mappatura:

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>

quindi è possibile premere <F9>per eseguire il buffer corrente conpython

Spiegazione:

  • autocmd: comando su cui Vim eseguirà automaticamente {event}(qui: se apri un file python)
  • [i]map: crea una scorciatoia da tastiera <F9>in modalità inserimento / normale
  • <buffer>: Se sono aperti più buffer / file: usa semplicemente quello attivo
  • <esc>: uscita dalla modalità di inserimento
  • :w<CR>: salva il tuo file
  • !: esegue il seguente comando nella tua shell (prova :!ls)
  • %: è sostituito dal nome del file del buffer attivo. Ma poiché può contenere cose come spazi bianchi e altre cose "cattive" è meglio non scrivere :python %, ma usare:
  • shellescape: sfugge ai caratteri speciali. I 1mezzi con una barra rovesciata

TL; DR: la prima riga funzionerà in modalità normale e una volta premuta <F9>salva prima il file e quindi esegue il file con python. Il secondo fa la stessa cosa, ma lascia prima la modalità di inserimento


6
Puoi espandere la tua risposta e spiegare dove dovrei aggiungere quella riga. All'interno di un file di configurazione di Vim forse? Sono un novellino.
multigoodverse

5
@ArditSulce nel tuo file vimrc, aggiungi una riga:autocmd FileType python nnoremap <buffer> ....
Kent

2
Se sei su os x (e presumo unix) ".vimrc" è nella directory home. Puoi verificarlo digitando ': version' in modalità comando per assicurarti che vedrai una riga chiamata 'user vimrc file: "..."'
ThinkBonobo

C'è un modo per salvare ed eseguire lo stesso file, invece di eseguirlo
Bharat

5
nnoremap <buffer> <F9> :!python %<cr>sembra funzionare in Vim 7.4.1689. A cosa serve la conchiglia?
Matt Kleinsmith

32

Vai alla modalità normale premendo <esc>e digita:

! clear; python %

inserisci qui la descrizione dell'immagine

Spiegazione passo passo:

! ti permette di eseguire un comando da terminale

clear svuoterà lo schermo del terminale

; termina il primo comando, consentendo di introdurre un secondo comando

pythonuserà python per eseguire il tuo script (potrebbe essere sostituito con rubyper esempio)

%concatena il nome del file corrente, passandolo come parametro al pythoncomando


27

Ho questo nel mio file .vimrc:

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

Quando ho finito di modificare uno script Python, premo semplicemente <F5>. Lo script viene salvato e quindi eseguito in una schermata vuota.


Grazie! Funziona abbastanza bene. Mi chiedo come faccio a impostare la scorciatoia su mtasto più ,tasto invece che F5tasto?
Jay Wong

Non vedo come si salva prima il file?
Thomas Browne

Scusa, ho dimenticato di aggiungere ": w". L'ho corretto e ho aggiunto anche <Esc>.
czayas

1
Va notato che questo viene eseguito in Insertmodalità. Per l'esecuzione in Normalmodalità usa nmapinvece di imap.
Marcin

16

Preferisco l'output di Python reindirizzato a una nuova finestra di Vim (e se quella finestra viene lasciata aperta, aggiorna il suo contenuto la prossima volta che esegui codice Python con questa funzione):

" 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

Devo inserire questo diritto nel mio .vimrc? In caso contrario, come dovrei dare questo script a vim? (Noob qui)
Benjamin Chausse

1
@BenjaminChausse Ci scusiamo per il ritardo nella risposta. Ho fatto un test con un .vimrc che conteneva esclusivamente quel codice e ha funzionato da quello che ho potuto dire. I miei test erano limitati all'apertura di un file .py e al premere F5, il che ha comportato la visualizzazione dell'output di python in una finestra di vim separata. "come dovrei dare questo script a vim?". Dipende dal tuo sistema operativo. Sto usando Windows quindi ho un file di testo C: \ Program Files (x86) \ Vim \ .vimrc che contiene quel codice (potresti anche chiamarlo "_vimrc" in Windows). In Linux o mac avresti un file di testo .vimrc nella tua cartella home cioè ~ / .vimrc
FocusedWolf

2
Sebbene ci rendiamo conto che questo potrebbe aver richiesto molto lavoro per crearlo, inserire collegamenti paypal in una risposta non è davvero appropriato.
Martijn Pieters

10

Basandosi sulle risposte precedenti, se ti piace vedere il codice mentre guardi il suo output potresti trovare utile il comando :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>

L'utilizzo vertnella seconda riga esegue il codice in divisione verticale anziché orizzontale.

Lo svantaggio è che se non chiudi la finestra divisa in cui è stato eseguito il codice, avrai molte divisioni dopo più esecuzioni (cosa che non accade nell'IDLE originale di python dove viene riutilizzata la stessa finestra di output).

(Tengo queste righe dentro /home/user/.vimrc)


5

Tieni presente che puoi ripetere l'ultimo comando utilizzato con @:, quindi è tutto ciò che devi ripetere sono quei due caratteri.

Oppure puoi salvare la stringa w !pythonin uno dei registri (come "aper esempio) e poi premere :<C-R>a<CR>per inserire il contenuto del registro anella riga di comando ed eseguirlo.

Oppure si può fare quello che faccio e traccio <leader>zper :!python %<CR>eseguire il file corrente.


3

Se non vuoi che " :exec python file.py" venga stampato ogni volta, usa questo:

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

Non ha nemmeno rovinato la mia barra di stato powerline / vim-airlines.


3

Plugin: jupyter-vim

Quindi puoi inviare righe ( <leader>E), selezione visiva ( <leader>e) a una corsa jupyter-client(la sostituzione di ipython)

inserisci qui la descrizione dell'immagine

Preferisco separare editor e interprete (ognuno nella sua shell). Immagina di inviare un comando di lettura di input errato ...


2

Per un uso generico (eseguire python / haskell / ruby ​​/ C ++ ... da vim basato su filetype), c'è un bel plugin chiamato vim-quickrun . Supporta molti linguaggi di programmazione per impostazione predefinita. È anche facilmente configurabile, quindi si possono definire comportamenti preferiti per qualsiasi tipo di file, se necessario. Il repository github non ha un file readme di fantasia, ma è ben documentato con il file doc.


2

La risposta accettata funziona per me (su Linux), ma volevo che questo comando salvasse anche il buffer prima di eseguirlo, quindi l'ho modificato leggermente:

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

Il :w <bar>salva il buffer POI esegue il codice in esso.


1

Un metodo semplice sarebbe quello di digitare :in modalità normale, quindi premere il tasto freccia su sulla tastiera e premere Invio. Questo ripeterà gli ultimi comandi digitati su VIM.


È possibile eseguire una ricerca incrementale digitando i caratteri iniziali del comando prima di premere la freccia su. Se molti comandi fa ho fatto un! python%, potrei:! quindi premere la freccia su, per scorrere solo i comandi che iniziano con!
shmup

1

Se vuoi tornare indietro rapidamente tra i :wcomandi, una cosa interessante è digitare :we poi premere la freccia su. Passerà solo attraverso i comandi che iniziano con w.


1

Ho questo sul mio .vimrc:

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

che salva il buffer corrente ed esegue il codice presing solo Esc + F9



1

Puoi estendere per qualsiasi lingua con 1 combinazione di tasti con il comando augroup, ad esempio:

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

1

Pensa di usare la linea shebang, così sarai in grado di usarla con qualsiasi linguaggio, non solo Python.

Aggiunta di shebang:

Aggiungi questo alla prima riga del tuo script:

#!/usr/bin/env python3

o questo, se stai usando Python 2:

#!/usr/bin/env python2

Mappa dei tasti di Vim:

Aggiungi questo al tuo ~/.vimrc:

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

Rendi il file eseguibile:

Digita Vim:

:!chmod +x %

o nel terminale:

chmod +x script_name.py

Spiegazione:

Quando F7 viene premuto in modalità normale, Vim proverà ad eseguire il file corrente come script bash. Quindi l'interprete di bash vedrà la riga shebang e capirà che questo file dovrebbe essere passato a Python (o qualsiasi altro programma se necessario).

Inoltre sarai in grado di eseguire il tuo script dal terminale usando il suo nome:

./script_name.py

invece di questo modo (funzionerà anche questo):

python3 script_name.py

0

Questa mappatura .vimrc necessita di Conque Shell , ma replica il comportamento di Geany (e di altri editor X):

  • Premere un tasto per eseguire
  • Viene eseguito in gnome-terminal
  • Attende conferma per uscire
  • La finestra si chiude automaticamente all'uscita

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


0

Posiziona il cursore nel codice da qualche parte. Fare clic con il tasto destro e scegliere una delle opzioni "Seleziona" per evidenziare il codice. Quindi premi Ctrl: e vedrai il nuovo prompt '<,>'

Ora digita! Python e vedi se funziona.

Ho solo passato giorni a cercare di capire lo stesso problema !!! Ho usato la codifica:

s='My name'
print (s) 

Dopo aver tirato fuori tutti i capelli, finalmente ho capito bene!


5
Uso del mouse non in modo vim
0xc0de

1
Ma è possibile farlo :% !python. %significa solo tutte le linee.
T.Chmelevskij

0

Invece di inserire la mappatura dei comandi nel tuo .vimrc, inserisci la mappatura nel tuo ~/.vim/ftplugin/python.vimfile (Windows $HOME\vimfiles\ftplugin\python.vim). Se non hai questo file o directory, creali e basta. In questo modo la chiave viene mappata solo quando apri un .pyfile o qualsiasi file con filetype=python, poiché eseguirai questo comando solo su script Python.

Per la mappatura effettiva, mi piace poter modificare in Vim mentre lo script viene eseguito. Uscendo dalla risposta di @cazyas, ho quanto segue nel mio ftplugin\python.vim(Windows):

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

Questo eseguirà lo script Python corrente in background. Per Linux basta cambiarlo in questo:

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

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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.