วิธีแทรกผลลัพธ์ของคำสั่งลงในข้อความในกลุ่ม?


42

ตัวอย่างเช่น:echo strftime(%c)จะแสดงเวลาปัจจุบันที่ด้านล่าง แต่จะแทรกสตริงเวลานี้ลงในข้อความได้อย่างไร (หลังเคอร์เซอร์)


1
ฉันเชื่อว่า OP หมายถึง "วิธีแทรกผลลัพธ์ของนิพจน์ Vim ลงในข้อความได้อย่างไร"
Alastair Irvine

นอกจากนี้ยังควรพูดถึงว่านี่ไม่ใช่คำถามเดียวกับการเขียนฟังก์ชั่น vim เพื่อแทรกบล็อกข้อความคงที่แต่คำตอบบางส่วนยังคงมีอยู่
Alastair Irvine

ตัวอย่างของคุณคือกรณีการใช้งานของฉันและฉันขอแสดงความนับถือ
Joe

ดูการเปลี่ยนเส้นทางไปยังการลงทะเบียน: stackoverflow.com/questions/2573021/…
NeilG

คำตอบ:


49

คุณสามารถใช้ลงทะเบียนแสดงออก"=,มีp(หรือP)ในโหมดปกติหรือ<C-R>ในโหมดแทรก:

ในโหมดปกติ:
( <C-M>ที่นี่หมายถึงControl+ Mหรือเพียงแค่กดEnter/ Return)

"=strftime('%c')<C-M>p

ในโหมดแทรก:
( <C-M>มีความหมายเหมือนข้างต้น<C-R>หมายถึงControl+ R)

<C-R>=strftime('%c')<C-M>

หากคุณต้องการแทรกผลลัพธ์ของนิพจน์เดียวกันหลายครั้งคุณอาจต้องการแมปเหล่านั้นลงในคีย์ของคุณ.vimrc:
(ที่นี่<C-M>และ<C-R>ควรพิมพ์ตามตัวอักษร (ลำดับของอักขระห้าตัวที่พิมพ์ได้ - Vim จะแปลภายใน))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>

2
+1 แน่นอน! การ"=ลงทะเบียน : - /
Eelvex

2
เพื่อรับค่าของตัวแปรเสียงเรียกเข้า (ตัวอย่างเช่น sessionoptions): <C-R>=&sessionoptions- มันทำให้แท็บ wildmode เสร็จสมบูรณ์!
Justin M. Keyes

2
: put = strftime ('% c') <CM>
brunch875

ในโหมดแทรกการใช้<c-r>=ช้าสำหรับคำสั่งซึ่งอาจมีเอาต์พุตจำนวนมากและอาจแตกเยื้องเพื่อให้ข้อความเอาต์พุตไม่สามารถอ่านได้ ตัวอย่างเช่น<c-r>=execute('nmap')เอาต์พุตจะถูกเขียนทีละบรรทัดซึ่งช้ามาก
jdhao

22

:r!date +\%c

ดู :help :r!


1
dateเป็นคำสั่งภายนอกและ!เรียกใช้คำสั่งภายนอกในขณะที่ OP ขอคำสั่ง vim
Eelvex

@eelvex ไม่เขาไม่ได้ และ ! เป็นกลุ่ม, และ vi, คำสั่ง นี่เป็นวิธีมาตรฐาน ทำงานเพื่อสิ่งอื่น ๆ อีกมากมายเช่นกัน
Keith

5
@Keith: ใช่!เป็นคำสั่ง vi (m) ที่เรียกใช้คำสั่งภายนอก คุณอาจถูก OP ไม่ต้องการส่งออกเฉพาะคำสั่ง vim แต่ถ้าเขาทำ!จะไม่ทำ
Eelvex

11

คำสั่งเหล่านี้จะแทรกผลลัพธ์ของstrftime("%c")ตำแหน่งที่เคอร์เซอร์อยู่:

:exe ":normal i" . strftime("%c")

และ

:call feedkeys("i". strftime("%c"))

มีวิธีอื่นในการทำสิ่งที่คุณต้องการ (เช่นตัวอย่างเช่นคำตอบของมิเคล )

แก้ไข : ดียิ่งขึ้นสำหรับการแทรกแบบ in-place ให้ใช้การ=ลงทะเบียนตามที่Chris Johnsen อธิบาย


10

หากคุณต้องการแทรกเอาต์พุตของคำสั่ง vim (ตรงข้ามกับค่าส่งคืนของการเรียกใช้ฟังก์ชัน ) คุณต้องจับมัน สิ่งนี้สามารถทำได้ผ่าน:redirคำสั่งซึ่งช่วยให้คุณสามารถเปลี่ยนเส้นทางของเอาต์พุตมาตรฐานของ vim ให้เป็นตัวแปรไฟล์ลงทะเบียนหรือเป้าหมายอื่น ๆ

