Bagaimana cara membalik urutan baris yang dipilih di Vim?

94

Misalnya, jika saya memiliki empat baris sebagai berikut:

baris pertama baris
kedua baris
ketiga baris
keempat

Saya ingin membalikkannya

baris keempat, baris
ketiga, baris
kedua, baris
pertama

Bagaimana saya bisa melakukan ini di Vim?

Jichao
sumber
1
:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1 vi.stackexchange.com/a/2107/10254
qeatzy

Jawaban:

86

Untuk membalikkan semua baris dalam file,

:g/^/m0

Untuk penjelasan, lihat

:help 12.4

yang juga menunjukkan cara membalikkan hanya serangkaian garis.

garyjohn
sumber
12
Kiat hebat di bagian bantuan yang tepat! Untuk meringkas: 1. mengatur penanda di baris terakhir yang Anda inginkan terbalik (saya beri nama penanda 'a' menggunakan ma), 2. pindahkan kursor ke baris pertama blok, 3. ketik:'a,.g/^/m 'a
Brent Faust
68

Pilih garis yang diinginkan, tekan !, dan pada prompt pipa hasilkan garis melalui taca la :'<,'>!tac. Lihat man tacuntuk lebih jelasnya.

Rhys Ulerich
sumber
4
Untuk memilih garis, gunakan shift+vuntuk masuk ke mode garis visual, lalu juntuk menambahkan garis ke pilihan.
wisbucky
Saya dapat mengkonfirmasi bahwa ini juga berfungsi di windows gvim! Kalau tidak, Anda harus menggunakan angka garis absolut (mungkin Anda dapat menggunakan relatif, tetapi Anda harus berhati-hati) dengan :g/^/m0(yang juga sangat sulit diingat) ... Jadi, pada dasarnya, tac harus dengan vim tidak peduli platform apa pun Anda sedang aktif, TAPI bukan 100% vimscript, TETAPI yang peduli: P
dylnmc
tac tidak sepenuhnya menangani vim asli, tetapi, perintah 'm'ove mengambil nomor baris dan itu tidak selalu masuk akal. Saya sering menggunakan tanda sebagai bagian dari rentang, jadi :.,'a!tacbekerja dengan sedikit usaha.
pejantan
Setelah menggunakan shift+v, Anda dapat menggunakan }untuk mencapai paragraf berikutnya, atau ruang vertikal kosong. Juga man tac: concatenate and print files in reverse,.
nilon
33

Pada Mac OS X, tactidak ada, tetapi Anda dapat menggunakan tail -refek yang sama:

:%!tail -r

Ini juga berfungsi dengan baik untuk mode visual:

:'<,'>!tail -r

Kutipan dari tail(1)halaman manual:

Opsi -r menyebabkan input ditampilkan dalam urutan terbalik, per baris. Selain itu, opsi ini mengubah arti opsi -b, -c dan -n. Ketika opsi -r ditentukan, opsi ini menentukan jumlah byte, baris atau blok 512-byte untuk ditampilkan, bukan byte, baris atau blok dari awal atau akhir input dari mana untuk memulai tampilan. Default untuk opsi -r adalah menampilkan semua input.

Thomas Perl
sumber
3
Luar biasa! Jadi untuk menyediakan 'tac' di bawah OS X:alias tac='tail -r'
Brent Faust
4
Anda juga bisa brew install coreutilsdan menggunakannya gtac.
Andrew Marshall
1
Jenius. Tidak pernah terpikir untuk menggunakan! perintah untuk jenis manipulasi garis visual ini.
Charlie Dalsass
3

Bagi mereka yang lebih nyaman dengan mode Visual:
1. Identifikasi nomor baris di atas pilihan yang ingin Anda gunakan :set nu.
2. Shift-Vuntuk menyorot pilihan yang Anda ingin membalik (mode visual).
3 :g/^/m <Line number from step 1>..

Perhatikan bahwa dalam mode visual itu akan muncul secara otomatis :'<,'>g/^/m <Line number>ketika Anda mengetik perintah dari 3.

Perintah ini berfungsi dengan memindahkan pilihan satu baris sekaligus ke nomor baris yang Anda berikan. Ketika item kedua didorong ke nomor baris yang diberikan, itu mendorong yang pertama turun ke nomor baris + 1. Kemudian yang ketiga mendorong yang pertama dan kedua ke bawah dan seterusnya sampai seluruh daftar telah didorong ke dalam nomor baris tunggal yang menghasilkan daftar terbalik urutan.

horta
sumber
4
Anda dapat menggunakan '<alih - alih memasukkan nomor baris secara manual. Mulailah seleksi satu baris sebelumnya dan jalankan :'<,'>g/^/m'<.
Palec
3

Perintah :Rev[erse]dan pemetaan opsional untuk Anda vimrc, sehingga Anda tidak perlu mengingat dan melakukan langkah-langkah yang tidak jelas dari resep ini:

" Reverse the lines of the whole file or a visually highlighted block.
    " :Rev is a shorter prefix you can use.
    " Adapted from http://tech.groups.yahoo.com/group/vim/message/34305
command! -nargs=0 -bar -range=% Reverse
    \       let save_mark_t = getpos("'t")
    \<bar>      <line2>kt
    \<bar>      exe "<line1>,<line2>g/^/m't"
    \<bar>  call setpos("'t", save_mark_t)

nmap <Leader>r :Reverse<CR>
xmap <Leader>r :Reverse<CR>

( :xmappeta untuk mode Visual tetapi tidak Pilih, seperti yang :help mapmode-xdisarankan untuk memetakan karakter yang dapat dicetak.)

(Berdasarkan: http://tech.groups.yahoo.com/group/vim/message/34305 )

Aaron Thoma
sumber
Ini harus menjadi jawaban yang diterima IMO. Paling bermanfaat dan saya tidak harus ingat :'<,'>g/^/m'<:)
Eliot
1
@Eliot, terima kasih! :) (Saya menambahkan sedikit 'konten bonus'.;))
Aaron Thoma
Bagaimana saya bisa mengatakan seleksi mulai -1 dalam hal ini? Karena langkah dimulai pada titik ini.
SergioAraujo
@SergioAraujo: Seperti :-1,+1Revapa yang Anda cari? Ketahuilah bahwa Anda secara visual dapat memilih jangkauan Anda ingin membalikkan, misalnya: V7j:Rev. Jika itu tidak menjawab pertanyaan Anda, saya belum memahaminya, jadi Anda perlu menjabarkan atau menyusunnya kembali untuk saya.
Aaron Thoma
1

Katakanlah Anda berada di baris 3, maka kami memiliki rentang 3 hingga 6. Cukup ketik.

:3,6g/^/m2
SergioAraujo
sumber
1
Anda dapat membiarkan nomor baris saat ini tersirat: Dengan kursor pada baris pertama rentang Anda, Anda dapat mempersingkat menjadi :,6g/^/m2; atau ketika pada baris terakhir kisaran ini: :3,g/^/m2; dan :3,6g/^/m2bekerja dari mana saja di file.
Aaron Thoma