Bagaimana saya bisa memetakan d [hitung] d?


18

NB Ini bukan duplikat dari Bagaimana cara kerja perintah "d3fg"? Silakan baca sebelum pemungutan suara untuk menutup!

Saya menemui sedikit kebuntuan dalam pencarian saya untuk menghapus pekerjaan kecil seperti yang besar . Masalah yang saya miliki adalah bahwa saya tidak tahu bagaimana cara membuat ulang perintah seperti d3d. Faktanya, saya bahkan tidak bisa mengerti bagaimana mereka bekerja sejak awal, juga tidak menemukan mereka dalam bantuan Vim. *

d3jmudah: itu berlaku doperator untuk 3jgerakan,

3ddjuga mudah: ia menjalankan ddperintah dengan "hitungan" 3.

d3d sepertinya itu harus langsung, itu berlaku doperator ke ... tapi apa 3d? Itu bukan gerak. Jika Anda mengetik 3dsendiri, Vim memperlakukannya sebagai hitungan yang diikuti oleh operator, dan menunggu dengan sabar untuk masukan lebih lanjut.

Dan Anda tidak dapat menerapkan operator ke operator lain. ddtidak dijelaskan dalam bantuan sebagai urutan dua operator. Ini adalah perintah dua tombol terpisah. (lih. dc, yang tidak melakukan apa-apa.)

Tampaknya juga tidak terjadi bahwa posisi penghitungan fleksibel untuk perintah yang memerlukan dua penekanan tombol: 2gjmemindahkan kursor ke bawah dua garis layar, tetapi g2jmembuang dua penekanan tombol pertama sepenuhnya dan memindahkan kursor ke bawah satu baris.

Jadi bagaimana cara kerjanya? Apakah ini hanya kasus khusus dalam kode internal Vim? Apakah ada cara saya bisa membuat d[count]dpemetaan?

EDIT : Apakah itu objek teks? :h text-objectstidak termasuk dalam daftar "text perintah seleksi obyek", tapi kemudian tidak termasuk hh dalam daftar penghapusan "dikelompokkan dari kecil ke benda-benda besar". Dan d2awmenghapus kata di bawah kursor dan yang berikut. Di sisi lain, c2dtidak melakukan apa pun.

* Saya yakin beberapa menyebutkan mereka harus ada, tetapi saya tidak dapat menemukannya. Saya telah membaca :help deleting,, :help motion.txtdan mencoba :helpgrep dNduntuk semua nilai N dari 1–9 .


2
Saya pikir dtindakan terakhir sebagai konfirmasi; Jadi sama dengan d3<CR>. y3ydan c3cjuga bekerja sama ... Saya tidak dapat menemukan dokumen tentang ini meskipun di Vim: help, vi (1), nvi (1), atau spec POSIX ... Itu berperilaku sama vidan dalam nvibtw .
Martin Tournoij

1
Di satu sisi, ddidentik dengan d_. _membawa kursor ke non-blank pertama pada garis ( [count]-1) ke bawah, tapi itu juga, jadi ketika dipasangkan dengan operator, kursor beroperasi pada seluruh baris. Untuk alasan itu, masuk akal bahwa hitungan dapat muncul di antara keduanya d.
tommcdo

Jawaban:


28

Mode operator-tertunda

Antara mengetik operator (seperti d, c, atau gU) dan gerak (seperti w, i}, atau /foo<CR>), Vim dalam mode Operator-pending. Anda dapat membuat pemetaan untuk ini menggunakan :omapdan :onoremap.

Dalam contoh saya, saya akan memetakan Operator-pending duntuk w. Ini adalah pilihan acak, karena saya tidak tahu untuk apa Anda sebenarnya ingin menggunakannya.

Buat omap

Mari kita buat pemetaan untuk ddalam mode pending Operator. Saya akan menganggap kita sedang menulis VimScript di sini (seperti di Anda .vimrc), jadi saya akan menghilangkan :s.

onoremap d w

Ini membuat ddbertindak seperti dw. Itu juga membuat d[count]dbertindak seperti d[count]w. Tapi saya yakin Anda tidak ingin mempengaruhi perilaku dd(yaitu, tidak [count]disediakan).