:redirเป็นการใช้งานที่ไม่สะดวกอย่างเจ็บปวด ฉันจะเขียนฟังก์ชั่นเพื่อแค็ปซูลฟังก์ชั่นในวิธีที่สะดวกกว่าเช่น

funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    return output
endfunct!

เมื่อคุณประกาศฟังก์ชั่นดังกล่าวแล้วคุณสามารถใช้นิพจน์รีจิสเตอร์ (ดังที่อธิบายโดย Chris Johnsen) เพื่อแทรกเอาต์พุตของคำสั่งที่ตำแหน่งเคอร์เซอร์ ดังนั้นจากโหมดปกติให้กดi^R=Exec('ls')เพื่อแทรกรายการบัฟเฟอร์ปัจจุบันของกลุ่ม

โปรดทราบว่าคำสั่งจะดำเนินการใน namespace ฟังก์ชั่นดังนั้นหากคุณใช้ตัวแปรทั่วโลกคุณจะต้องชัดเจน namespace มันโดย prefixing g:ด้วย นอกจากนี้โปรดทราบว่าExec()ตามที่เขียนไว้ด้านบนจะผนวกบรรทัดใหม่ที่ยกเลิกไปยังเอาต์พุตบรรทัดเดียว คุณอาจต้องการเพิ่มการเรียกไปsubstitute()ยังฟังก์ชันเพื่อหลีกเลี่ยงปัญหานี้

โปรดดูที่https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054/vim-how-to-redirect-example.com/สำหรับข้อมูลเพิ่มเติมเกี่ยวกับredirการเชื่อมโยงและเชื่อมโยงไปยัง คำสั่งที่เกี่ยวข้อง


2
มันใช้งานได้ดี ฉันเพิ่มset pasteคำสั่งก่อนที่จะส่งคืนผลลัพธ์และset nopasteหลังจากนั้นเพื่อหลีกเลี่ยงการเยื้องบันไดเมื่อบรรทัดเริ่มต้นด้วยช่องว่าง ที่จริงแล้วฉันต้องการบันทึกค่าของตัวเลือกการวางปัจจุบันและส่งคืน แต่ฉันไม่สามารถทำได้
Juan Lanus

1
@JuanLanus set nopasteไม่ควรทำงานหลังจากreturn outputนั้นเนื่องจาก return statement เป็นจุดออกจากฟังก์ชัน ฉันได้แก้ไขปัญหานี้เป็นคำตอบแยกต่างหากในหน้านี้
Evgeni Sergeev

4
:call append(line('.'), strftime("%c"))

จะวางไว้ที่บรรทัดถัดไปจากนั้นคุณสามารถกดJ( Shift+ J) เพื่อรวมมันเข้ากับตำแหน่งปัจจุบัน

หรือถ้าคุณต้องการทั้งหมดในคำสั่งเดียวคุณสามารถทำได้

:call setline(line('.'), getline(line('.')) . strftime("%c"))

หรือ

:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))

ขึ้นอยู่กับว่าคุณต้องการแทรกช่องว่างก่อนวันที่หรือไม่


4

การปรับปรุง @intuited คำตอบเพื่อหลีกเลี่ยงปัญหาด้วยช่องว่างนำหน้าและการเยื้องที่เพิ่มขึ้น:

"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    let @o = output
    execute "put o"
    return ''
endfunct!

สิ่งนี้จะแทรกที่ตำแหน่งปัจจุบันในไฟล์เมื่อคุณ:call Exec('command')จากโหมดปกติ ตามที่ระบุไว้ในความคิดเห็นวิธีการดั้งเดิม (โหมดแทรก) Ctrl + R =Exec('command')วิธีการExec(..)กลับสตริงสามารถแก้ไขได้บางส่วนโดยใช้set pasteแต่ไม่ได้มีโอกาสที่จะใส่ที่set nopasteใดก็ได้

let @o = outputไวยากรณ์ชุดลงทะเบียนoกับเนื้อหาของตัวแปรoutputตามที่อธิบายไว้ที่นี่: https://stackoverflow.com/a/22738310/1143274

return ''บรรทัดเพื่อให้ค่าตอบแทนเริ่มต้น0ไม่ได้รับการแทรกการบัฟเฟอร์


2

นี่คือวิธีที่ฉันทำ pมันทำให้มันถูกต้องหลังจากที่เคอร์เซอร์เพราะมันใช้

" save previous yank
let reg_save = @@

" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"

" restore previous yank
let @@ = reg_save
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.