Bagaimana cara mengatur Vim agar bekerja dengan satu kalimat per baris?


17

Saat ini saya sedang menulis banyak teks biasa (dan LaTeX dengan format minimal dalam paragraf), dan alangkah baiknya jika saya dapat mengatur vim untuk menjaga setiap kalimat (untuk kesederhanaan, teks diakhiri dengan '.', '!' , atau '?'; itu adalah tanda baca penghentian yang diikuti oleh spasi untuk menghindari pemutusan pada angka desimal) pada barisnya sendiri sehingga VCS diffs akan lebih berguna.

Minimal, saya ingin gqmemformat teks dari:

He lay flat on the brown, pine-needled floor of the forest, his chin on his
folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he
could see the dark of the oiled road winding through the pass. There was a
stream alongside the road and far down the pass he saw a mill beside the
stream and the falling water of the dam, white in the summer sunlight. 

Untuk:

He lay flat on the brown, pine-needled floor of the forest, his chin on his folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he could see the dark of the oiled road winding through the pass.
There was a stream alongside the road and far down the pass he saw a mill beside the stream and the falling water of the dam, white in the summer sunlight.

Tapi alangkah baiknya jika vim juga akan melakukan pemformatan ini saat saya mengetik (seperti halnya dengan reflow bandwidth). Apakah ini mungkin?

Solusi saya saat ini adalah bergabung dengan paragraf J, kemudian jalankan :'<,'>s/\. /.\r/gyang cukup bagus karena ada beberapa tanda seru dan tanda tanya, tetapi akan jauh lebih baik jika saya bisa membuat gq sedikit lebih pintar.

Jawaban:


23

The 'formatexpr'pilihan

Anda dapat mencapai ini menggunakan 'formatexpr'opsi. Dari bantuan:

Ekspresi yang dievaluasi untuk memformat rentang garis untuk operator gq atau pemformatan otomatis (lihat 'formatoptions'). Ketika opsi ini kosong 'formatprg' digunakan.

Pengaturan Anda 'formatexpr'dengan benar akan berfungsi baik saat menggunakan gqdan saat memasukkan teks.

Contoh sederhana

Inilah fungsi VimScript sederhana dan 'formatexpr'nilai terkait yang harus melakukan pekerjaan itu. Saya belum mengujinya di sekitar semua tepi kasus, tetapi bekerja dengan baik untuk tes sederhana saya.

function! MyFormatExpr(start, end)
    silent execute a:start.','.a:end.'s/[.!?]\zs /\r/g'
endfunction

set formatexpr=MyFormatExpr(v:lnum,v:lnum+v:count-1)

Penjelasan

Ekspresi adalah panggilan ke fungsi MyFormatExpr(), melewati garis awal dan akhir di mana format akan diterapkan. Baris-baris ini dihitung menggunakan variabel yang terisi secara otomatis v:lnum(baris pertama yang akan diformat) dan v:count(jumlah baris yang akan diformat).

The MyFormatExpr()Fungsi membangun sebuah :substituteperintah dengan melewati dalam kisaran, dan menggantikan spasi menyusul akhir-of-kalimat tanda baca ( ., !, atau ?) dengan baris baru ( \r).

Peringatan

  • The MyFormatExpr()Fungsi tidak melindungi lekukan terkemuka. Beberapa logika yang lebih canggih akan dibutuhkan untuk memperbaikinya.
  • Mungkin ada kasus tepi lain di mana ini berantakan. Berikan test drive dan atur seperlunya!

Oh, ya ini benar-benar cara untuk pergi, abaikan jawaban saya.
Sukima

Ini luar biasa! Yang saya harap bisa saya lakukan adalah menjalankan fungsi makro, seperti "maju ke kalimat berikutnya )dan masukkan baris baru; ulangi sampai Anda mencapai akhir rentang." Maka itu mungkin akan menerapkan aturan indentasi. Tapi Vim-fu saya terlalu lemah untuk itu. :)
Nathan Long

Ini terbagi misalnya e.g. blah, dan Blah et al. 2018yang sedikit mengganggu. Anda dapat mencocokkan pola seperti itu dengan sesuatu seperti 's/\(e\.g\|\<al\)\@<![.!?]\zs /\r/g'. Cukup tambahkan lebih banyak pola ke grup pertama untuk menghindari hal-hal lain yang tidak ingin Anda bagi. Kalau tidak, ini sangat berguna, terima kasih. Saya belum pernah menemukan gqsebelumnya, dan gqipsangat berguna untuk memformat teks yang telah rusak oleh editor teks rekan penulis.
naught101

Apakah ada cara untuk menambahkan perilaku ini ke perilaku default? Saya ingin dapat membungkus pada lebar teks yang diberikan, serta membelah pada akhir kalimat ..
101

1

Anda dapat mengatur beberapa peta dan perintah otomatis:

function! AddSentenceMaps()
  imap .<Space> .<CR>
  imap !<Space> !<CR>
  imap ?<Space> ?<CR>
  exec "nmap gq vipJ:s/\\([.!?]\\)\\s\\+/\\1\\r/g<CR>"
endfunction

autocmd Filetype customtxt call AddSentenceMaps()

Kemudian cukup atur jenis file ke customtxt atau panggil AddSentenceMapsfungsi secara manual.


0

Saya ingin menambahkan pemikiran saya tentang masalah ini. Biasanya orang menginginkan fitur semacam ini karena melompati garis yang dibungkus ketika orang menavigasi kode dengan jdan kperintah yang merupakan perilaku default Vim. Untuk navigasi melalui garis terbungkus saya gunakan gj- pindah ke bawah dan gk- pindah ke atas. Juga ada kemungkinan remap standar jdan kperintah pada rekan-rekan g-prefixed, tapi IMHO itu akan berlebihan.


atau memiliki kunci untuk melakukan itu membuat kembali dari jdan kke gjdan gkketika Anda menginginkannya ;-)
anthony

0

Itu tidak menjawab pertanyaan spesifik Anda tentang memformat ulang, tetapi 'set wrap' bersama dengan 'set linebreak' dapat membuat mengedit garis panjang jauh lebih menyenangkan. Gabungkan ini dengan gj dan gk untuk bernavigasi di dalam garis yang terbungkus. Saya memetakan panah atas dan bawah ke gj dan gk masing-masing sehingga saya memiliki pilihan antara bergerak ke atas dan ke bawah garis nyata atau garis visual. Suka bijaksana untuk Home / End to g0 / g $.

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.