ฉันสามารถทำซ้ำคำสั่ง UI ล่าสุดได้หรือไม่


17

ฉันรู้ว่าฉันสามารถใช้.เพื่อทำซ้ำคำสั่งแก้ไขล่าสุด

มีวิธีการทำซ้ำคำสั่งการจัดการ UI ล่าสุดหรือไม่ ตัวอย่างเช่นฉันสามารถเขียน10<C-W>-เพื่อลดขนาดหน้าต่างสิบแถว มันดีที่จะสามารถกด⟨ บางปุ่ม ⟩เพื่อทำซ้ำคำสั่งนี้ได้อย่างง่ายดายหากฉันต้องการลดขนาดมันอีก


ที่เกี่ยวข้อง: stackoverflow.com/q/6952636/2072269 (ไม่ได้รับคำตอบที่สามารถใช้ได้หลังจากที่คุณทำการปรับขนาดเสร็จแล้ว )
muru

@muru: ดี แต่สำหรับกรณีนี้โดยเฉพาะ ถ้าฉันทำอะไรที่ชอบfzแล้ว10;ล่ะ เกี่ยวกับ:tabm +1อะไร สิ่งเหล่านี้จะต้องเป็นกรณีพิเศษหรือไม่?
wchargin

ฉันคิดว่าคุณเข้าใจฉันผิด ฉันกำลังบอกว่าโพสต์ที่เชื่อมโยงมีคำตอบที่ไร้ประโยชน์ (ก่อนที่คนอื่นจะมาและแนะนำ)
muru

โอ้! โอเคเราอยู่ในหน้าเดียวกัน @muru :)
wchargin

คำตอบ:


12

คำสั่ง dot ใช้.งานได้เพราะ Vim "Keep track" ของคำสั่งที่เปลี่ยนเนื้อหาของบัฟเฟอร์ หากคุณเรียกใช้:echo b:changedtickคุณจะเห็นการเพิ่มขึ้นของการเปลี่ยนแปลงในบัฟเฟอร์ปัจจุบัน

แต่กลุ่มไม่ได้ "ติดตาม" คำสั่งที่ไม่แก้ไข ดังนั้นไม่สิ่งที่คุณขอไม่สามารถทำได้


8

ไม่มีวิธีการทำสิ่งนี้ตามค่าเริ่มต้นใน vim เนื่องจาก vim ไม่ได้ติดตาม wincmd ที่ดำเนินการก่อนหน้านี้ อย่างไรก็ตามมันเป็นไปได้ที่จะทำสิ่งนี้ผ่านการแม็พที่ฉลาด:

function! s:Wincmd(count, key)
    " If count is not zero, use the original count.  If otherwise, don't
    " include a count.
    let if_count = a:count ? a:count : ""
    " This builds a wincmd from the given key, and saves it so
    " it can be repeated.
    let g:last_wincmd = "wincmd " . nr2char(a:key)
    " Execute the built wincmd
    execute if_count . g:last_wincmd
endfunction

function! s:WincmdRepeat(count)
    " If no wincmd has been executed yet, don't do anything
    if !exists('g:last_wincmd') | return | endif
    " If a count is given, repeat the last wincmd that amount of times.
    " If otherwise, just repeat once.
    let if_count = a:count ? a:count : ""
    execute if_count . g:last_wincmd
endfunction

" Overwrite the default <C-w> mapping so that the last wincmd can be kept
" track of.  The getchar function is what captures the key pressed
" directly afterwards.  The <C-u> is to remove any cmdline range that vim
" automatically inserted.
nnoremap <silent> <C-w> :<C-u>call <SID>Wincmd(v:count, getchar())<CR>

" This just calls the function which repeats the previous wincmd.  It
" does accept a count, which is the number of times it should repeat the
" previous wincmd.  You can also replace Q with whatever key you want. 
nnoremap <silent> Q :<C-u> call <SID>WincmdRepeat(v:count)<CR>

