Bagaimana cara memasukkan teks berulang dengan sedikit perbedaan dalam vim?


11

Saya ingin memasukkan teks seperti ini:

similar text wordA similar text ...
similar text wordB similar text ...
similar text wordC similar text ...

Saya tahu saya dapat menempelkan teks berkali-kali kemudian menggunakan subtitusi untuk mengubah satu kata untuk setiap baris, namun saya masih menemukan metode ini sangat tidak nyaman.

Apakah ada cara untuk menyimpan kata atau daftar kata ke dalam "variabel" kemudian menggunakan variabel ini untuk menghasilkan teks yang serupa?


EDIT Saya membuat sesuatu yang tidak jelas dalam pertanyaan asli, sebenarnya saya mencoba untuk membuat beberapa definisi fungsi yang sangat mirip, jadi wordA wordB... mungkin muncul berkali-kali di setiap klon teks dan teks mungkin berisi banyak baris. polanya persis seperti ini:

similar_text1 wordA similar_text2 wordA similar_text3 ...
similar_text1 wordB similar_text2 wordB similar_text3 ...
similar_text1 wordC similar_text2 wordC similar_text3 ...

(teks dapat berisi baris baru, dan wordA, wordB ... mungkin ada berkali-kali)


EDIT ke-2 Bagian "similar_text" mungkin berbeda setiap kali saya melakukan pekerjaan seperti itu, jadi solusi untuk pekerjaan ini lebih baik untuk digunakan kembali. Karena saya mencoba membuat definisi fungsi yang sangat mirip, atau string ke tabel pemetaan fungsi.

Setelah membaca jawaban dan beberapa latihan, saya menemukan bahwa lebih nyaman untuk menganggap pekerjaan ini sebagai semacam penggantian, karena memisahkan "part1", "part2" ... "partN" yang mungkin berisi baris baru sulit untuk ditulis, jadi tulis templat dulu:

similar_text1 $WORD similar_text2 $WORD similar_text3 ...
(text may contain <ENTER>, make sure $WORD not exist in "similar_text" parts )

Kemudian mencoba untuk menempatkan klon teks tetapi mengganti $ WORD dengan daftar kata-kata adalah pemikiran yang lebih lurus.

Jadi sepertinya masalah saya berubah menjadi "bagaimana mengkloning blok teks berkali-kali, tetapi setiap kali dengan mengganti kata kunci di dalamnya dengan kata dari daftar?"


Itu sebabnya register digunakan untuk. Anda dapat menarik (menyalin) teks ke register dan kemudian menggunakan register itu. Macro dapat digunakan untuk melakukan tugas yang sama serta berulang.
SibiCoder

Jawaban:


7

Anda dapat menggunakan fungsi berikut:

function! GenerateLines()
    let firstpart="similar text part 1"
    let secondpart="similar text part 2"

    let words=["wordA","wordB","wordC","wordD","wordE"]

    for word in words
        let line = firstpart . word . secondpart
        call append(line('.')+1, line)
        normal j
    endfor
endfunction

Dalam variabel firstpartdan secondpartmenempatkan teks untuk mengulangi sebelum dan sesudah kata-kata dan dalam daftar wordsmasukkan kata-kata yang harus diubah.

Kemudian loop akan membuat konten baris untuk setiap kata dalam daftar, masukkan baris dalam buffer dan pergi ke baris baru ini.

Anda kemudian dapat hanya memanggil fungsi: call GenerateLines().


Edit Untuk membuatnya lebih mudah untuk memanipulasi Anda juga dapat melewati bagian yang berbeda sebagai argumen, fungsinya akan terlihat seperti ini:

function! GenerateLines(firstpart, secondpart, words)
    for word in a:words
        call append(line('.')+1, a:firstpart . word . a:secondpart)
        normal j
    endfor
endfunction

Dan Anda bisa menyebutnya seperti ini:

call GenerateLines("first part", "second part", ["wordA","wordB","wordC","wordD","wordE"])

Anda dapat menghindari loop dengan call map(a:words, 'a:firstpart . v:val . a:secondpart')dan call append(line('.'), a:words).
Antony

Karena saya sering mengedit seperti itu dengan "bagian pertama" dan "bagian kedua" yang sangat panjang, bahkan "bagian ketiga", dan bagian-bagian ini mungkin berisi baris baru, sepertinya terlalu lama untuk mengetik sebanyak itu dalam mode perintah, jadi mungkin itu lebih nyaman untuk menarik teks ke register, lalu gunakan fungsi untuk menghasilkan teks dari register?
social_loser

