Bagaimana cara menyisipkan pemutusan baris di mana kursor berada tanpa masuk ke mode penyisipan di Vim?

89

Apakah mungkin untuk memasukkan jeda baris di mana kursor berada di Vim tanpa masuk ke mode penyisipan? Berikut contohnya ( [x]artinya kursor aktif x):

if (some_condition) {[ ]return; }

Kadang-kadang, saya mungkin ingin memasukkan beberapa kode lagi. Jadi saya akan menekan iuntuk masuk ke mode sisip, tekan Enteruntuk memasukkan jeda baris dan kemudian menghapus spasi ekstra. Selanjutnya, saya akan masuk ke mode normal dan memposisikan kursor sebelum tanda kurung tutup dan kemudian melakukan hal yang sama untuk mendapatkannya di barisnya sendiri.

Saya sudah melakukan ini beberapa lama, tetapi pasti ada cara yang lebih baik untuk melakukannya?

Mark A. Nicolosi
sumber
Anda ingin memasukkan sesuatu tanpa masuk ke mode INSERT?
Jeremy Cantrell
26
@ Jeremy-Cantrell Ya, seperti "J" yang bergabung dengan baris berikutnya dan memasukkan spasi tanpa masuk ke mode INSERT!
Awendt

Jawaban:

108

Untuk contoh yang Anda berikan, Anda dapat menggunakan rEnteruntuk mengganti satu karakter (spasi) dengan Enter. Kemudian, fspace.untuk maju ke ruang berikutnya dan ulangi perintah terakhir.

Bergantung pada pengaturan autoindent Anda, di atas mungkin atau mungkin tidak indentasi pernyataan return dengan benar. Jika tidak, gunakan sEnterTabEscsebagai gantinya untuk mengganti spasi dengan baris baru, membuat indentasi baris, dan keluar dari mode penyisipan. Anda harus mengganti spasi kedua dengan perintah yang berbeda sehingga Anda tidak dapat menggunakan '.' pada kasus ini.

Greg Hewgill
sumber
1
Saya rasa ini adalah solusi termudah. Terima kasih Greg.
Mark A. Nicolosi
4
'f [spasi]' harus setara dengan 'W' (yaitu pindah ke whitepsace berikutnya)
Nathan Fellman
4
'W' memindahkan satu karakter terlalu jauh, ia pindah ke karakter berikutnya setelah spasi berikutnya.
Greg Hewgill
1
Anda juga dapat menggunakan >>dan <<untuk membantu membuat indentasi jika Anda tidak ingin masuk ke mode penyisipan s.
Conner
12

Berikut cara membuat makro yang menyisipkan baris baru di kursor setiap kali Anda menekan 'g' saat tidak dalam mode penyisipan:

Dari dalam vim, ketik:

:map g i[Ctrl+V][Enter][Ctrl+V][Esc][Enter]

Dimana:

  • [Ctrl + V] berarti tahan tombol Ctrl dan tekan 'v'
  • [Enter] berarti tekan tombol Enter
  • [Esc] berarti menekan tombol Esc

Anda akan melihat yang berikut ini di bagian bawah jendela vim Anda sampai Anda menekan Enter terakhir:

:map g i^M^[

Penjelasan:

[Ctrl + V] berarti "kutip karakter berikut" - ini memungkinkan Anda untuk menyematkan baris baru dan keluar dari karakter dalam perintah.

Jadi Anda memetakan kunci 'g' ke urutan:

i [Masuk] [Escape]

Ini adalah vim untuk menyisipkan baris baru sebelum kursor, lalu keluar dari mode penyisipan .

Tweaks:

  • Anda dapat mengganti 'g' dengan karakter apa pun yang belum ditautkan ke perintah yang Anda gunakan.
  • Tambahkan lebih banyak ke perintah, misalnya f}i^M^[O - ini akan f ind } dan saya nsert baris baru yang lain, lalu melarikan diri dari modus insert dan O pen baris kosong bagi Anda untuk memasukkan kode lebih.
  • Anda dapat menambahkan perintah ke file .vimrc atau .exrc Anda untuk membuatnya permanen. Hapus saja titik dua dari awal, jadi perintahnya dimulai dengan "peta"

Nikmati!

