So führen Sie eine Datei aus, die ich in Vi (m) bearbeite

100

Wie führe ich eine Datei aus, die ich in Vi (m) bearbeite, und erhalte die Ausgabe im geteilten Fenster (wie in SciTE)?

Natürlich könnte ich es so ausführen:

:!scriptname

Aber ist es möglich, das Schreiben von Skriptnamen zu vermeiden und zu vermeiden, dass die Ausgabe im geteilten Fenster statt nur am unteren Bildschirmrand erfolgt?

Alex Bolotov
quelle
21
:!% verhindert, dass Sie 'scriptname' schreiben. Die folgenden Lösungen sind besser, aber ich dachte, ich würde dies erwähnen, falls Sie sich entscheiden :!% Ist gut genug.
überdenken
11
Ein weiterer Hinweis: Sie können%: p (anstelle von nur%) verwenden, um auf den absoluten Pfad der aktuellen Datei zu verweisen. Dies kann erforderlich sein, wenn sich Ihr aktuelles Verzeichnis an einem anderen Ort befindet.
Andy
4
Ruby-Skripte ausführen :! Ruby% wird den Trick machen
Alexis Perrier
1
@andy :!%: p behebt auch, dass sich das Verzeichnis nicht im $ PATH befindet
MayTheSForceBeWithYou
2
Und :!"%:p"mit Leerzeichen fertig zu werden.
OJFord

Antworten:

109

Da ist der makeBefehl. Es führt den Befehlssatz in der makeprgOption aus. Verwenden Sie %als Platzhalter für die aktuellen Dateinamen. Wenn Sie beispielsweise ein Python-Skript bearbeitet haben:

:set makeprg=python\ %

Ja, du musst dem Raum entkommen. Danach können Sie einfach ausführen:

:make

Wenn Sie möchten, können Sie die autowriteOption festlegen und sie wird automatisch gespeichert, bevor Folgendes ausgeführt wird makeprg:

:set autowrite

Dies löst den Ausführungsteil. Ich kenne keine Möglichkeit, diese Ausgabe in ein geteiltes Fenster zu bringen, das keine Umleitung in eine Datei beinhaltet.

R. Martinho Fernandes
quelle
5
Tatsächlich erhält Ihre Lösung die Ausgabe in ein geteiltes Fenster. Verwenden Sie :copendiese Option, um die "Fehlerliste" zu öffnen, die durch Ausführen von :make.in einem eigenen Fenster erstellt wurde. Um die Ausgabe richtig formatieren zu können, ist leider eine gewisse Feinabstimmung der errorformatOption erforderlich. Andernfalls wird angenommen, dass die Ausgabe das von gcc ausgegebene Format hat.
Auffälliger Compiler
2
Sie sind sich verdammt sicher, dass das Fehlerformat "finagling" ist. Es sieht aus wie ein Perl-Code, den ich gesehen habe ...
R. Martinho Fernandes
1
Diese Funktion steht für das Erstellen von Projekten von vim zur Verfügung (gibt vim die IDE-ähnliche Funktion). Brian Carpers Lösung ( :let f=expand("%")|vnew|execute '.!ruby "' . f . '"') sieht zwar kryptisch aus, funktioniert aber genau so, wie es der Autor der Frage gestellt hat.
AjayKumarBasuthkar
29

Verwenden Sie, um auf den Dateinamen des aktuellen Puffers zuzugreifen %. Um es in eine Variable zu bekommen, können Sie die expand()Funktion verwenden. Verwenden Sie :newoder, um ein neues Fenster mit einem neuen Puffer zu öffnen :vnew. Verwenden Sie, um die Ausgabe eines Befehls in den aktuellen Puffer zu leiten :.!. Alles zusammen:

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

offensichtlich durch einen rubybeliebigen Befehl ersetzen . Ich habe verwendet, executedamit ich den Dateinamen mit Anführungszeichen umgeben kann. Es funktioniert also, wenn der Dateiname Leerzeichen enthält.

Brian Carper
quelle
3
@baboonWorksFine Verwenden Sie :command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'diese Option , um nur :Rseinen Befehl ausführen zu können
xorpaul
Wäre es möglich, dies auch mit Skripten auszuführen, die während der Ausführung Benutzereingaben erfordern?
Whileam
23

Vim hat den !Befehl ("bang"), der den Shell-Befehl direkt aus dem VIM-Fenster ausführt. Darüber hinaus können Sie eine Folge von Befehlen starten, die mit Pipe verbunden sind, und stdout lesen.

Beispielsweise:

! node %

entspricht dem Öffnen des Eingabeaufforderungsfensters und dem Starten von Befehlen:

cd my_current_directory 
node my_current_file

Weitere Informationen finden Sie unter "Vim-Tipps: Arbeiten mit externen Befehlen" .

Gediminas Bukauskas
quelle
11

Ich habe eine Verknüpfung dafür in meinem 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>