Saya mengedit pertanyaan, itu banyak berubah, maaf atas ketidaknyamanan ini.
social_loser

5

Strategi saya dalam kasus seperti itu akan bervariasi, tetapi sering kali mengikuti langkah-langkah berikut:

  1. Tulis kata unik, mis

    wordA
    wordB
    ...
    wordK
    
  2. Antara

    a) melakukan pencarian dan ganti, mis

    :%s/\w\+/similar text \0 similar text .../
    

    b) atau menggunakan mode blok visual, lihat :h blockwise-visual. Secara khusus, saya akan memilih kata-kata dan menggunakan Iuntuk memasukkan teks yang sama di depan, atau Auntuk menambahkan teks yang serupa setelah.

Saya berpendapat bahwa strategi ini masuk akal ketika Anda melakukan tugas mengedit semacam ini relatif jarang. Namun, jika Anda merasa perlu sering melakukan ini, maka Anda harus mengikuti saran @ statox dengan fungsi yang memperluas daftar kata-kata.


Saya pikir solusinya tergantung dari mana daftar kata itu berasal. Jika itu dari file, maka :readdiikuti dengan substitusi Anda sangat masuk akal.
Antony

solusi Anda mudah dilakukan dan menyelesaikan masalah yang saya tanyakan dalam pertanyaan awal dengan mudah. Namun ada beberapa kesalahan dalam posting asli saya, saya membuat 2 suntingan dan itu banyak berubah, terima kasih atas jawabannya, maaf untuk bahasa Inggris saya yang berubah dan buruk :)
social_loser

@social_loser Anda dapat mengadaptasi solusi ini dengan menggunakan "\ r" untuk membela baris baru di bagian pengganti substitusi
frangio

2

Saya akan berpendapat bahwa ini adalah pekerjaan untuk blok visual ( Ctrl+ v). Pertama saya akan menulis semua kata yang berbeda:

wordA
wordB
wordC
wordD
wordE

Dimulai dengan kursor pada hari pertama wsaya akan melakukan:

<c-v>5j$yA <esc>pA <esc>p

Saya dapat mengontrol berapa kolom yang saya butuhkan dengan menekan A <esc>psebanyak yang saya inginkan. Mari kita asumsikan bahwa saya membutuhkan tiga kolom seperti perintah di atas. Sekarang kita punya ini:

wordA wordA wordA
wordB wordB wordB
wordC wordC wordC
wordD wordD wordD
wordE wordE wordE

Dan kursor berada di awal ke-3 wordAdi baris pertama. Selanjutnya saya akan memblokir pilih kolom spasi di antara kolom yang mundur dan menambahkan teks di antaranya. Dari lokasi kursor saat ini:

h<c-v>5jI similar text 3<esc>

Ini menghasilkan (% menandai posisi kursor):

wordA wordA%similar text 3 wordA
wordB wordB similar text 3 wordB
wordC wordC similar text 3 wordC
wordD wordD similar text 3 wordD
wordE wordE similar text 3 wordE

Ulangi untuk kolom berikutnya:

bh<c-v>5jI similar text 2<esc>

Dan kolom terakhir / pertama (yang ada di sebelah kiri):

b<c-v>5jIsimilar text 1 <esc>

Akhirnya menghasilkan:

similar text 1 wordA similar text 2 wordA similar text 3 wordA
similar text 1 wordB similar text 2 wordB similar text 3 wordB
similar text 1 wordC similar text 2 wordC similar text 3 wordC
similar text 1 wordD similar text 2 wordD similar text 3 wordD
similar text 1 wordE similar text 2 wordE similar text 3 wordE

Pembaruan: menambahkan screencast

masukkan deskripsi gambar di sini


Ini tampaknya banyak mengetik tetapi sebenarnya sangat mudah untuk terbiasa. Ini memberi Anda kebebasan untuk mengubah jumlah kata, jumlah kolom dan bahkan jarak antar kolom.

Kekurangannya adalah Anda perlu mengetahui jumlah kata berbeda yang Anda gunakan. Saya memiliki 5hardcoded di semua perintah di atas karena itu adalah jumlah baris perintah yang beroperasi.

Catatan debugging: semua perintah mulai dan berakhir dalam mode normal, jika Anda menemukan diri Anda dalam mode visual atau menyisipkan di akhir perintah Anda melakukan sesuatu yang salah.

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.