จะใช้ read แทน execute ใน function ได้อย่างไร?

Sep 07 2020

ฉันพยายามค้นหาบรรทัดที่เลือกของไฟล์โดยใช้สิ่งต่อไปนี้:

function! GrepSelection()
    normal! gvy
    let result = escape(@", '\\/.*$^~[]#') let result = substitute(result, "\n$", "", "")
    let result = substitute(result, "\n", '\\n', "g")
    new | setlocal buftype=nofile bufhidden=hide noswapfile
    execute 'grep "'.result.'" file'
endfunction
xnoremap <silent> <unique> * :<C-U>call GrepSelection()<CR>

แต่ดูเหมือนว่ามันจะล้มเหลวเมื่อฉันเปลี่ยนชิ้นexecuteส่วนด้วยread !(มันก็ล้มเหลวด้วยread!) มันใช้งานได้เมื่อฉันทำสิ่งนี้ด้วยตนเองบนบรรทัดคำสั่ง

วิธีที่ล้มเหลวคือ:

/bin/bash: grep ".result." file: No such file or directory

ซึ่งเห็นได้ชัดว่าพบไฟล์ แต่ปัญหาที่เกิดขึ้นคือ ".result" ถูกนำมาใช้ตามตัวอักษรแทนที่จะถูกแทนที่ด้วยสตริงที่เลือก (เช่นเมื่อexecuteถูกใช้แทน)

มีอะไรผิดปกติกับสิ่งที่ฉันทำที่นี่?

คำตอบ

2 filbranden Sep 07 2020 at 11:17

คุณยังคงต้องใช้executeเพื่อที่จะสอดแทรกเนื้อหาของresultตัวแปร Vimscript ลงในคำสั่งเชลล์:

execute 'read !grep "'.result.'" file'

โปรดทราบว่าตอนนี้นี่เป็นคำสั่งเชลล์และไม่ใช่แค่คำสั่ง Vim อีกต่อไปดังนั้นให้พิจารณาใช้shellescape()เพื่อหลีกเลี่ยงสตริงอย่างถูกต้องเพื่อใช้ในคำสั่งเชลล์ (แต่โปรดทราบว่าคุณอาจต้องปรับเปลี่ยนสคริปต์ที่เหลือเพื่อให้ทำงานได้อย่างถูกต้อง)