วิธีเรียกใช้ไฟล์ที่ฉันแก้ไขใน Vi (m) และรับเอาต์พุตในหน้าต่างแยก (เช่นใน SciTE)
แน่นอนฉันสามารถดำเนินการได้เช่นนั้น:
:!scriptname
แต่เป็นไปได้หรือไม่ที่จะหลีกเลี่ยงการเขียนชื่อสคริปต์และวิธีรับเอาต์พุตในหน้าต่างแยกแทนที่จะอยู่ด้านล่างของหน้าจอ
วิธีเรียกใช้ไฟล์ที่ฉันแก้ไขใน Vi (m) และรับเอาต์พุตในหน้าต่างแยก (เช่นใน SciTE)
แน่นอนฉันสามารถดำเนินการได้เช่นนั้น:
:!scriptname
แต่เป็นไปได้หรือไม่ที่จะหลีกเลี่ยงการเขียนชื่อสคริปต์และวิธีรับเอาต์พุตในหน้าต่างแยกแทนที่จะอยู่ด้านล่างของหน้าจอ
:!"%:p"
เพื่อรับมือกับช่องว่าง
คำตอบ:
มีmake
คำสั่ง มันเรียกใช้ชุดคำสั่งในmakeprg
ตัวเลือก ใช้%
เป็นตัวยึดสำหรับชื่อไฟล์ปัจจุบัน ตัวอย่างเช่นหากคุณกำลังแก้ไขสคริปต์ python:
:set makeprg=python\ %
ใช่คุณต้องหนีออกจากพื้นที่ หลังจากนี้คุณสามารถเรียกใช้:
:make
หากคุณต้องการคุณสามารถตั้งค่าautowrite
ตัวเลือกและจะบันทึกโดยอัตโนมัติก่อนที่จะเรียกใช้makeprg
:
:set autowrite
สิ่งนี้จะแก้ส่วนที่ดำเนินการ ไม่ทราบวิธีใดในการรับผลลัพธ์นั้นไปยังหน้าต่างแยกที่ไม่เกี่ยวข้องกับการเปลี่ยนเส้นทางไปยังไฟล์
:copen
เพื่อเปิด "รายการข้อผิดพลาด" ที่เกิดจากการเรียกใช้:make
. ในหน้าต่างของตัวเอง น่าเสียดายที่เพื่อให้ได้ผลลัพธ์ที่ได้รับการจัดรูปแบบอย่างถูกต้องerrorformat
จำเป็นต้องมีตัวเลือกขั้นสุดท้ายบางอย่าง มิฉะนั้นผลลัพธ์จะถูกสันนิษฐานว่าเป็นรูปแบบที่ gcc กำหนดไว้
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
) แม้ว่าจะดูคลุมเครือ แต่ก็ใช้งานได้ตรงตามที่ผู้เขียนคำถามถาม
ในการเข้าถึงชื่อไฟล์ของบัฟเฟอร์ปัจจุบันให้ใช้%
. เพื่อให้เป็นตัวแปรคุณสามารถใช้expand()
ฟังก์ชัน เพื่อเปิดหน้าต่างใหม่ด้วยกันชนใหม่ใช้หรือ:new
ท่อผลลัพธ์จากคำสั่งลงในบัฟเฟอร์ปัจจุบันการใช้งาน:vnew
:.!
วางมันทั้งหมดเข้าด้วยกัน:
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
เห็นได้ชัดว่าแทนที่ruby
ด้วยคำสั่งที่คุณต้องการ ฉันใช้execute
เพื่อให้ฉันสามารถล้อมรอบชื่อไฟล์ด้วยเครื่องหมายคำพูดดังนั้นมันจะใช้ได้ถ้าชื่อไฟล์มีช่องว่างอยู่
:command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
เพื่อให้สามารถใช้:R
คำสั่งได้
Vim มี!
คำสั่ง ("bang") ซึ่งรันคำสั่งเชลล์โดยตรงจากหน้าต่าง VIM นอกจากนี้ยังอนุญาตให้เรียกใช้ลำดับของคำสั่งที่เชื่อมต่อกับ pipe และอ่าน stdout
ตัวอย่างเช่น:
! node %
เทียบเท่ากับการเปิดหน้าต่างพรอมต์คำสั่งและเรียกใช้คำสั่ง:
cd my_current_directory
node my_current_file
ดูเคล็ดลับ "ที่เป็นกลุ่ม: การทำงานกับคำสั่งภายนอก"สำหรับรายละเอียด
ฉันมีทางลัดสำหรับสิ่งนั้นใน 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
:w<CR>:silent !chmod +x %:p<CR>:silent !%:p 2>&1 | tee ~/.vim/output<CR>:split ~/.vim/output<CR>:redraw!<CR>
- สิ่งนี้เปลี่ยนเส้นทางทั้ง stdout และ stderr ไปยังไฟล์ temp และก่อนที่จะทำเช่นนั้นมันจะพิมพ์ทุกอย่างเป็น stdout ดังนั้นหากสคริปต์ใช้เวลานานในการรันคุณจะเห็นว่ามันใช้งานได้จริง นอกจากนี้ยังไม่ขึ้นกับไดเรกทอรี (ฉันได้รับข้อผิดพลาดเมื่อเปิดไฟล์โดยใช้พา ธ สัมบูรณ์) อย่างไรก็ตามมันไม่ได้เรียกใช้สคริปต์แบบโต้ตอบและฉันไม่พบวิธีที่จะทำให้เป็นเช่นนั้น
สำหรับเชลล์สคริปต์ที่ฉันใช้
:set makeprg=%
:make
Vim 8 มีเทอร์มินัลแบบโต้ตอบในตัวในการรันสคริปต์ทุบตีปัจจุบันในบานหน้าต่างแยก:
: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.
ฉันใช้กลไกที่ล่วงล้ำมากขึ้นเล็กน้อยผ่านแผนที่:
map ;e :w<CR>:exe ":!python " . getreg("%") . "" <CR>
แค่ทำให้ฉันไม่ต้องบันทึกแล้วไป เพียงแค่ไป.
คุณสามารถใช้เสียงเรียกเข้าเป็นปลั๊กอินbexec ตามความรู้ของฉันเวอร์ชันล่าสุดคือ 0.5
จากนั้น:
$ mkdir -p ~/.vim/plugin
$ mv bexec-0.5.vba ~/.vim/plugin
$ vim ~/.vim/plugin/bexec-0.5.vba
ภายในกลุ่มตัวเองในขณะที่แก้ไขไฟล์. vba ทำ:
:so %
ผลลัพธ์บางอย่างจะแสดงขึ้นเพื่อแจ้งให้คุณทราบว่าbexec.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" ..
ฉันรู้ว่ามันเป็นคำถามเก่า แต่ฉันหวังว่านี่จะช่วยใครสักคนได้ ฉันประสบปัญหาเดียวกันในขณะที่เรียนหลักสูตรวิศวกรรมเริ่มต้นของ Coursera ซึ่งศาสตราจารย์ Palaji ใช้ Emacs และฉันไม่ชอบ Emacs ..
จากคำตอบของ @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 เพื่อรันสคริปต์ของคุณและทีไปยังไฟล์เอาต์พุตของคุณ
ฉันยังเพิ่มชื่อสคริปต์ให้กับชื่อไฟล์เอาต์พุตเพื่อให้คุณสามารถใช้สิ่งนี้สำหรับหลายสคริปต์ในเวลาเดียวกัน
ในของ.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
คำสั่ง run :shell python ~/p.py
ตามตัวอย่าง และคุณจะได้รับผลลัพธ์ในหน้าต่างแยก + หลังจากการเปลี่ยนแปลงในp.py
ตัวอย่างคุณจะเรียกใช้คำสั่งเดิมอีกครั้งฟังก์ชันนี้จะไม่สร้างหน้าต่างใหม่อีกครั้งจะแสดงผลลัพธ์ในหน้าต่างแยกก่อนหน้า (เดียวกัน)
@xorpaul
ฉันกำลังมองหาสคริปต์นี้ (python / Windows) มาระยะหนึ่งแล้ว เนื่องจากไม่มี "tee" ใน 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>
เพียงใช้โคลอนและเครื่องหมายอัศเจรีย์ตามที่แสดงด้านล่าง
:! <script_name>