Banyak kursor di lokasi yang diinginkan


13

Saya menggunakan plugin vim-multiple-cursors .

Saya ingin menempatkan kursor tepat di tempat yang saya inginkan. Misalnya ( [x]adalah posisi kursor):

Lorem ipsum dolor sit amet[1], consectetur adipiscing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna[2]
aliqua.

Dalam Teks Sublim saya biasanya akan meletakkan kursor pertama, kemudian pergi ke posisi berikutnya dengan tombol panah dan meletakkan yang kedua.

Apakah ada yang serupa di VIM? Dengan plugin ini atau yang lain.

EDIT

Setelah komentar, minat saya untuk melakukannya muncul ketika mencoba menulis
\section[My first section in this book]{My first section in this book}
dalam .texfile. Reaksi pertama saya adalah menulis \section[]{}dan kemudian meletakkan dua kursor untuk menulis hal yang sama di dalam []dan {}.

Contoh lain adalah menambahkan _someStuffsetelah beberapa nama variabel berbeda. Misalnya, ubah ini:

variable1 = 2
my_variable2 = 12
var3 = 14

dalam hal ini:

variable1_someStuff = 2
my_variable2_someStuff = 12
var3_someStuff = 14

Dengan banyak kursor, saya dapat melakukannya dengan memilih kursor kolom dan kemudian pergi ke akhir kata, lalu memasukkan, dll. Tapi saya rasa saya akan mudah untuk memilih di mana saya ingin kursor berada.



1
Saya pikir pertanyaan penting untuk ditanyakan adalah mengapa Anda ingin melakukan itu? Apa yang sedang Anda coba lakukan? Menggunakan banyak kursor tidak benar-benar "mengikuti cara Vim", mungkin ada cara berbeda untuk melakukan apa yang Anda inginkan, setidaknya seefisien, menggunakan fitur bawaan.
statox

@statox. Lihat edit. Saya memberikan dua contoh yang muncul di benak saya. Yang kedua saya bisa capai dengan plugin vim-multiple-cursors, tetapi yang pertama saya tidak bisa, setidaknya dengan cara yang mudah.
tomasyany

@ Nobe4. Terima kasih, skrip kedua membuatnya.
tomasyany

Jawaban:


29

Menggunakan banyak kursor bukanlah hal Vimmer

Seperti yang saya katakan di komentar menggunakan multi kursor (bahkan dengan plugin) tidak benar-benar "mengikuti cara Vim", saya benar-benar mengerti bahwa itu menarik bagi seseorang yang datang dari Sublime-Text tetapi Anda sering dapat menemukan alternatif yang setidaknya seefisien dengan fitur bawaan Vim.

Tentu saja, menemukan solusi alternatif ini tidak selalu mudah dan kadang-kadang membutuhkan waktu tetapi akan lebih mudah dengan pengalaman Vim Anda dan Anda akan melihat bahwa seiring waktu beberapa kursor akan tampak sama sekali tidak berguna bagi Anda.

Itu keren tapi bagaimana saya bisa menemukan cara alternatif?

Tidak ada jawaban universal karena sangat tergantung pada apa yang Anda coba lakukan, saya hanya akan mencoba memberikan beberapa petunjuk tentang hal-hal pertama yang harus dicoba:


Perintah titik .

Perintah Dot mungkin salah satu alat paling kuat di Vim, itu hanya memungkinkan kita untuk mengulangi perubahan terakhir. Saya tidak bisa menjelaskannya lebih baik daripada Drew Neil dalam bukunya Practical Vim . Saya pikir setiap Vimmer harus mempertimbangkan untuk membaca buku ini.

Kekuatan dari perintah ini adalah bahwa perubahan terakhir dapat berupa tindakan yang bekerja pada karakter, baris atau seluruh file. Misalnya, perubahan dapat dibatasi pada saat Anda memasuki mode penyisipan dan saat Anda kembali ke mode normal.

