2009-06-04 8 views
87

Come eseguire il file che sto modificando in Vi (m) e ottenere l'output in finestra divisa (come in SciTE)?Come eseguire il file che sto modificando in Vi (m)

Naturalmente potrei eseguirlo così:

:!scriptname 

Ma è posible di evitare di scrivere il nome dello script e come per ottenere l'output in una finestra divisa invece solo parte inferiore dello schermo?

+19

:!% Ti consente di evitare di scrivere 'scriptname'. Le soluzioni sottostanti sono migliori, ma ho pensato di menzionarlo nel caso in cui decidessi:!% È abbastanza buono. – overthink

+10

Un'altra nota, è possibile utilizzare%: p (anziché solo%) per fare riferimento al percorso assoluto del file corrente. Questo potrebbe essere necessario se la tua directory corrente è altrove. – andy

+4

per eseguire gli script ruby:! Ruby% farà il trucco –

risposta

103

C'è il comando make. Esegue il comando impostato nell'opzione makeprg. Utilizzare % come segnaposto per il nome file corrente. Ad esempio, se stavi modificando uno script python:

:set makeprg=python\ % 

Sì, è necessario sfuggire allo spazio. Dopo questo si può eseguire semplicemente:

:make 

Se si desidera, è possibile impostare l'opzione autowrite e sarà salvare automaticamente prima di eseguire l'makeprg:

:set autowrite 

Questo risolve la parte eseguire. Non conosco alcun modo per ottenere quell'output in una finestra divisa che non implichi il reindirizzamento al file.

+5

In realtà, la tua soluzione ottiene l'output in una finestra divisa. Usa ': copen' per aprire la" lista degli errori "prodotta eseguendo': make'.in la propria finestra. Sfortunatamente, per fare in modo che l'output sia formattato correttamente, è necessaria una certa risoluzione dell'opzione 'errorformat'. In caso contrario, si presume che l'output sia del formato che gcc emette. –

+2

Sei dannatamente sicuro di "capovolgere" errorformat. Sembra un codice perl che ho visto ... –

+1

Questa funzione è disponibile per la "creazione" del progetto da vim (dà a Vim la capacità di IDE). La soluzione di Brian Carper (': let f = expand ("% ") | vnew | execute '.! Ruby". F.' "'') Sebbene sembri criptica, funziona esattamente come richiesto dall'autore della domanda. – AjayKumarBasuthkar

28

Per accedere al nome file del buffer corrente, utilizzare %. Per inserirlo in una variabile puoi utilizzare la funzione expand(). Per aprire una nuova finestra con un nuovo buffer, utilizzare :new o :vnew. Per reindirizzare l'output da un comando al buffer corrente, utilizzare :.!. Mettere tutto insieme:

:let f=expand("%")|vnew|execute '.!ruby "' . f . '"' 

ovviamente sostituendo ruby con qualsiasi comando che si desidera. Ho usato execute così ho potuto racchiudere il nome del file tra virgolette, quindi funzionerà se il nome del file contiene degli spazi.

+0

Sai fare un comando personalizzato dalla tua soluzione? – Rn2dy

+2

@baboonWorksFine Usa ': comando! R let f = expand ("%") | vnew | execute '.! Ruby "'. F. '"' 'Per poter usare semplicemente': ​​R' per eseguire il suo comando – xorpaul

+0

Sarebbe possibile effettuare questa esecuzione anche con script che richiedono l'input dell'utente durante l'esecuzione? – Ilias95

1

Io uso un meccanismo un po 'più invadente attraverso le mappe:

map ;e :w<CR>:exe ":!python " . getreg("%") . "" <CR> 

Proprio lo rende così non ho salvare, poi andare. Vai.

+1

Se si imposta l'opzione autowrite, è possibile eseguire: make e ... salva prima. –

4

Per Shell script che ho usato

:set makeprg=% 

:make 
+3

cosa non va con '! % '? – ErichBSchulz

19

Vim ha il comando ! ("bang"), che esegue comandi di shell direttamente dalla finestra VIM. Inoltre consente di avviare la sequenza di comandi che sono collegati con pipe e leggere stdout.

Ad esempio:

! node % 

equivale ad aprire finestra di comando e lanciare comandi:

cd my_current_directory 
node my_current_file 

Vedi "Vim tips: Working with external commands" per i dettagli.

9

Ho una scorciatoia per che nel mio vimrc:

nmap <F6> :w<CR>:silent !chmod 755 %<CR>:silent !./% > .tmp.xyz<CR> 
    \ :tabnew<CR>:r .tmp.xyz<CR>:silent !rm .tmp.xyz<CR>:redraw!<CR> 

