Vi (m)에서 편집중인 파일을 실행하는 방법


101

Vi (m)에서 편집중인 파일을 실행하고 SciTE와 같이 분할 창에서 출력을 얻는 방법은 무엇입니까?

물론 다음과 같이 실행할 수 있습니다.

:!scriptname

그러나 스크립트 이름을 작성하지 않고 화면 하단 대신 분할 창에서 출력을 얻는 방법을 피할 수 있습니까?


21
:! %를 사용하면 'scriptname'작성을 피할 수 있습니다. 아래 솔루션이 더 낫지 만 결정한 경우에 대해 언급 할 것이라고 생각했습니다. :! %가 충분합니다.
overthink

11
또 다른 참고로, % : p (단지 % 대신)를 사용하여 현재 파일의 절대 경로를 참조 할 수 있습니다. 현재 디렉토리가 다른 곳에있는 경우 필요할 수 있습니다.
andy

4
루비 스크립트를 실행하려면 :! ruby ​​%가 트릭을 수행합니다
Alexis Perrier 2011

1
!의 @andy : % : p는 또한 $ PATH에있는 디렉토리 가지고 있지 해결합니다
MayTheSForceBeWithYou

2
그리고 :!"%:p"공백에 대처합니다.
OJFord

답변:


109

make명령은. makeprg옵션에 설정된 명령을 실행합니다 . %현재 파일 이름에 대한 자리 표시 자로 사용 합니다. 예를 들어, Python 스크립트를 편집하는 경우 :

:set makeprg=python\ %

네, 공간을 탈출해야합니다. 그 후에 간단히 실행할 수 있습니다.

:make

원하는 경우 autowrite옵션을 설정할 수 있으며 다음 을 실행하기 전에 자동으로 저장됩니다 makeprg.

:set autowrite

이것은 실행 부분을 해결합니다. 파일로의 리디렉션을 포함하지 않는 분할 창으로 출력을 가져 오는 방법을 모릅니다.


5
실제로 솔루션은 분할 창으로 출력을 얻습니다. 자체 창에서.를 :copen실행 :make하여 생성 된 "오류 목록"을 열 때 사용 합니다 . 안타깝게도 출력의 형식을 올바르게 지정하려면 errorformat옵션을 일부 마무리 해야합니다. 그렇지 않으면 출력은 gcc가 출력 한 형식으로 간주됩니다.
눈에 띄는 컴파일러

2
"finagling"errorformat에 대해 확신합니다. 그것은 내가 본 몇 가지 펄 코드 ...처럼
R. 마르틴 페르난데스

1
이 기능은 vim에서 프로젝트의 'make'에 사용할 수 있습니다 (vim에 IDE와 유사한 기능 제공). Brian Carper의 솔루션 ( :let f=expand("%")|vnew|execute '.!ruby "' . f . '"')은 은밀 해 보이지만 질문 작성자가 요청한대로 정확하게 작동합니다.
AjayKumarBasuthkar

29

현재 버퍼의 파일 이름에 액세스하려면 %. 변수로 가져 오려면 expand()함수를 사용할 수 있습니다 . 새 버퍼로 새 창을 열려면 :new또는을 사용하십시오 :vnew. 명령의 출력을 현재 버퍼로 파이프하려면을 사용하십시오 :.!. 함께 모아서:

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

분명히 ruby원하는 명령으로 대체하십시오 . execute파일 이름을 따옴표로 묶을 수 있도록 사용 했으므로 파일 이름에 공백이 있으면 작동합니다.


3
@baboonWorksFine 그의 명령을 실행 :command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'하는 :R데 사용할 수 있도록 사용
xorpaul 2014 년

실행하는 동안 사용자 입력이 필요한 스크립트로도 실행할 수 있습니까?
ilstam

23

Vim에는 !VIM 창에서 직접 쉘 명령을 실행하는 ( "bang") 명령이 있습니다. 또한 파이프와 연결된 명령 시퀀스를 시작하고 stdout을 읽을 수 있습니다.

예를 들면 :

! node %

명령 프롬프트 창을 열고 명령을 실행하는 것과 같습니다.

cd my_current_directory 
node my_current_file

자세한 내용은 "Vim 팁 : 외부 명령 작업" 을 참조하십시오.


11

내 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>

이렇게하면 현재 버퍼를 쓰고 현재 파일을 실행 가능하게 만들고 (unix 만 해당) 실행 (unix 만 해당)하고 출력을 .tmp.xyz로 리디렉션 한 다음 새 탭을 만들고 파일을 읽은 다음 삭제합니다.

