Vi (m) 'de düzenlediğim dosya nasıl çalıştırılır


103

Vi (m) 'de düzenlediğim dosya nasıl çalıştırılır ve bölünmüş pencerede (SciTE gibi) çıktı alınır?

Tabii ki bunu şu şekilde yürütebilirim:

:!scriptname

Ancak, komut dosyası adını yazmaktan ve ekranın hemen altı yerine bölünmüş pencerede çıktı almaktan kaçınmak mümkün müdür?


21
:!%, 'komut dosyası adı' yazmaktan kaçınmanıza izin verir. Aşağıdaki çözümler daha iyi, ancak karar verirseniz bundan bahsetmeyi düşündüm:!% Yeterince iyi.
overthink

11
Başka bir not, mevcut dosyanın mutlak yolunu belirtmek için%: p (sadece% yerine) kullanabilirsiniz. Mevcut dizininiz başka bir yerde ise bu gerekli olabilir.
andy

4
Ruby komut dosyalarını çalıştırmak için:! ruby% hile yapacak
Alexis Perrier

1
@andy:!%: p ayrıca dizinin $ PATH içinde olmamasını da
çözüyor

2
Ve :!"%:p"boşlukla başa çıkmak için.
OJFord

Yanıtlar:


110

Orada makekomut. makeprgSeçenek içindeki komut setini çalıştırır . %Mevcut dosya adı için yer tutucu olarak kullanın . Örneğin, bir python komut dosyasını düzenliyorsanız:

:set makeprg=python\ %

Evet, boşluktan kaçmanız gerekiyor. Bundan sonra şunları çalıştırabilirsiniz:

:make

İsterseniz, autowriteseçeneği ayarlayabilirsiniz ve aşağıdakileri çalıştırmadan önce otomatik olarak kaydedilir makeprg:

:set autowrite

Bu, yürütme kısmını çözer. Bu çıktıyı dosyaya yeniden yönlendirmeyi içermeyen bölünmüş bir pencereye almanın herhangi bir yolunu bilmiyorum.


5
Aslında, çözümünüz çıktıyı bölünmüş bir pencereye götürür. Kendi penceresinde :copençalıştırılarak üretilen "hata listesini" açmak için kullanın :make. Maalesef, çıktının düzgün şekilde biçimlendirilmesi için, errorformatseçeneğin bir miktar sonlandırılması gerekir. Aksi takdirde çıktının gcc'nin koyduğu formatta olduğu varsayılacaktır.
Göze Çarpan Derleyici

2
Hata formatı "bitirme" konusunda kesinlikle eminsin. Gördüğüm bazı perl kodlarına benziyor ...
R. Martinho Fernandes

1
Bu olanak, vim'den proje 'yapmak' için kullanılabilir (vim'e IDE benzeri bir yetenek verir). Brian Carper'ın çözümü ( :let f=expand("%")|vnew|execute '.!ruby "' . f . '"') şifreli görünse de, tam olarak sorunun yazarının sorduğu gibi çalışıyor.
AjayKumarBasuthkar

29

Geçerli arabelleğin dosya adına erişmek için kullanın %. Bir değişkene eklemek için expand()işlevi kullanabilirsiniz . Yeni bir arabellek ile yeni bir pencere açmak için :newveya kullanın :vnew. Çıkışı bir komuttan geçerli arabelleğe yönlendirmek için kullanın :.!. Hepsini bir araya koy:

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

belli ki rubyistediğiniz komutla değiştiriyorsunuz . Kullandığım executeBen tırnak işareti dosya adı çevreleyen böylece o dosya içinde boşluklar varsa çalışacağız yüzden.


3
@baboonWorksFine :command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'Sadece :Rkomutunu yerine getirebilmek için kullan
xorpaul

Yürütme sırasında kullanıcı girişi gerektiren betiklerde bile bunu çalıştırmak mümkün olabilir mi?
ilstam

23

Vim, !kabuk komutunu doğrudan VIM penceresinden çalıştıran ("bang") komutuna sahiptir. Dahası, boru ile bağlantılı komut dizisinin başlatılmasına ve stdout okunmasına izin verir.

Örneğin:

! node %

komut istemi penceresini açmaya ve komutları başlatmaya eşdeğerdir:

cd my_current_directory 
node my_current_file

Ayrıntılar için "Vim ipuçları: Harici komutlarla çalışma" bölümüne bakın .


11

Vimrc'imde bunun için bir kısayolum var:

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>

