Mengurungkan perintah dalam vim

151

Vim adalah editor teks pilihan saya ketika saya memprogram, dan karena itu saya selalu mengalami masalah yang sangat mengganggu.

Seringkali, ketika saya dengan cepat perlu menyimpan buffer dan melanjutkan ke tugas lain-lain, saya melakukan yang khas

:w

Namun, saya - yang sepertinya lebih dari 50% dari waktu - selalu berhasil memanfaatkannya :w. Tentu saja, vim meneriaki saya karena Witu perintah yang tidak valid

E492: Not an editor command: W

Pertanyaan saya adalah bagaimana bisa satu alias perintah-usus di vim . Terutama, bisa Anda contoh bagaimana alias Wuntuk w.

Saya menyadari proses memetakan kunci ke perintah tertentu . Sayangnya, bukan itu yang saya cari.

Sean
sumber
1
kemungkinan duplikat dari perintah Dapatkah saya (kembali) memetakan dalam vim?
Chris Morgan
1
Untuk menghindari :WAnda bisa memetakan kunci untuk melakukan penghematan. Jika Anda terbiasa dengan beberapa program yang menyimpan dengan Ctrl-s, ada pemetaan ini dari $ 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
Pertanyaan serupa tentang pertukaran Vi Stack: vi.stackexchange.com/q/2665/7244
Flimm

Jawaban:

127

Agar penyelesaian tidak tersentuh, coba gunakan

cnoreabbrev W w

, itu akan menggantikan Wdalam baris perintah dengan w, tetapi hanya jika itu tidak diikuti atau didahului oleh karakter kata, jadi :W<CR>akan diganti dengan :w<CR>, tetapi :Writetidak akan. (Perhatikan bahwa ini memengaruhi perintah yang cocok termasuk yang tidak Anda harapkan, misalnya perintah :saveas W Zakan diganti :saveas w Z, jadi berhati-hatilah dengan ini.)

Memperbarui

Inilah cara saya akan menulisnya sekarang :

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

Sebagai fungsi:

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

Ini memeriksa apakah tipe perintahnya :dan perintahnya W, jadi lebih aman dari pada adil cnoreabbrev W w.

ZyX
sumber
2
Jawaban ini adalah yang paling aman dan paling dapat diandalkan untuk saya.
Sean
2
Jika Anda menggunakan solusi yang disarankan, harap perhatikan bahwa kedua perintah di bawah ini akan berfungsi sebagai yang lebih rendah yang dapat memberikan hasil yang tidak terduga tergantung pada konten buffer aktual dan pengaturan VIM::%s/W/foo/g<CR> :%s/w/foo/g<CR>
cprn
2
Sebenarnya, ini berarti W akan diganti di mana saja di bilah perintah, termasuk, misalnya, dalam pencarian, sehingga s / W foo / bar / g akan berubah menjadi s / w foo / bar / g. ini bisa menjengkelkan sangat cepat. lihat jawaban saya untuk solusi yang komprehensif.
serangan udara
4
Benar; ini ide yang mengerikan . Anda harus tidak pernah , pernah , pernah melakukan hal ini.
Chris Morgan
4
:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
kev
97

Dengan mencari tambahan, saya telah menemukan bahwa seseorang bertanya hampir sama pertanyaan sebagai I.

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

akan melakukan trik.

Perlu diketahui bahwa, seperti yang ditunjukkan Richo , perintah pengguna harus dimulai dengan huruf kapital.

Sean
sumber
5
Menggunakan: perintah adalah solusi yang bagus. : cnoreabbrev tidak mengerti cmd1 | cmd2,: perintah tidak.
Pavel Strakhov
1
Cara yang kurang membingungkan untuk menulis ini adalah,:command AliasName string of command to be aliased
Alec Jacobson
8
Ini tidak akan menangani / meneruskan commandargumen, seperti -nargs, -completedll.
blueyed
Bagaimana dengan :Q!atau :W!?
Jack
5
Untuk menjadi sangat literal: masukkan ke :command W wdalam .vimrcfile.
isomorfisma
20

Saya menemukan bahwa memetakan ;kunci untuk :menjadi solusi yang lebih baik, dan akan membuat Anda lebih produktif untuk mengetik perintah lain.

nnoremap ; :
vnoremap ; :
fent
sumber
Ini adalah tip terbaik tunggal untuk vim. Saya sudah terbiasa dengan hal itu sekarang sehingga setiap kali saya menghadapi perilaku normal, saya perlu beberapa upaya untuk mendapatkan kembali pikiran saya.
serangan udara
Ini bukan jawaban untuk pertanyaan itu.
Flimm
5
@ Flimm Tidak, tapi itu membuat masalah OP hilang.
Duncan X Simpson
1
Saat menggunakan tatau f, seseorang biasanya dapat menggunakan ;untuk pergi ke kejadian berikutnya. Satu dapat dengan aman memetakan itu dengan cara lain, bahkan jika Anda memetakan titik koma ke titik dua. Tidak akan ada loop alias. nnoremap : ;
Luc
9

Solusi terbaik melibatkan penulisan fungsi khusus untuk menangani singkatan yang hanya terjadi di awal bilah perintah.

Untuk ini, tambahkan berikut ini file vimrc Anda atau di mana pun.

" 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')

Beberapa singkatan yang berguna dari bahan sumber tempat saya menemukan barang ini:

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")
serangan udara
sumber
1
Ada fungsi bawaan string()yang melakukan hal yang sama seperti milik Anda Single_quote().
ZyX
6

Mungkin Anda ingin memetakan salah satu tombol fungsi Anda (F1..F12) ke: w? Kemudian masukkan ini ke .vimrc Anda:

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

(ctrl-o dalam mode insert beralih sementara ke mode normal).

Benoit
sumber
6

Misalkan Anda ingin menambahkan alias untuk perintah tabnew di gvim. Anda cukup mengetik perintah berikut di file .vimrc Anda (jika tidak di folder home daripada membuatnya)

cabbrev t tabnew
Sandip
sumber
1
Ini akan menyebabkan perintah ingin :saveas t examplediganti dengan:saveas tabnew example
Flimm
5

Paling aman dan termudah adalah plugin seperti cmdalias.vim atau pembaruan terbaru saya -alias vim yang memperhitungkannya

  • kekosongan atau pengubah sebelumnya seperti :sil(ent)(!)atau :redi(r),
  • pengubah rentang seperti '<,'>untuk pemilihan visual saat ini,
  • melarikan diri karakter khusus seperti kutipan, dan
  • periksa apakah alias yang dipilih adalah singkatan baris perintah yang valid.
Enno
sumber