Adam Liss
sumber
Anda menjawab pertanyaan yang diutarakan dengan buruk di subjek, bukan pertanyaan di postingan. Yang ingin dia ketahui adalah bagaimana dengan mudah menghilangkan spasi yang berada di titik di mana garis putus tetapi tidak lagi memiliki tujuan.
Aristoteles Pagaltzis
Terima kasih. Memperbarui bagian "Tweaks" untuk mencapai apa (menurut saya) yang diminta penulis. Ketika saya mengujinya, vi secara otomatis menghapus ruang ekstra untuk saya; gunakan 'x' untuk menghapusnya jika milik Anda tidak. Dan mengapa perintah vi terlihat seperti gangguan jalur modem? :-)
Adam Liss
11

Pemetaan sederhana untuk memutus garis di kursor dengan menekan Ctrl + Enter:

:nmap <c-cr> i<cr><Esc>

pada dasarnya memasuki mode 'sisipkan', menyisipkan jeda baris dan kembali ke mode normal.

letakkan di file .vimrc Anda untuk digunakan di masa mendatang.

Yariv
sumber
5

Jika Anda biasanya memperluas blok satu baris menjadi tiga baris, cobalah substitusi. Ubah braket pembuka menjadi braket / braket penutup, dan braket penutup menjadi braket kembali / braket.

Perintah untuk mengganti braket / pengembalian braket terlihat seperti ini:

