Bagaimana cara menghitung kata-kata di bagian file, tanpa meninggalkan vim?

10

Saya memiliki file yang penuh teks (mis. Markdown atau LaTeX). Saya ingin menghitung jumlah kata di bagian file ini.

Saya tahu saya bisa lakukan :! wc -w %untuk menjalankan wc -w pada buffer saat ini. Dan saya tahu bahwa saya dapat menarik bagian yang menarik ke dalam register bernama. Saya menduga ada cara untuk mengirim register bernama ke sistem operasi untuk digunakan dalam perintah atau pipa, tetapi saya belum dapat menemukannya. Atau adakah cara yang lebih baik untuk menghitung kata-kata dalam register?

Kasus penggunaan saya adalah bahwa saya melakukan banyak penulisan non-pemrograman (catatan, tesis, dll) dalam vim, dan saya ingin menghitung berapa banyak kata yang telah saya tambahkan ke bagian file tertentu di tengah pengeditan sidang.

Colin McFaul
sumber

Jawaban:

16

Anda dapat menggunakan gCTRL+g, yang akan memberi Anda:

Col 1 of 118-121; Line 1 of 5; Word 1 of 142; Byte 1 of 678

Anda juga dapat menggunakan ini dari mode visual, jika Anda ingin mendapatkan jumlah kata hanya untuk pemilihan, yang sangat berguna dikombinasikan dengan objek teks seperti ip. (mis. Anda dapat menggunakan vipg<C-g>untuk mendapatkan jumlah kata dari paragraf saat ini).

Lihat: :help word-countdan :help text-objects.


Opsi di atas mungkin lebih baik, tetapi Anda juga dapat menggunakan wcutilitas untuk menghitung jumlah kata dalam suatu bagian. Selain dari :! wc -w %formulir yang Anda gunakan, Anda juga dapat menggunakan :%!wc -w. Ini akan memfilter gerakan ke alat shell (dalam hal ini %, seluruh buffer), tetapi Anda juga dapat menggunakan rentang lain (seperti :1,5!wc -wuntuk 5 baris pertama, !,+5!wc -wuntuk 5 baris saat ini dan berikutnya, dll.). Anda juga dapat memilih teks dalam mode visual, dan mengetik :!wc -wuntuk memfilter pilihan Anda.

Perhatikan bahwa ini akan menggantikan gerakan dengan output dari alat shell, tetapi Anda dapat umembatalkannya.

Lihat :help :range!,, :help rangedan jawaban ini tempat saya memberikan lebih banyak contoh rentang.

Martin Tournoij
sumber
Saya telah menemukan sesuatu seperti ini saat mencari, tetapi melewatkan bahwa g pertama adalah bagian dari perintah penghitungan, bukan penentu lokasi. Solusi ini masuk akal sekarang. Saya juga harus membaca mode Visual; Saya tidak cukup sering menggunakannya.
Colin McFaul
1
Saya tidak tahu Anda bisa menggunakan g<C-g>cara itu. Luar biasa!
EvergreenTree
3

Ada dua cara ini dapat dicapai, cara penulisan naskah murni dan wccara.

Cara vim murni

Anda dapat menggunakan perintah pencarian dan ganti untuk melakukan ini. Sebagai contoh:

:%s/\<\w\{-}\>//gn

Apa yang dilakukan adalah alih-alih mengganti pola yang diberikan dengan sesuatu, itu hanya menghitung kemunculan pola tersebut. Ini karena nbenderanya. Untuk menghitung kata-kata di bagian tertentu (dalam hal ini baris 5 hingga 15), Anda dapat melakukan sesuatu seperti ini:

:5,15s/\<\w\{-}\>//gn

Ini menghilangkan kebutuhan untuk menarik konten pilihan ke dalam register. Untuk melihat lebih banyak kemungkinan untuk apa yang dapat dilakukan 5-15, baca topik bantuan untuk cmdline-ranges. Jika Anda ingin sering melakukan ini, mungkin baik untuk membuat pemetaan (atau perintah) untuk itu. Juga, jika Anda telah hlsearchmengaktifkan, Anda mungkin ingin menjalankan :nohlsearchsesudahnya untuk menghapus sorotan.

The wccara

Hal yang sama dapat dicapai wc. Dengan cara yang sama Anda dapat menggunakan cmdline-rangesuntuk memilih area dengan :sperintah, Anda dapat menggunakannya dengan perintah eksternal. Sebagai contoh:

:5,15!wc -w

Ini menjalankan baris 5 hingga 15 melalui wcperintah. Kelemahan dari ini adalah bahwa ia mengganti rentang garis dengan output dari perintah. Anda dapat membatalkan perubahan ini dengan menekan u. Perhatikan juga bahwa solusi vimscript mungkin tidak berfungsi dengan bahasa yang berbeda, karena \wtidak cocok dengan apa yang biasanya menjadi karakter kata dalam bahasa lain. wcmungkin lebih baik dalam hal ini daripada \w. Juga, ini adalah perintah mewah untuk membuatnya lebih cepat untuk melakukan ini:

command -range=% -addr=lines WordCount execute '<count>!wc -w' | .y a | undo | echo @a

Perhatikan bahwa ini akan menghalangi aregister.

Catatan

Tampaknya ini juga dapat dilakukan dalam mode visual dengan g<C-g>kombinasi tombol. Lihat jawaban Carpetsmoker untuk penjelasannya.

Pohon cemara
sumber
Ini perlu bersamaan dengan n untuk menjadikannya global (jika tidak, mereka hanya cocok dengan satu kata per baris). Yang kedua juga membutuhkan huruf s di awal.
Colin McFaul
1
Memperbaiki, maaf soal itu.
EvergreenTree
1
Menggunakan \wsuara seperti ide bagus pada awalnya, tapi setelah pengujian itu saya menemukan sejumlah masalah. Yang terbesar adalah bahwa itu tidak akan cocok dengan karakter non-ascii, jadi kata seperti überhanya dilewati (ada pertanyaan tentang ini kemarin). Juga, kata seperti e-maildihitung sebagai 2 kata, karena -tidak ada dalam \w(menggunakan -agak jarang dalam bahasa Inggris, tetapi sangat umum di Belanda misalnya). Mungkin ada karakter lain yang diabaikan dalam mode ini, yang membawa kita ke poin terakhir saya: konvensi tentang apa yang dianggap sebagai "kata" mungkin berbeda ...
Martin Tournoij
... dalam berbagai bahasa, dan alat "layak" seperti wcdapat mengambil di tempat (saya tidak tahu apakah GNU wcbenar-benar berurusan dengan ini, alat GNU tidak terkenal dengan dukungan unicode mereka yang luar biasa).
Martin Tournoij
Itu menarik. Saya mungkin menambahkan itu sebagai nilai tambah untuk wcsolusi.
EvergreenTree
1

Untuk kata-kata gunakan:

:.,+4 s/\i\+/&/gn

. menunjukkan garis saat ini.

Saya juga memasukkan yang berikut ini di file .vimrc saya:

:cabbrev zzcc   s/./&/gn

:cabbrev zzcw   s/\i\+/&/g

Saya bisa mengetik:

:.,+6 zzcw

dan zzcwakan berkembang menjadis/\i\+/&/g

Itu zzcwhanya nama aneh yang tidak cocok dengan apa pun (untuk saya).

Efek sampingnya adalah seluruh file dipilih dan disorot.

Saya ingin dapat mengetik tweet multi-baris dalam sebuah file, memastikan tidak ada terlalu banyak karakter, dan menempelkan tweet di twitter.

Elemanman
sumber