การใช้นามแฝงในคำสั่งเป็นกลุ่ม


151

Vim เป็นตัวแก้ไขข้อความที่ฉันต้องการเมื่อฉันเขียนโปรแกรมและทำให้ฉันพบเจอปัญหาที่น่ารำคาญเป็นพิเศษ

บ่อยครั้งเมื่อฉันต้องการบันทึกบัฟเฟอร์อย่างรวดเร็วและทำงานอื่น ๆ ต่อไปฉันจะทำตามปกติ

:w

อย่างไรก็ตามฉัน - สิ่งที่ดูเหมือนจะเป็นมากกว่า 50% ของเวลา - จัดการเพื่อใช้ประโยชน์จากสิ่งนั้น:wเสมอ ตามธรรมชาติแล้วเสียงตะโกนใส่ฉันเพราะWมันเป็นคำสั่งที่ไม่ถูกต้อง

E492: Not an editor command: W

คำถามของฉันคือคำสั่งโคลอนหนึ่งคำสั่งในกลุ่มได้อย่างไร โดยเฉพาะอย่างยิ่งคุณสามารถเป็นตัวอย่างวิธีการนามแฝงไปWw

ฉันรู้กระบวนการในการmap ปุ่มบางคำสั่ง น่าเสียดายที่นั่นไม่ใช่สิ่งที่ฉันกำลังมองหา



1
เพื่อหลีกเลี่ยงการที่:Wคุณสามารถทำแผนที่คีย์เพื่อทำการบันทึก หากคุณคุ้นเคยกับบางโปรแกรมที่บันทึกด้วย Ctrl-s จะมีการจับคู่จาก $ VIM / mswin.vim:" Use CTRL-S for saving, also in Insert mode noremap <C-S> :update<CR> vnoremap <C-S> <C-C>:update<CR> inoremap <C-S> <C-O>:update<CR>
mMontu

คำถามที่คล้ายกันเกี่ยวกับการแลกเปลี่ยน Vi Stack: vi.stackexchange.com/q/2665/7244
Flimm

คำตอบ:


127

หากต้องการคงความสมบูรณ์ไว้โดยไม่ถูกแตะต้องให้ลองใช้

cnoreabbrev W w

มันจะแทนที่Wในบรรทัดคำสั่งด้วยwแต่ถ้ามันไม่ได้ตามหรือนำหน้าด้วยตัวอักษรคำดังนั้น:W<CR>จะถูกแทนที่ด้วย:w<CR>แต่:Writeจะไม่ (โปรดทราบว่าสิ่งนี้มีผลกับคำสั่งใด ๆ ที่ตรงกับที่รวมถึงคำที่คุณอาจไม่คาดคิดเช่นคำสั่ง:saveas W Zจะถูกแทนที่ด้วย:saveas w Zดังนั้นโปรดระมัดระวังสิ่งนี้)

ปรับปรุง

นี่คือวิธีที่ฉันจะเขียนตอนนี้ :