Dies schreibt den aktuellen Puffer, macht die aktuelle Datei ausführbar (nur Unix), führt sie aus (nur Unix) und leitet die Ausgabe an .tmp.xyz um, erstellt dann eine neue Registerkarte, liest die Datei und löscht sie dann.

Brechen sie ab:

: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
Sebastian Bartos
quelle
2
Ihre Lösung hat mir sehr gut gefallen, und nach einer Weile hatte ich das Gefühl, dass sie verbessert werden könnte. Hier ist meine :w<CR>:silent !chmod +x %:p<CR>:silent !%:p 2>&1 | tee ~/.vim/output<CR>:split ~/.vim/output<CR>:redraw!<CR>Meinung dazu: - Dadurch werden sowohl stdout als auch stderr in die temporäre Datei umgeleitet. Zuvor wird alles in stdout gedruckt. Wenn die Ausführung eines Skripts also lange dauert, funktioniert es tatsächlich. Außerdem ist es verzeichnisunabhängig (beim Öffnen von Dateien über ihren absoluten Pfad wurden Fehler angezeigt). Es werden jedoch keine Skripte interaktiv ausgeführt, und ich habe keinen Weg gefunden, dies zu erreichen.
Kirill G
1
fyi - bei @Cyrils Lösung musste ich dem Pipe-Symbol entkommen: | -> \ |
mpettis
4

Für Shell-Skript habe ich verwendet

:set makeprg=%

:make
Timur Fanshteyn
quelle
3

In Vim 8 ist ein interaktives Terminal integriert. So führen Sie das aktuelle Bash-Skript in einem geteilten Bereich aus:

:terminal bash %

oder kurz gesagt

:ter bash %

% wird auf den aktuellen Dateinamen erweitert.

Von :help terminal:

The terminal feature is optional, use this to check if your Vim has it:
    echo has('terminal')
If the result is "1" you have it.
apostl3pol
quelle
1

Ich benutze einen etwas aufdringlicheren Mechanismus durch Karten:

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

Macht es einfach so, dass ich nicht sparen muss, dann geh. Geh einfach.

Jack M.
quelle
1
Wenn Sie die Option zum automatischen Schreiben festlegen, können Sie Folgendes ausführen: make and it ... wird zuvor automatisch gespeichert.
R. Martinho Fernandes
1

Sie können das Plugin bexec von vim verwenden . Meines Wissens ist die neueste Version 0.5.

Dann:

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

In vim selbst beim Bearbeiten der .vba-Datei gehen Sie wie folgt vor:

:so %

Einige Ausgaben zeigen an, dass bexec.vim geschrieben wurde, sowie Dokumentation usw.

Jetzt können Sie es testen, indem Sie Ihr (unabhängig von der Sprache funktionierendes Skript, in dem ein #! - Interpreter ordnungsgemäß funktioniert) in vim öffnen und ausführen

:Bexec 

Hinweis: Ich wollte, dass die Aufteilung eher vertikal als horizontal ist, also habe ich Folgendes getan:

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

und änderte den Wert von "hor" in "ver" ..

Ich weiß, dass es eine alte Frage ist, aber ich hoffe, dass dies jemandem da draußen helfen kann. Ich habe in der gleichen Ausgabe gearbeitet, als ich an Courseras Startup Engineering-Kurs teilgenommen habe, in dem Professor Palaji Emacs verwendet und ich Emacs nicht mag.

Angie
quelle
Sie sollten die Einstellungen für Einstellungen in Ihrer lokalen .vimrc ändern. bexec bietet die Einstellung "let bexec_splitdir = 'hor'" an, die dies ohne Änderung des Plugin-Codes tun kann.
Saurabh Hirani
0

Basierend auf den Antworten von @SethKriticos und @Cyril verwende ich jetzt Folgendes:

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>

Verwenden Sie F9, um das neue Fenster einzurichten, und F2, um Ihr Skript auszuführen und zu Ihrer Ausgabedatei zu wechseln.

Ich habe auch den Skriptnamen zum Namen der Ausgabedatei hinzugefügt, damit Sie diesen für mehrere Skripte gleichzeitig verwenden können.

xorpaul
quelle
0

In Ihre können .vimrcSie diese Funktion einfügen

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

Danach im vimBefehl run :shell python ~/p.pyals Beispiel. Und Sie erhalten die Ausgabe in einem geteilten Fenster. + Nach Änderungen im p.pyBeispiel führen Sie denselben Befehl erneut aus. Diese Funktion erstellt kein neues Fenster, sondern zeigt das Ergebnis im vorherigen (gleichen) geteilten Fenster an.

Igor Komar
quelle
Das ist großartig, danke! Wie können Sie es ändern, um es erneut auszuführen, wenn der Puffer erneut geschrieben wird?
Elzi
0

@xorpaul

Ich habe lange nach diesem Skript (Python / Windows) gesucht. Da es in Windows kein "Tee" gibt, habe ich es geändert 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>
Jetrock
quelle
0

Verwenden Sie einfach Doppelpunkt und Ausrufezeichen wie unten gezeigt

:! <Skriptname>

Sarath
quelle