:s/{/{\r/

Karena Anda ingin sering menggunakannya, Anda dapat memetakan urutan lengkap ke penekanan tombol yang tidak digunakan seperti ini:

:map <F7> :s/{/{\r/ ^M :s/}/\r}/ ^M

Di mana Anda melihat ^ M dalam urutan, ketik [Ctrl-V] , lalu tekan enter .

Sekarang dengan kursor Anda di mana saja pada baris sampel Anda, tekan tombol yang dipetakan, dan carriage return ditambahkan.

Periksa :help map-which-keyssaran tentang memilih penekanan tombol yang tidak digunakan untuk dipetakan.

slothbear
sumber
BTW: gtidak dipetakan karena digunakan sebagai kunci 'namespace' untuk banyak pemetaan vim yang terdiri dari dua penekanan tombol (lihat :h g). Jadi pemetaan ini sebenarnya tidak boleh dilakukan.
Hotschke
Apakah ada perintah yang baik yang melaporkan yang gsudah digunakan sebagai kunci 'namespace'?
slothbear
Tidak secara khusus. Seperti yang saya katakan :help gadalah salah satu cara untuk melihat daftar gpemetaan + sesuatu default . z, [ ]adalah kunci 'namespace' lebih lanjut, lihat mis :help index. Anda dapat meminta :verbose map guntuk melihat semua pemetaan yang ditentukan saat ini yang dimulai dengan g. Sumber daya web yang berguna adalah viemu.com/vi-vim-cheat-sheet.gif , vimcasts.org/blog/2014/02/follow-my-leader , vimeo.com/85343734 (slide: speakerdeck.com/nelstrom/follow-my -leader )
Hotschke
3

Dengan asumsi Anda baik-baik saja dengan memetakan Kke sesuatu yang lain (pilih kunci lain yang Anda sukai), dan menggunakan penanda 'sebagai penanda sementara tidak masalah mengapa tidak melakukan ini?

:nmap K m'a<CR><Esc>`'

sekarang menekan K dalam mode normal di atas karakter yang Anda inginkan agar pemutusan baris terjadi akan memisahkan garis dan meninggalkan kursor di tempatnya.

mondaugen
sumber
1

Vim secara otomatis akan mematikan spasi kosong di sebelah kanan kursor jika Anda memutus baris dalam dua saat autoindent(atau bantuan indentasi lainnya) diaktifkan.

Jika Anda tidak ingin menggunakan pengaturan tersebut, gunakan sbukan iuntuk s ubstitute teks baru untuk kosong daripada hanya memasukkan. (Jika ada beberapa tempat kosong, letakkan kursor di paling kiri dan gunakan cwsebagai gantinya.)

Aristoteles Pagaltzis
sumber
1

Pada dasarnya, saat Anda membagi garis, Anda hanya ingin memasukkan carriage return, atau jika Anda berada di spasi, gantilah dengan carriage return. Nah, mengapa puas dengan satu atau yang lain? Inilah pemetaan saya untuk K:

"Have K split lines the way J joins lines
nnoremap <expr>K getline('.')[col('.')-1]==' ' ? "r<CR>" : "i<CR><Esc>"

Saya menggunakan operator terner untuk menyingkat dua tindakan menjadi satu peta utama. Memecahnya, <expr>berarti keluaran peta kunci bisa dinamis dan dalam hal ini bergantung pada kondisi getline('.')[col('.')-1]==' 'yang merupakan cara bertele-tele untuk menanyakan vim apakah karakter di bawah kursor adalah spasi. Terakhir, operator terner yang sudah dikenal ? :mengganti spasi dengan linebreak ( r<CR>) atau menyisipkan yang baru ( i<CR><Esc>)

Sekarang Anda memiliki peta kunci adik yang bagus untuk Jperintah.

ctrl
sumber
Ini cukup apik. Saya tidak yakin apakah saya pernah dengan sengaja menggunakan K, tetapi ini mungkin membuatnya layak untuk dihapus atau dipetakan ulang di tempat lain.
dragon788
0

Setel pemetaan kunci ini di vimrc Anda

:map <C-m> i<CR><Esc>h

Kemudian tekan Ctrl + m jika Anda ingin menggunakannya di vim Anda.

Kiddo
sumber
0

IMHO, pemetaan bawaan gsbukanlah pemetaan yang berguna (alihkan vim ke mode tidur), orang dapat menggunakan ini untuk pemisahan:

nmap gs i<CR><ESC>
Hotschke
sumber
0

Di Vrapper Anda dapat menggunakan gql yang akan membagi baris tanpa memasuki mode penyisipan, tetapi mungkin tidak selalu mempertahankan indentasi.

Janac Meena
sumber
0

Sebenarnya Anda membutuhkan operasi gabungan berikut:

  1. Tekan vuntuk masuk ke Mode Visual
  2. Pilih garis yang ingin Anda pisahkan
  3. Tekan :untuk masuk dalam Mode Perintah
  4. s/\s/\r/g
  5. Selesai
Nathan
sumber
0

Jika Anda memiliki masukan:

aaa bbb ccc ddd

dan ingin menghasilkan

aaa
bbb
ccc
ddd

Anda bisa menggunakan perintah

f r<ENTER>;.;.
Yarden Akin
sumber
0

Saya menemukan ini sebagai implementasi paling tepat dari apa yang saya harapkan dari perilaku yang berlawanan J

nnoremap S i<cr><esc>^mwgk:silent! s/\v +$//<cr>:noh<cr>`w

Itu melakukan baris baru yang sederhana pada kursor, menangani spasi kosong apa pun pada baris sebelumnya jika ada, dan kemudian mengembalikan kursor ke posisi yang benar.

i <cr> <esc> - ini adalah salah satu solusi paling umum yang disarankan, tidak menghapus karakter non-spasi di bawah kursor Anda tetapi juga meninggalkan Anda dengan spasi kosong

^mw - Goto start dari baris baru dan buat tanda di bawah w

gk - naik satu baris

:silent! s/\v +$//<cr> - regex mengganti spasi kosong di akhir baris

:noh<cr> - Hapus penelusuran apa pun yang menyorot bahwa regex mungkin telah diaktifkan

`w - kembalikan tanda di bawah w

Pada dasarnya menggabungkan yang terbaik dari keduanya r<esc><cr>dani<cr><esc>

Catatan: Saya memiliki ikatan ini Syang berpotensi menimpa kunci yang berguna tetapi ini adalah sinonim untuk ccdan karena saya tidak menggunakannya sesering yang saya lakukan perpecahan, saya baik-baik saja dengan menimpanya.

JaredMcAteer
sumber
0

o ESC perintah akan melakukannya untuk Anda.

logbasex
sumber
-1

Pemetaan ini akan memecah fungsi satu baris yang Anda miliki. Cukup letakkan kursor Anda di baris dan tekan 'g' dalam mode normal:

:map g ^f{malr<CR>`a%hr<CR>`a

Ini mengasumsikan bahwa Anda memiliki spasi setelah kurung kurawal buka dan spasi sebelum kurung kurawal tutup. Lihat apakah itu berhasil untuk Anda.

Lucas Oman
sumber