Bagaimana cara saya mengurutkan beberapa blok teks dengan baris pertama di setiap blok di Vim?

11

Saya memiliki beberapa blok teks, atau dengan kata lain, beberapa fungsi seperti ini:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

Saya ingin mengurutkan fungsi berdasarkan abjad dengan tanda tangan fungsi. Bagaimana ini bisa paling mudah dilakukan di Vim?

Hubro
sumber
Tolong jelaskan apa yang Anda maksud dengan tanda tangan fungsi. Apa jenis fungsi ini? Juga, pada platform apa Anda bekerja di bawah OS, distribusi, dan nomor versi akan SANGAT membantu.
mdpc
1
mengapa ini harus dilakukan di VIM? ada beberapa utilitas bawaan unix / linux yang dapat dengan mudah dirangkai bersama untuk hal-hal semacam ini .... awk datang ke pikiran.
mdpc
@ mdpc: Dengan fungsi tanda tangan yang saya maksud adalah baris yang berisi def .... Saya menggunakan Linux, jadi semua utilitas itu akan bekerja untuk saya.
Hubro

Jawaban:

12

Ini relatif sederhana (dan, saya percaya, dekat dengan apa yang ada dalam pikiran Jason):

  1. ubah semua fungsi Anda menjadi satu liner dengan mengganti semua baris baru dengan beberapa karakter mewah:

    :g/def/,/end/s/\n/§
    
  2. urutkan satu kalimat dengan:

    :%sort
    
  3. perluas semua fungsi Anda kembali ke status individual awal mereka:

    :g/def/s/§/\r
    
romainl
sumber
1
Demikian pula, jika garis kosong dapat dianggap sebagai pemisah yang unik, maka itu bisa dilakukan dengan :g/./,/^$/-s/\n/§/g, dan kemudian :%sort, dan kemudians/§/\r/g
ArtBIT
3

Saya telah menulis plugin AdvancedSorters untuk menyederhanakan tiga langkah terpisah yang diberikan dalam jawaban @ romainl menjadi satu perintah:

:SortRangesByRange /^def\>/,/^end\>\_s*\zs$/

Pola di sini sedikit lebih rumit untuk memasukkan garis kosong yang memisahkan dengan benar.

Ingo Karkat
sumber
Catatan: Saat ini Anda membutuhkan Vim 7.4.218 yang cukup baru untuk itu; Saya akan segera memberikan pembaruan yang juga mendukung versi Vim yang lebih lama.
Ingo Karkat
2

Cara terbaik yang dapat saya pikirkan untuk melakukan ini tanpa menulis fungsi yang mem-parsing definisi, adalah dengan mengganti pembatas garis yang tidak didahului oleh endpembatas unik lainnya (+ EOL +?), Dan kemudian :sort, dan mengganti pembatas garis. Mungkin bisa direkam ke makro.

Namun, fungsi mungkin lebih baik, jika Anda ingin menggunakan pemilihan visual.

Jason
sumber
2

Coba plugin vissort. Ini mendukung fasilitas penyortiran blok:

  • : '<'> BS nextblock endblock findtag tagpat tagsub
  • : [range] call BlockSort (nextblock, endblock, findtag, tagpat, tagsub)

Jika ada argumen yang hilang, BlockSort () akan meminta Anda untuk mereka. Pola nextblock / endblock membatasi blok, pola findtag digunakan untuk menemukan garis yang berisi "tag" yang akan digunakan untuk menyortir; tagpat dan tabsub digunakan sebagai pengganti untuk mengekstrak tag pengurutan dari baris yang mengandung tag.

Anda dapat memperoleh vissort.vim dari http://www.drchip.org/astronaut/vim/index.html#VISSORT

pengguna21497
sumber