Bu, geçerli arabelleği yazar, geçerli dosyayı yürütülebilir hale getirir (yalnızca unix), yürütür (yalnızca unix) ve çıktıyı .tmp.xyz'e yeniden yönlendirir, ardından yeni bir sekme oluşturur, dosyayı okur ve ardından siler.

Parçalamak:

: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

2
Çözümünüzü çok beğendim ve bir süre kullandıktan sonra geliştirilebileceğini hissettim. İşte benim görüşüm: :w<CR>:silent !chmod +x %:p<CR>:silent !%:p 2>&1 | tee ~/.vim/output<CR>:split ~/.vim/output<CR>:redraw!<CR>- bu hem stdout hem de stderr'i geçici dosyaya yönlendirir ve bunu yapmadan önce, her şeyi stdout'a yazdırır, yani bir komut dosyasının çalışması uzun sürerse, gerçekten çalıştığını görürsünüz. Ayrıca, dizinden bağımsızdır (dosyaları mutlak yollarına göre açarken hatalar alıyordum). Ancak komut dosyalarını etkileşimli olarak çalıştırmıyor ve bunu yapmanın bir yolunu bulamadım.
Kirill G

1
fyi - @Cyril'in çözümünde boru sembolünden kaçmak zorunda kaldım: | -> \ |
mpettis


3

Vim 8'de yerleşik bir etkileşimli terminal vardır. Geçerli bash komut dosyasını bölünmüş bir bölmede çalıştırmak için:

:terminal bash %

veya kısaca

:ter bash %

% mevcut dosya adına genişler.

Kimden :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.

1

Haritalar aracılığıyla biraz daha müdahaleci bir mekanizma kullanıyorum:

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

Kaydetmek zorunda kalmamak için yapar, sonra git. Sadece git.


1
Otomatik yazma seçeneğini ayarlarsanız, çalıştırabilirsiniz: make ve it ... önce otomatik kaydeder.
R. Martinho Fernandes

1

Vim'in bexec eklentisini kullanabilirsiniz . Bildiğim kadarıyla en son sürüm 0.5.

Sonra:

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

.Vba dosyasını düzenlerken vim içinde şunları yapın:

:so %

Bazı çıktılar görünecek ve size bexec.vim'in ve dokümantasyonun vb. Yazıldığını bildirecektir .

Şimdi, vim'de (#! Yorumlayıcı düzgün çalışan dil betiği ne olursa olsun) açarak test edebilir ve çalıştırabilirsiniz.

:Bexec 

Not: Bölmenin yatay yerine dikey olmasını istedim, bu yüzden şunu yaptım:

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

ve "hor" olan değeri "ver" olarak değiştirildi ..

Bunun eski bir soru olduğunu biliyorum, ama umarım bu oradaki birine yardımcı olabilir. Profesör Palaji'nin Emacs kullandığı ve Emacs'ı sevmediğim Coursera'nın Startup Engineering kursunu alırken de aynı konuya giriyorum ..


Yerel .vimrc dosyanızda tercihlerle ilgili ayarları değiştirmelisiniz. bexec, eklenti kodunu değiştirmeden bunu yapabilen "let bexec_splitdir = 'hor'" ayarını sunar.
Saurabh Hirani

0

@SethKriticos ve @Cyril yanıtlarına dayanarak, şimdi aşağıdakileri kullanıyorum:

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>

Yeni pencereyi kurmak için F9'u ve komut dosyanızı çalıştırmak için F2'yi ve çıktı dosyanıza tee'yi kullanın.

Komut dosyası adını çıktı dosyası adına da ekledim, böylece bunu aynı anda birden çok komut dosyası için kullanabilirsiniz.


0

Gözlerinde farklı .vimrcEğer bu işlevi yapıştırabilirsiniz

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

Bundan sonra örnek olarak vimrun komutunda :shell python ~/p.py. Ve çıktıyı bölünmüş pencerede alacaksınız. + p.pyÖrnek olarak yapılan değişikliklerden sonra aynı komutu tekrar çalıştıracaksınız, bu fonksiyon bir daha yeni pencere oluşturmayacak, sonucu önceki (aynı) bölünmüş pencerede gösterecektir.


Bu harika, teşekkürler! Arabellek yeniden yazıldığında yeniden çalışacak şekilde nasıl değiştirebilirsin?
elzi

0

@kafadergisi

Bu betiği (python / Windows) bir süredir arıyordum. Windows'ta "tee" olmadığı için bunu şu şekilde değiştirdim:

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>

0

Aşağıda gösterildiği gibi iki nokta üst üste ve ünlem işareti kullanın

:! <script_name>


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.