cnoreabbrev <expr> W ((getcmdtype() is# ':' && getcmdline() is# 'W')?('w'):('W'))

ในฐานะที่เป็นฟังก์ชั่น:

fun! SetupCommandAlias(from, to)
  exec 'cnoreabbrev <expr> '.a:from
        \ .' ((getcmdtype() is# ":" && getcmdline() is# "'.a:from.'")'
        \ .'? ("'.a:to.'") : ("'.a:from.'"))'
endfun
call SetupCommandAlias("W","w")

การตรวจสอบนี้ว่าประเภทคำสั่ง:และคำสั่งดังนั้นจึงปลอดภัยกว่าเพียงWcnoreabbrev W w


2
คำตอบนี้ปลอดภัยที่สุดและน่าเชื่อถือที่สุดสำหรับฉัน
Sean

2
หากคุณใช้โซลูชันที่แนะนำโปรดระวังทั้งสองคำสั่งด้านล่างจะทำงานเป็นคำสั่งที่ต่ำกว่าซึ่งอาจนำเสนอผลลัพธ์ที่ไม่คาดคิดขึ้นอยู่กับเนื้อหาบัฟเฟอร์ที่แท้จริงและการตั้งค่า VIM::%s/W/foo/g<CR> :%s/w/foo/g<CR>
cprn

2
ที่จริงแล้วนี่หมายความว่า W จะถูกแทนที่ที่ใดก็ได้ในแถบคำสั่งรวมถึงตัวอย่างเช่นในการค้นหาดังนั้น s / W foo / bar / g จะกลายเป็น s / w foo / bar / g สิ่งนี้สามารถทำให้เกิดความรำคาญได้อย่างรวดเร็ว ดูคำตอบของฉันสำหรับโซลูชันที่ครอบคลุม
airstrike

4
แน่นอน; นี่เป็นความคิดที่น่ากลัว คุณควรจะไม่เคย , เคย , เคยทำเช่นนี้
Chris Morgan

4
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
kev

97

กับการค้นหาเสริมฉันพบว่ามีคนถามเกือบเดียวกันคำถามเป็นครั้งที่หนึ่ง

:command <AliasName> <string of command to be aliased>

จะทำเคล็ดลับ

โปรดระวังว่าในขณะที่Richoชี้ให้เห็นคำสั่งผู้ใช้จะต้องเริ่มต้นด้วยอักษรตัวใหญ่


5
การใช้: คำสั่งเป็นทางออกที่ดี : cnoreabbrev ไม่เข้าใจ cmd1 | cmd2,: คำสั่งทำ
Pavel Strakhov

1
วิธีการเขียนที่สับสนน้อยกว่านี้คือ:command AliasName string of command to be aliased
อเล็กซ์จา

8
นี้จะไม่จัดการ / ไปข้างหน้าใด ๆcommandข้อโต้แย้งเช่น-nargs, -completeฯลฯ
blueyed

สิ่งที่เกี่ยวกับ:Q!หรือ:W!?
Jack

5
เพียงเพื่อเป็นตัวอักษรมาก: ใส่:command W wใน.vimrcไฟล์
isomorphismes

20

ฉันพบว่าการทำแผนที่;กุญแจสำคัญที่:จะเป็นทางออกที่ดีกว่าและจะทำให้คุณมีประสิทธิผลมากขึ้นสำหรับการพิมพ์คำสั่งอื่น ๆ

nnoremap ; :
vnoremap ; :

นี่คือเคล็ดลับเดียวที่ดีที่สุดสำหรับกลุ่ม ตอนนี้ฉันชินแล้วว่าทุกครั้งที่ฉันพบกับพฤติกรรมปกติมันต้องใช้เวลาสักสองสามครั้งที่ฉันจะได้รับการฝึกฝนใหม่
airstrike

นี่ไม่ใช่คำตอบสำหรับคำถาม
Flimm

5
@ ไม่เป็นไร แต่มันทำให้ปัญหาของ OP หายไป
Duncan X Simpson

1
เมื่อใช้tหรือfมักจะสามารถใช้;เพื่อไปที่เกิดขึ้นต่อไป หนึ่งสามารถทำแผนที่ได้อย่างปลอดภัยในทางอื่นแม้ว่าคุณจะทำเครื่องหมายอัฒภาคถึงโคลอน จะไม่มีการวนซ้ำนามแฝง nnoremap : ;
Luc

9

ทางออกที่ดีที่สุดเกี่ยวข้องกับการเขียนฟังก์ชั่นที่กำหนดเองสำหรับการจัดการตัวย่อที่เกิดขึ้นเฉพาะในจุดเริ่มต้นของแถบคำสั่ง

สำหรับสิ่งนี้เพิ่มไฟล์ vimrc ของคุณต่อไปนี้หรือที่อื่น

" cabs - less stupidity                                                      {{{
fu! Single_quote(str)
  return "'" . substitute(copy(a:str), "'", "''", 'g') . "'"
endfu
fu! Cabbrev(key, value)
  exe printf('cabbrev <expr> %s (getcmdtype() == ":" && getcmdpos() <= %d) ? %s : %s',
    \ a:key, 1+len(a:key), Single_quote(a:value), Single_quote(a:key))
endfu
"}}}

 

" use this custom function for cabbrevations. This makes sure that they only
" apply in the beginning of a command. Else we might end up with stuff like
"   :%s/\vfoo/\v/\vbar/
" if we happen to move backwards in the pattern.

" For example:
call Cabbrev('W', 'w')

ตัวย่อที่เป็นประโยชน์เล็กน้อยจากแหล่งข้อมูลที่ฉันพบสิ่งนี้:

call Cabbrev('/',   '/\v')
call Cabbrev('?',   '?\v')

call Cabbrev('s/',  's/\v')
call Cabbrev('%s/', '%s/\v')

call Cabbrev('s#',  's#\v')
call Cabbrev('%s#', '%s#\v')

call Cabbrev('s@',  's@\v')
call Cabbrev('%s@', '%s@\v')

call Cabbrev('s!',  's!\v')
call Cabbrev('%s!', '%s!\v')

call Cabbrev('s%',  's%\v')
call Cabbrev('%s%', '%s%\v')

call Cabbrev("'<,'>s/", "'<,'>s/\v")
call Cabbrev("'<,'>s#", "'<,'>s#\v")
call Cabbrev("'<,'>s@", "'<,'>s@\v")
call Cabbrev("'<,'>s!", "'<,'>s!\v")

1
มีฟังก์ชั่นที่จะเป็นสิ่งเดียวกันกับคุณstring() Single_quote()
ZyX

6

บางทีคุณต้องการแมปปุ่มฟังก์ชั่นหนึ่งตัว (F1..F12) กับ: w? จากนั้นใส่สิ่งนี้ลงใน. vimrc ของคุณ:

noremap  <f1> :w<return>
inoremap <f1> <c-o>:w<return>

(ctrl-o ในโหมดแทรกเปลี่ยนเป็นโหมดปกติชั่วคราว)


6

สมมติว่าคุณต้องการเพิ่มนามแฝงสำหรับคำสั่ง tabnew ใน gvim คุณสามารถพิมพ์คำสั่งต่อไปนี้ในไฟล์. vimrc ของคุณ (หากไม่อยู่ในโฮมโฟลเดอร์มากกว่าสร้างขึ้นมาใหม่)

cabbrev t tabnew

1
สิ่งนี้จะทำให้คำสั่งที่ต้องการ:saveas t exampleแทนที่ด้วย:saveas tabnew example
Flimm

5

ที่ปลอดภัยและง่ายที่สุดคือปลั๊กอินเช่นcmdalias.vimหรือvim-alias ที่อัปเดตล่าสุดของฉันซึ่งคำนึงถึง

  • ก่อนหน้านี้ช่องว่างหรือการปรับเปลี่ยนเช่น:sil(ent)(!)หรือ:redi(r),
  • ตัวดัดแปลงช่วงเช่น '<,'>สำหรับการเลือกภาพปัจจุบัน
  • หนีอักขระพิเศษเช่นคำพูดและ
  • ตรวจสอบว่านามแฝงที่เลือกเป็นตัวย่อบรรทัดคำสั่งที่ถูกต้อง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.