Pemetaan ekspresi

Pemetaan ekspresi memungkinkan Anda mengevaluasi ekspresi VimScript untuk menghasilkan sisi kanan pemetaan. Ekspresi harus dievaluasi menjadi string. Pemetaan ekspresi dilambangkan dengan <expr>kata kunci.

Vim juga memiliki beberapa variabel bawaan yang dapat diisi pada berbagai waktu, dan sering berguna selama pemetaan. Salah satunya adalah v:count, yang [count]disuplai ke operator atau gerak.

Mari kita satukan itu semua. Jika tidak [count]disediakan, v:countakan 0. Kami dapat memberitahu pemetaan kami untuk hanya digunakan ddalam kasus itu.

onoremap <expr> d v:count == 0 ? 'd' : 'w'

Sekarang ddberperilaku seperti default (menghapus garis), tetapi d[count]dberperilaku seperti d[count]w. Keren!

Batasi untuk digunakan setelah doperator

Anda mungkin memperhatikan sesuatu. Sekarang cdjuga berperilaku seperti cw. Ini mungkin bukan masalah, tetapi untuk kelengkapan, mari batasi sehingga hanya berfungsi setelah doperator.

Vim memiliki variabel lain v:operator, yang berisi operator yang terakhir digunakan. Mari kita periksa juga, sebelum melakukan sesuatu yang istimewa.

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'

CATATAN: Karena :mapperintah dapat dirantai dengan |, kita harus menghindarinya dalam ekspresi kita di sini. Jadi operator OR logis ||menjadi \|\|.

Keren, jadi cddan c[count]dkembali untuk tidak melakukan apa-apa, seperti dulu. Ini bagus sehingga plugin lain dapat mendefinisikan cd.

Saya tidak ingin menghapus beberapa gerakan lainnya

Jika Anda ingin memetakan d[count]dsesuatu yang sama sekali berbeda, tidak ada hubungannya dengan menghapus teks, kita bisa membuatnya bekerja juga.

Saat Anda mengetik perintah dalam mode Normal, dan Anda mulai mengetik perintah secara tidak sengaja, Anda dapat menekan <Esc>untuk membatalkan perintah itu. Hal yang sama berlaku untuk pemetaan Anda.

Mari kita d[count]dubah baris saat ini menjadi apa pun [count].

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'

Bagian terakhir dari pemetaan adalah ekspresi VimScript: <Esc>cc' . v:count . '<Esc>'. Itu <Esc>untuk membatalkan dperintah yang tertunda , kemudian ccuntuk mengubah baris saat ini, v:countuntuk mengetik nilai [count](dalam mode Insert), dan <Esc>untuk kembali ke mode Normal. Perhatikan bahwa kami sedang membuat string di sini menggunakan operator gabungan VimScript .,.


Kasing Anda yang sebenarnya mungkin akan berbeda dari yang saya sebutkan di sini, tapi mudah-mudahan ini membantu Anda untuk membuat bola bergulir.

Selamat Vimming!


Jawaban bagus! Terpilih. Saya melakukan tautan ke use case saya (juga di vi.SE) pada awal pertanyaan, tapi saya kira Anda pasti melewatkannya. Saya pada dasarnya perlu melakukan :omap d d(!), Tapi sayangnya mode pending operator tidak pernah benar-benar tercapai karena pemetaan saya untuk d yang menetapkan fungsi operator kustom. Mudah-mudahan mungkin untuk mengubah hal-hal untuk membuat d3dpekerjaan sebagaimana mestinya. (Beri tahu saya jika Anda memiliki ide, atau merasa bebas untuk mengirim solusi lengkap ke pertanyaan lain jika Anda mau.) Jika saya tidak segera mengetahuinya, saya akan menerimanya dan mengirim pertanyaan lain yang lebih spesifik. Terima kasih!
Rich

1
Sebenarnya, setelah dipikir-pikir, saya menerima ini sekarang. Anda menjelaskan cara membuat pemetaan seperti itu, dan juga cara kerjanya di bawah tenda, yang merupakan dua hal yang saya tanyakan.
Rich
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.