Questo scrive il buffer corrente, rende il file eseguibile corrente (solo Unix), la esegue (solo Unix) e reindirizza l'output a .tmp .xyz, quindi crea una nuova scheda, legge il file e quindi lo elimina.

scomponendola:

:w<CR>        write current buffer 
:silent !chmod 755 %<CR>   make file executable 
:silent !./% > .tmp.xyz<CR>  execute file, redirect output 
:tabnew<CR>      new tab 
:r .tmp.xyz<CR>     read file in new tab 
:silent !rm .tmp.xyz<CR>   remove file 
:redraw!<CR>      in terminal mode, vim get scrambled 
            this fixes it 
+1

Mi è piaciuta molto la tua soluzione e, dopo un po 'di utilizzo, ho ritenuto che potesse essere migliorata. Quindi ecco il mio modo di pensare: ': w : silent! Chmod + x%: p : silent!%: P 2> & 1 | tee ~/.vim/output : split ~/.vim/output : ridisegna! '- questo reindirizza sia lo stdout che lo stderr al file temporaneo e, prima di farlo, stampa tutto sullo stdout, quindi se uno script impiega molto tempo per essere eseguito lo vedi effettivamente funzionante. Inoltre, è indipendente dalla directory (ricevevo errori durante l'apertura dei file tramite il loro percorso assoluto). Tuttavia, non esegue gli script in modo interattivo e non ho trovato il modo di renderlo tale. –

+1

fyi - sulla soluzione di @Cyril, ho dovuto sfuggire al simbolo pipe: | -> \ | – mpettis

1

È possibile utilizzare il plugin di vim bexec. Per quanto ne so, l'ultima versione è 0.5.

Poi:

$ mkdir -p ~/.vim/plugin 
$ mv bexec-0.5.vba ~/.vim/plugin 
$ vim ~/.vim/plugin/bexec-0.5.vba 

All'interno vim stesso, mentre la modifica del file .vba fare:

:so % 

Alcuni uscita apparirà ti permette di sapere che bexec.vim è stato scritto pure come documentazione, ecc.

Ora puoi testarlo aprendo il tuo (qualsiasi script di lingua che ha un interprete #! funzionante correttamente) in vim ed eseguire

:Bexec 

Nota: volevo la scissione per essere verticale e non orizzontale, così ho fatto:

$ grep -i -n split ~/.vim/plugin/bexec.vim | grep -i hor 
102: let bexec_splitdir = "hor" " hor|ver 
261:  exec {"ver":"vsp", "hor":"sp"}[g:bexec_splitdir] 

e cambiato il valore di da "hor" a "ver" ..

So che è una vecchia domanda, ma spero che questo possa aiutare qualcuno là fuori. Sono stato in esecuzione nello stesso numero durante l'assunzione di corso di Ingegneria di avvio del Coursera dove professore Palaji utilizza Emacs e non mi piace Emacs ..

+0

È necessario modificare le impostazioni relative alle preferenze nel proprio .vimrc locale. bexec offre l'impostazione "let bexec_splitdir = 'hor'" che può farlo senza modificare il codice del plugin. –

0

Sulla base @SethKriticos e risposte @Cyril io uso il seguente:

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> 

Utilizzare F9 per impostare la nuova finestra e F2 per eseguire lo script e il tee sul file di output.

Ho anche aggiunto il nome dello script al nome del file di output, in modo che sia possibile utilizzarlo contemporaneamente per più script.

0

@xorpaul

ero alla ricerca di questo script (python/Windows) per un bel po 'di tempo. Poiché non esiste un "tee" in Windows ho cambiato in:

function! Setup_ExecNDisplay() 
    execute "w" 
    let n=expand('%:t') 
    execute "silent ! python % > d:\\temp\\output_".n ." 2>&1" 
    execute "vsplit d:\\temp\\output_".n 
    execute "redraw!" 
    set autoread 
endfunction 

function! ExecNDisplay() 
    execute "w" 
    let n=expand('%:t') 
    execute "silent ! python % > d:\\temp\\output_".n . " 2>&1" 
endfunction 

:nmap <F9> :call Setup_ExecNDisplay()<CR> 
:nmap <F2> :call ExecNDisplay()<CR> 

thx

0

Nel vostro .vimrc è possibile incollare questa funzione

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 

Dopo di che, al comando :shell python ~/p.pyvim Esegui come esempio. E otterrai l'output nella finestra divisa. + Dopo le modifiche in p.py come nell'esempio si eseguirà di nuovo lo stesso comando, questa funzione non creerà nuovamente una nuova finestra, visualizzerà il risultato nella precedente (uguale) finestra divisa.

+0

Questo è fantastico, grazie! Come potresti cambiarlo per eseguire nuovamente quando il buffer viene nuovamente scritto? – elzi

Problemi correlati