Dengan mengingat hal itu, mudah untuk melakukan apa yang ingin Anda lakukan dengan multicursor:

  • Pertama mari kita mengatur lingkungan kita: Mari menulis seperti yang Anda sarankan

    \section[]{}

  • Kemudian buat perubahan berulang . Kursor sekarang aktif }, tekan F[untuk kembali ke [karakter. Kemudian masukkan mode masukkan dengan idan ketik My first section in this bookdan kembali ke mode normal dengan ESC:

    \section[My first section in this book]{}

  • Dan inilah bagian ajaibnya: Mari kita ketik f{untuk meletakkan kursor pada {karakter dan tekan .untuk mengulangi perubahan terakhir:

    \section[My first section in this book]{My first section in this book}

Semua tantangan dari perintah titik adalah belajar bagaimana membuat perubahan berulang: itu akan datang dengan gim Vim tetapi dasarnya adalah memahami bagaimana membuat perubahan Anda dengan cara yang berulang.

Misalnya untuk menyisipkan titik koma di akhir baris yang Anda akan lebih suka menggunakan A;daripada $a;. Mengapa?

Karena A;menciptakan aksi atom, jadi ketika Anda akan menggunakan .di jalur lain, di mana pun Anda berada di garis itu, Anda akan memasukkan titik koma di bagian akhir. Sedangkan saat menggunakan $a;Anda membagi perubahan Anda menjadi dua bagian $adan penyisipan ;jadi jika Anda menggunakannya .akan memasukkan titik koma di posisi kursor saat ini.

Perhatikan Rumus ajaib dalam Vim adalah n.. Alur kerja yang sangat keren adalah:

  • cari tempat Anda ingin mengedit /pattern
  • lakukan pengeditan berulang Anda
  • gunakan nuntuk pergi ke tempat berikutnya untuk mengedit
  • gunakan .untuk mengulang suntingan
  • ulangi dua langkah terakhir: Anda adalah raja dunia (atau setidaknya suntingan)

makro

Macro adalah alat lain yang sangat penting di Vim karena memungkinkan Anda untuk merekam urutan penekanan tombol dan mengulanginya seolah-olah Anda mengetiknya lagi.

Saya akan menggunakan, sebagai contoh, use case kedua Anda:

variable1 = 2
my_variable2 = 12
var3 = 14

Sekali lagi yang penting adalah mempelajari cara membuat makro Anda efisien (saya akan memberikan contoh balasan setelahnya):

  • Letakkan kursor Anda pada kata variable1dan mulai merekam makro Anda dengan qq. Ini berarti "mulai merekam semua penekanan tombol masa depan saya di register bernama q".

  • Mulai buat pengetikan edit Anda:

    • 0 untuk pergi di awal baris
    • e untuk pergi di akhir kata pertama
    • a untuk menambahkan setelah kursor Anda
    • .someStuff untuk menambahkan teks yang diinginkan
    • <Esc> untuk menghentikan penyisipan
    • j untuk melanjutkan ke baris berikutnya
    • q untuk berhenti merekam makro
  • Anda akan mendapatkan:

variable1.someStuff = 2
my_variable2 = 12
var3 = 14
  • Sekarang Anda dapat menggunakan makro untuk mengulangi pengeditan Anda. Saat Anda berada di jalur yang benar untuk diedit, Anda cukup menjalankan makro dengan @q. Karena kami ingin menjalankannya dua kali, Anda dapat menggunakan 2@qdan Anda akan mendapatkan hasil berikut:
variable1.someStuff = 2
my_variable2.someStuff = 12
var3.someStuff = 14

CATATAN 1 Seperti yang mungkin telah Anda perhatikan, menggunakan 0eapada awal makro sangat penting. Memang, jika Anda meletakkan kursor di akhir kata pertama sebelum merekam makro dan mengeksekusinya lagi, hasilnya adalah:

variable1.someStuff = 2
my_variable2 = 12.someStuff
var3 = 14.someStuff

Sebagai kursor Anda teks akan disisipkan pada posisi kursor setelah mengubah baris (yaitu akhir baris dalam kasus ini)

CATATAN 2 Makro sangat kuat dan Anda bahkan dapat membuat makro rekursif saat Anda merasa nyaman dengannya. Di sini, makro Anda mungkin:

`0ea.someStuff<Esc>j@q`

Final @qakan memanggil makro dengan sendirinya alih-alih menggunakan 2@q; Anda hanya akan menggunakan @qdan semua pekerjaan akan dilakukan.


blok visual

Ini dia trik lain yang tidak secara langsung diterapkan pada use case Anda tetapi bisa sangat berguna untuk mengedit sejumlah besar baris pada saat yang bersamaan. Mari kita ambil ekstrak kode CSS ini:

li.one   a{ background-image: url('/images/sprite.png'); }
li.two   a{ background-image: url('/images/sprite.png'); }
li.three a{ background-image: url('/images/sprite.png'); }

Bagaimana jika Anda memindahkan sprite dari imageske components?

Nah Anda dapat menempatkan kursor Anda pada idari imagesdan tekan <C-v>. Ini akan memulai mode blok visual yang memungkinkan untuk memilih blok. Sekarang Anda dapat mengetik t/ untuk memilih kata yang ingin Anda ubah dan 2juntuk memilih semua kemunculan kata tersebut.

Setelah itu Anda cukup mengetik cuntuk mengubah kata lalu components. Saat Anda keluar dari mode penyisipan, Anda akan melihat:

li.one   a{ background-image: url('/components/sprite.png'); }
li.two   a{ background-image: url('/components/sprite.png'); }
li.three a{ background-image: url('/components/sprite.png'); }

Perintah global

Perintah global adalah alat yang memungkinkan untuk menerapkan perintah mode ex pada garis yang cocok dengan pola, sekali lagi itu cara yang baik untuk menerapkan perubahan yang sama di tempat yang berbeda tanpa memerlukan banyak kursor.

Sintaksnya adalah sebagai berikut:

:[range] g / pattern / command

Untuk detail lebih lanjut tentang [range]parameter, silakan lihat :h :range. Saya tidak akan memerinci di sini, saya hanya akan mengingatkan yang %mewakili seluruh file, '<,'> mewakili pilihan terakhir, dan 1,5mewakili baris 1 hingga 5 file.

Parameter ini mendefinisikan garis yang akan diperlakukan oleh perintah global. Jika tidak ada rentang yang ditentukan, maka perintah global akan digunakan %secara default.

Argumen [pola] adalah pola pencarian seperti yang biasa Anda gunakan dengan mesin pencari. Saat mengintegrasikan riwayat pencarian, Anda dapat membiarkan bidang ini kosong dan perintah global akan menggunakan pola pencarian terakhir dalam riwayat pencarian.

Akhirnya parameter [perintah] adalah perintah ex karena Anda mungkin terbiasa.

Sekarang perilaku perintah global cukup sederhana:

  • Ulangi semua garis yang ditentukan dalam parameter [rentang]
  • Jika garis saat ini cocok dengan pola yang ditentukan, terapkan perintah

Karena parameter [perintah] adalah perintah ex, Anda dapat melakukan banyak hal. Mari kita ambil kode pseudo berikut yang tidak cukup menarik dan memiliki banyak pesan debug:

var myList  = null
var i       = 0

myList = new List()
echo "List instantiated"

for (i=0; i<10; i++)
    myList.Add(i)
    echo i . " added to the list"

echo "end of for loop"

Sekarang katakanlah Anda yakin kode ini berfungsi dan Anda ingin menghapus echopernyataan tidak berguna ini :

  • Anda dapat menerapkan perintah global Anda pada seluruh file sehingga Anda harus menambahkan perintah dengan %(atau tanpa apa-apa karena %rentang default).

  • Anda tahu bahwa garis yang ingin Anda hapus semua cocok dengan pola echo

  • Anda ingin menghapus baris-baris ini sehingga Anda harus menggunakan perintah :delete yang juga bisa disingkatd

Jadi, Anda cukup menggunakan fungsi berikut:

:%global/echo/delete

Yang juga bisa disingkat

:g/echo/d

Perhatikan bahwa %menghilang, globaldisingkat sebagai gdan deletesebagai d. Seperti yang Anda bayangkan hasilnya adalah:

var myList  = null
var i       = 0

myList = new List()

for (i=0; i<10; i++)
    myList.Add(i)

CATATAN 1 Poin penting yang perlu waktu untuk saya sadari adalah bahwa normalperintah tersebut adalah perintah ex yang artinya Anda dapat menggunakannya dengan perintah global. Itu bisa sangat kuat: katakanlah saya ingin menduplikasi semua baris yang berisi gema, saya tidak perlu makro atau bahkan formula ajaib n.. Saya cukup menggunakan

:g/echo/normal YP

Dan voila:

var myList  = null
var i       = 0

myList = new List()
echo "List instantiated"
echo "List instantiated"

for (i=0; i<10; i++)
    myList.Add(i)
    echo i . " added to the list"
    echo i . " added to the list"

echo "end of for loop"
echo "end of for loop"

CATATAN 2 "Hei bagaimana jika saya ingin menggunakan perintah saya pada baris yang tidak cocok dengan pola tertentu?"

globalmemiliki perintah berlawanan vglobaldisingkat vyang berfungsi persis seperti globalkecuali bahwa perintah akan diterapkan pada baris yang tidak cocok dengan parameter [pola]. Cara ini jika kita terapkan

:v/echo/d

Pada contoh kami sebelumnya, kami mendapatkan:

echo "List instantiated"
    echo i . " added to the list"
echo "end of for loop"

The deleteperintah telah diterapkan pada baris yang tidak mengandung echo.


Di sini saya berharap bahwa beberapa petunjuk itu akan memberi Anda ide tentang cara menyingkirkan plugin multi-kursor Anda dan menggunakan Vim dengan cara Vim ;-)

Seperti yang dapat Anda bayangkan, contoh-contoh ini sangat sederhana dan dibuat untuk menunjukkan bahwa ketika Anda mengikuti Vim, Anda jarang membutuhkan beberapa kursor. Saran saya adalah ketika Anda menghadapi situasi di mana Anda pikir itu akan berguna, tulis dan luangkan waktu kemudian untuk menemukan solusi yang lebih baik. 99% dari waktu Anda akhirnya akan menemukan cara yang lebih cepat / lebih efisien untuk melakukannya.

Juga saya akan mengulangi diri saya sekali lagi tetapi saya benar-benar mendorong Anda untuk membaca Vim Praktis oleh Drew Neil karena buku ini bukan tentang "Bagaimana melakukan ini atau ini di Vim" ini tentang "Bagaimana belajar berpikir dengan cara Vim" yang akan memungkinkan Anda untuk membangun solusi Anda sendiri untuk masalah masa depan Anda dengan cara yang baik.


Terima kasih khusus PS kepada @Alex Stragies untuk pekerjaan penyuntingannya dan koreksi yang ia buat untuk pos panjang ini.


Jawabannya sangat lengkap. Saya sebenarnya tahu semua perintah itu, tetapi tidak pernah berpikir untuk menggunakannya seperti itu ... Saya kira saya perlu lebih banyak latihan. Namun, saya harus mengatakan bahwa kadang-kadang 'vim-way' memakan waktu lebih lama daripada hanya menggunakan beberapa plugin (misalnya, contoh CSS Anda dapat dilakukan lebih cepat dengan plugin yang saya sebutkan), dan kadang-kadang dibutuhkan jauh lebih pendek (sebenarnya, luas sebagian besar kali vim lebih cepat daripada editor teks apa pun, jika digunakan dengan benar).
tomasyany

Btw, saya pikir jawaban Anda sudah cukup lengkap. Saya akan menerimanya, tetapi jika Anda ingin menambahkan lebih banyak detail, silakan lakukan dan saya akan senang membacanya.
tomasyany

1
@tomasyany: Memang kadang-kadang menggunakan "vim way" mungkin tampak lebih lama (saya tidak bisa menghitung berapa kali saya menghabiskan lebih banyak waktu untuk membuat makro yang berfungsi daripada jika saya telah melakukan perubahan secara manual) tetapi dengan latihan itu akhirnya menjadi lebih cepat. Saya telah menggunakan Vim hanya selama satu tahun dan saya (sangat) jauh dari menjadi seorang ahli tetapi saya dapat merasakan bahwa pengeditan saya terus meningkat ketika saya berlatih.
statox

1
Mungkin harus menyebutkan gnobjek teks juga. Ini membahas beberapa kasus penggunaan beberapa kursor. Cari dengan /, lalu dgnatau cgn, lalu ulangi dengan ..
Justin M. Keyes

@Justin Saya tidak terlalu akrab dengan gnsaya akan mencobanya dan menambahkannya setelah. Terima kasih atas kepalanya!
statox

5

Kasus penggunaan yang Anda berikan kepada saya terdengar ingin tahu .perintah kunci (ulangi perintah Pengeditan terakhir)

  • Pergi ke tempat pertama, tekan i, masukkan teks Anda,<ESC>
  • pindah ke lokasi 2, tekan .(Dot) ==> Teks Identik dimasukkan
  • Untuk memindahkan satu baris ke sini dan menyisipkan lagi (saat memasukkan ke dalam garis yang berurutan), tekan <ALT>-j.

Contoh tex Anda untuk saya diselesaikan oleh:

I\section[]{}<ESC>hhiMy first Sec...<ESC>lll.


Ini solusi yang cukup bagus. Saya tahu benar .perintah kunci, tetapi tidak pernah berpikir untuk menggunakannya dengan cara itu. Saya setuju itu cara yang bagus. Tetapi jawaban Anda sebenarnya tidak merujuk pada pertanyaan yang sebenarnya, jadi saya rasa tidak pantas menerimanya.
tomasyany

1
Nah, pertanyaan Anda (setelah Anda menambahkan use case yang diinginkan) mengingatkan saya pada "Saya sangat suka gunting saya, dan ingin mengencangkan sekrup dengan mereka. Katakan padaku caranya". Dan saya menunjuk Anda ke penggunaan bagus untuk obeng;) (saya menambahkan sebagai jawaban, karena saya tidak tahu, bagaimana melakukan pemformatan dalam komentar)
Alex Stragies

4

Lebih banyak cara Vim.

Tugas pertama:

\section[foobar baz]{foobar baz}

Alur kerja:

\section[]{}
hh
ifoobar baz<Esc>
$.

Tugas kedua:

variable1 = 2
my_variable2 = 12
var3 = 14

Perintah:

3:norm ea_somestuff

Hasil:

variable1_somestuff = 2
my_variable2_somestuff = 12
var3_somestuff = 14
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.