분석 :

: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
나는 당신의 솔루션을 많이 좋아했고 그것을 사용하고 나서 개선 될 수 있다고 느꼈습니다. 그래서 여기에 내 의견이 있습니다. :w<CR>:silent !chmod +x %:p<CR>:silent !%:p 2>&1 | tee ~/.vim/output<CR>:split ~/.vim/output<CR>:redraw!<CR>— 이것은 stdout과 stderr를 임시 파일로 리디렉션하고 그렇게하기 전에 모든 것을 stdout으로 인쇄하므로 스크립트가 실행되는 데 시간이 오래 걸리면 실제로 작동하는 것을 볼 수 있습니다. 또한 디렉토리 독립적입니다 (절대 경로로 파일을 열 때 오류가 발생했습니다). 그러나 대화식으로 스크립트를 실행하지 않으며 그렇게 할 수있는 방법을 찾지 못했습니다.
Kirill G

1
fyi-@Cyril의 솔루션에서 파이프 기호를 이스케이프해야했습니다. | -> \ |
mpettis


3

Vim 8에는 대화 형 터미널이 내장되어 있습니다. 분할 창에서 현재 bash 스크립트를 실행하려면 :

:terminal bash %

또는 짧게

:ter bash %

% 현재 파일 이름으로 확장됩니다.

에서 :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

맵을 통해 약간 더 침입적인 메커니즘을 사용합니다.

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

저장하지 않아도되게 만든 다음 가십시오. 바로 가기.


1
autowrite 옵션을 설정하면 : make를 실행할 수 있으며 이전에 자동 저장됩니다.
R. Martinho Fernandes

1

vim의 플러그인 bexec을 사용할 수 있습니다 . 내가 아는 한 최신 버전은 0.5입니다.

그때:

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

.vba 파일을 편집하는 동안 vim 자체에서 다음을 수행합니다.

:so %

bexec.vim 이 문서와 같이 작성 되었음을 알리는 일부 출력이 표시됩니다 .

이제 vim에서 (올바르게 작동하는 #! 인터프리터가있는 모든 언어 스크립트)를 열고 실행하여 테스트 할 수 있습니다.

:Bexec 

참고 : 분할이 수평이 아닌 수직이되기를 원했기 때문에 다음과 같이했습니다.

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

의 값을 "hor"에서 "ver"로 변경했습니다 ..

나는 그것이 오래된 질문이라는 것을 알고 있지만 이것이 누군가를 도울 수 있기를 바랍니다. Palaji 교수가 Emacs를 사용하고 Emacs를 좋아하지 않는 Coursera의 Startup Engineering 과정을 수강하면서 같은 문제를 겪고 있습니다.


로컬 .vimrc에서 환경 설정 관련 설정을 변경해야합니다. bexec은 플러그인 코드를 수정하지 않고 그렇게 할 수있는 "let bexec_splitdir = 'hor'"설정을 제공합니다.
Saurabh Hirani 2014 년

0

@SethKriticos 및 @Cyril 답변을 기반으로 이제 다음을 사용합니다.

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>

F9를 사용하여 새 창을 설정하고 F2를 사용하여 스크립트를 실행하고 출력 파일을 입력합니다.

또한 출력 파일 이름에 스크립트 이름을 추가하여 동시에 여러 스크립트에 사용할 수 있습니다.


0

당신의에서 .vimrc이 기능을 붙여 넣을 수 있습니다

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

그 후 vim실행 명령 :shell python ~/p.py에서 예제로. 그리고 분할 된 창에 출력이 표시됩니다. + p.py예제를 변경 한 후에 는 동일한 명령을 다시 실행합니다.이 함수는 새 창을 다시 생성하지 않으며 이전 (동일한) 분할 된 창에 결과를 표시합니다.


굉장합니다, 감사합니다! 버퍼가 다시 쓰여질 때 다시 실행되도록 어떻게 변경할 수 있습니까?
elzi

0

뿡뿡

나는 꽤 오랫동안이 스크립트 (python / Windows)를 찾고 있었다. Windows에는 "티"가 없으므로 다음과 같이 변경했습니다.

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

아래와 같이 콜론과 느낌표 만 사용하세요.

:! <스크립트 _ 이름>


0

플러그인 quickrun을 권장합니다 . 빠르고 간단하게 구성 할 수 있습니다. 다음은 약간의 데모입니다. 여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.