โปรดทราบว่าหากคุณมีการแมปใด ๆ ที่ใช้<C-w>จะสามารถทำซ้ำได้หากไม่มีnoreความหลากหลาย wincmds ใด ๆ ที่ออกโดยใช้:wincmdจะไม่ถูกทำซ้ำ นอกจากนี้ wincmds ใด ๆ ที่มีมากกว่าหนึ่งตัวไม่สามารถดำเนินการ(เช่น<C-w>gf )

หัวข้อความช่วยเหลือที่เกี่ยวข้อง

  • :help v:count
  • :help getchar()
  • :help nr2char()
  • :help expr1
  • :help :wincmd
  • :help :execute
  • :help :for
  • :help :map-<silent>
  • :help c_CTRL-U
  • :help <SID>

1
นี่เป็นสิ่งที่ยอดเยี่ยมและเป็นตัวอย่างที่ยอดเยี่ยมของ VimScript ที่เป็นลายลักษณ์อักษร! ความคิดเห็นเล็กน้อย (อาจจะพิถีพิถัน) บางคำสั่ง: คำสั่งซ้ำนี้จะทำงานแตกต่างจาก.พฤติกรรมที่มีในตัวกับการนับ เมื่อมีการนับจำนวนการนับ.ก่อนหน้านี้จะถูกละเว้น ดังนั้น2ddตามด้วย3.จะลบ 2 บรรทัดและ 3 บรรทัด; ในทางตรงกันข้ามกับการแมปของคุณแล้ว2<C-w>-ตามด้วย3Qจะหดหน้าต่าง 2 บรรทัดและ 6 บรรทัด = (= 2x3) พฤติกรรมนั้นเป็นสิ่งที่ดี แต่การดึงคำสั่ง Vim แบบบิวด์อินแบบอะนาล็อกมาใช้เมื่อเลือกว่าคำสั่งแบบกำหนดเองควรทำงานอย่างไร
tommcdo

ขอบคุณ! นอกจากนี้ฉันเห็นสิ่งที่คุณหมายถึงวิธีการนับงาน ฉันอาจเปลี่ยนมันเพื่อให้มันทำงานอย่างนั้น
EvergreenTree

4

submodeปลั๊กอินสามารถช่วยให้มีนี้ คุณสามารถกำหนด "submode" ที่คุณป้อนโดยพิมพ์<C-W>-ซึ่งคุณได้กำหนดไว้-(และอาจ+) เพื่อปรับขนาดหน้าต่างต่อไป


2

มีอีกปลั๊กอินหนึ่งที่เรียกว่าrepmo.vim ("ทำซ้ำการเคลื่อนไหว") ซึ่งสามารถทำสิ่งที่คุณต้องการ

แต่คุณจะต้องระบุการเคลื่อนไหว (หรือการกระทำโดยทั่วไป) ที่คุณต้องการทำซ้ำ ปัจจุบันฉันได้รับการกำหนดค่าเช่นนี้:

let g:repmo_mapmotions = "j|k h|l zh|zl g;|g, <C-w>w|<C-w>W"
let g:repmo_mapmotions .= " <C-w>+|<C-w>- <C-w>>|<C-w><"
let g:repmo_key = ";" 
let g:repmo_revkey = "," 

ดังนั้นหลังจากทำ5 CTRL-W +ฉันสามารถกด;ซ้ำได้หลายครั้งเหมือนกัน

ปลั๊กอินทำงานโดยการสร้างการแมปสำหรับแต่ละคีย์ที่ระบุ

เมื่อfหรือtมีการใช้;และ,การแมปจะถูกล้างออกกลับไปทำงานเริ่มต้นของพวกเขา

ฉันพบว่าการทำแผนที่g;มีประโยชน์อย่างยิ่งเพื่อกลับไปยังจุดแก้ไขก่อนหน้า g; ; ; ;


@albfan ฉันไม่แน่ใจว่าฉันเข้าใจคำถามของคุณ แต่สำหรับฉันกดการ,กระทำทันทีและ5,ยังทำงานตามที่คาดไว้ มันเป็นไปได้ที่คุณได้ตั้งค่าของคุณmapleaderไป,?
joeytwiddle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.