Bisakah saya menggabungkan garis dengan koma (atau karakter lain)?

19

Saya tahu saya dapat bergabung dengan baris dalam Vim dengan Jdan beberapa varian daripadanya ( gJ, dll.); Jakan "Hapus indentasi dan masukkan hingga dua spasi" .

Tetapi apakah ada juga cara mudah untuk memasukkan karakter lain alih-alih dua spasi? Misalnya koma ( ,) atau koma & spasi ( ,)?

Diberikan:

8
9
10
32

Saya ingin mengakhiri dengan:

8, 9, 10, 32

atau:

8,9,10,32
Martin Tournoij
sumber
Anda juga bisa menyukai github.com/sk1418/Join (tidak diuji).
VanLaser

Jawaban:

5

Saya menulis plugin Gabung, dapat melakukan apa yang Anda inginkan, dan banyak lagi.

Kecuali untuk semua fitur yang disediakan oleh perintah built-in: join, Join bisa:

  • Gabung garis dengan pemisah (string)
  • Gabungkan garis dengan atau tanpa memotong spasi putih depan / belakang
  • Gabungkan garis dengan jumlah negatif (gabung mundur)
  • Gabungkan garis secara terbalik
  • Gabung garis dan pertahankan garis yang digabungkan (tanpa menghapus garis yang digabungkan)
  • Gabungkan garis dengan kombinasi opsi apa pun di atas

lebih detail dan tangkapan layar:

https://github.com/sk1418/Join

Kent
sumber
23

Cara sederhana adalah ini: cukup pilih baris Anda (semua kecuali yang terakhir) - atau gunakan %- dan jalankan:

:'<,'>s/\n/,/

atau

:'<,'>s/\n/, /

(di mana, tentu saja, '<,'>bagian itu sudah dimasukkan setelah :oleh Vim, untuk menargetkan pemilihan)


(2) Pembaruan:

Membangun di atas (dan komentar Sato Katsura ), berikut ini kemungkinan implementasi "gabung interaktif", dengan jumlah dan dukungan pengulangan opsional:

" ================ script ===============================================
" interactive 'J', 'gJ' replacement with optional 'vim-repeat' support
" The last used separator is automatically reused as:
" a. default choice
" b. when repeating (=> non-interactive repeats: same range, same separator)
let g:last_join_separator = " "
function! s:interactiveJoin(use_last_sep,...) range
    if (a:use_last_sep == 0) "interactive, ask for separator to use
        call inputsave()
        echohl Question
        let l:sep = input("Separator:", g:last_join_separator)
        echohl None
        call inputrestore()
        redraw!
        let g:last_join_separator = l:sep "update last separator value
    else "non-interactive (when repeating with '.')
        let l:sep = g:last_join_separator
    endif
    if (a:0 == 0) "with no argument, remove indentation *and trailing spaces*
        let l:subst = 's/\s*\n\+\s*/\=' . "'" . l:sep . "'/"
    else " don't remove indentation or trailing spaces (act like 'gJ')
        let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
    endif
    if a:firstline < a:lastline "join given range
        execute a:firstline . ',' . (a:lastline - 1) . l:subst
        let l:count = a:lastline - a:firstline + 1 "default count for repeat
    else "or join only with next line
        execute l:subst
        let l:count = 1 "default count for repeat
    endif
    "make command repeatable
    "(with the tpope/vim-repeat plugin: optional, recommended)
    if (a:0 == 0)
        silent! call repeat#set("\<Plug>(repeatJoin)", l:count)
    else
        silent! call repeat#set("\<Plug>(repeatGJoin)", l:count)
    endif
endfunction

noremap <silent> <Plug>(interactiveJoin)  :call <SID>interactiveJoin(0)<CR>
noremap <silent> <Plug>(interactiveGJoin) :call <SID>interactiveJoin(0,'g')<CR>
noremap <silent> <Plug>(repeatJoin)       :call <SID>interactiveJoin(1)<CR>
noremap <silent> <Plug>(repeatGJoin)      :call <SID>interactiveJoin(1,'g')<CR>

Dan pemetaan aktual:

"================= vimrc ================================================
nmap J <Plug>(interactiveJoin)
xmap J <Plug>(interactiveJoin)
nmap gJ <Plug>(interactiveGJoin)
xmap gJ <Plug>(interactiveGJoin)

Ini agak (*) seperti J, tetapi interaktif - ini akan meminta string pemisah. String default adalah spasi - jadi, misalnya, untuk bergabung dengan garis tanpa pemisah, tekan Backspacesaat diminta, untuk menghapus karakter spasi default, dan Enteruntuk menerima pemisah kosong (sekarang). Hitung, misalnya 3J, juga berfungsi. Jika tpope/vim-repeatplugin diinstal, ulangi dengan '.' juga akan berfungsi, menggunakan kembali pemisah terakhir dan (jika tidak diubah - mis. 10.) hitungan terakhir atau rentang garis visual.


(*) Ini tidak persis seperti J, meskipun: sementara itu akan menghapus lekukan, itu tidak akan memeriksa .!?(akhir frase) untuk memasukkan 2 spasi, bukan satu, atau menyisipkan spasi hanya jika itu hilang (sulit untuk melakukan sesuatu seperti ini, karena string pemisah dapat berupa apa saja sekarang). Ini juga akan menghapus spasi tambahan (lebih masuk akal).

Saya pikir ini mungkin cara yang bagus untuk membebani ruang surat operator yang terbatas :)

Yah, secara teknis Jbukan operator, tetapi dekat dengan satu - misalnya, Anda tidak dapat melakukan Jaw, untuk bergabung dengan "sepatah kata".

(saran dipersilahkan)

masukkan deskripsi gambar di sini

VanLaser
sumber
2
Lebih baik lagi: :'<,'>-1s/\n/, /untuk baris yang ditandai, atau :1,$-1s/\n/, /untuk seluruh file.
Sato Katsura
Memang, itu lebih baik :)
VanLaser
@SatoKatsura dapatkah Anda menjelaskannya -1?
alxndr
1
@alxndr - ini digunakan untuk melewati baris terakhir dalam rentang / file: misalnya dalam contoh OP, Anda tidak ingin koma setelah 32, dan Anda juga tidak ingin bergabung dengan baris berikutnya, jika ada . Anda bahkan dapat menggunakan '<,'>-s/\n/, /atau 1,$-s/\n/, /sebagai -sama dengan -1.
VanLaser
1
Jika l:sepadalah &, maka penggantian Anda akan bekerja secara salah, karena &ajaib dalam penggantian. Mungkin lebih baik menggunakan \=menggunakan string literal - let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"- daripada mencoba menangani melarikan diri.
jamessan
3

Berikut ini contoh menggunakan perintah eksternal:

:%!paste -sd,

di mana %!menggantikan buffer saat ini (konten file) dengan perintah: paste -sd,(parameter -sdigunakan untuk bergabung dengan beberapa baris dan -dmengatur karakter pembatas ,).

kenorb
sumber
3

Hanya dalam kasus seseorang tidak suka mengetik Regex dan menghafal lebih banyak Perintah Ex Plugin:

Visual-block Append

Visual-block Append tersedia dalam mode Visual Block ( <C-v>) dan dapat melakukan blok A ppend (dan block I nsert for prepend). (ref: :help v_b_A, :help v_b_I)

Dan jika gerakan terakhir dalam Block Visual Mode adalah $, append akan dilakukan di akhir semua pilihan; atau spasi akan dimasukkan sebelum teks yang Anda tambahkan (bayangkan menyelaraskan penutupan )di akhir beberapa panggilan metode dalam kode).

Dengan contoh teks di bawah ini dan kursor aktif 8:

8
9
10
12

<C-v>}$A,<C-c>. Setelah kembali ke mode normal, kita dapat melihat ,ditambahkan ke semua baris yang dipilih. (Coba tanpa $)

Kemudian lakukan gvuntuk memilih kembali area dan Jatau gJ. Kami memiliki jejak ,: 8,9,10,12,dan $xkami selesai.

Gunakan Sisipan untuk Tidak Membuntuti ,

Mari batalkan teks kita (baik itu uu..umewah :ea 1d<cr>:lat 1), dan coba Visual Sisipkan:

j<C-v>}I, <C-c>dan kemudian kita bisa bergabung dengan garis gJtanpa spasi.

Tunggu tunggu tunggu, ada yang hilang. Bagaimana cara memilih ulang seluruh "array"? Kali ini kami tidak memilih baris pertama ... jadi gvtidak membantu.

- Atau mungkin membantu, gvokpilih kembali ( gv), osudut pposite dan katas.

PS saya pinky tidak cepat dan cukup akurat untuk mengetik /\untuk /\n, jadi saya seperti menggabungkan Vim built-in operasi dan gerakan untuk menghindari menggunakan Regex. Namun jika saya cukup sering melakukan ini, menggunakan pemetaan - mungkin yang memetakan ke plugin harus lebih baik.

Sunny Pun
sumber
1

Cara yang jauh lebih sederhana tanpa plugin atau perintah eksternal untuk memetakan kembali join ( J) dari sebuah ruang ke karakter apa pun yang Anda suka. Misalnya, untuk bergabung dengan koma dan spasi:

:nmap J :s/\n/, /^M

Untuk baris baru karakter khusus di akhir ( ^M) tekan Ctrl-Vdan kemudian Kembali / Enter. Sama halnya jika Anda ingin mengganti dengan tab ( ^I), ketik Ctrl-Ikemudian Tab.

:nmap J :s/\n/^I/^M

Apa yang dilakukan adalah mengganti baris baru dengan tab pada baris saat ini dan memetakan kembali perilaku itu ke karakter J.

Ini juga berfungsi dengan kombinasi, seperti 4Juntuk bergabung dengan 4 baris berikutnya.

Mode Wes
sumber
0

Anda dapat merekam makro untuk bergabung dengan garis dengan koma. Ini berguna jika ini adalah tugas yang jarang atau sekali saja, dan Anda tidak dapat mengingat bagaimana menulis perintah pengganti dan ekspresi reguler untuk melakukan tugas tersebut, tetapi Anda ingat bagaimana cara merekam dan menjalankan makro.

Untuk bergabung dengan baris dengan koma, ketik qjgJi,Escquntuk merekam makro dalam register j. Kemudian Anda dapat menjalankan makro dengan @j. Anda dapat menjalankan kembali makro dengan @@, yang menghemat saat mengetik ketika menjalankannya beberapa kali berturut-turut — Anda bahkan dapat menahannya @hingga mendekati akhir baris yang ingin Anda gabungkan. Anda juga dapat menggunakan awalan angka @jatau @@mengulanginya beberapa kali. Ini membiarkan spasi terdepan dan tertinggal, jadi akan ada spasi sebelum atau setelah koma jika teks asli Anda memiliki spasi di sana.

Untuk bergabung dengan koma dan spasi, masukkan Spaceantara ,dan Escsaat merekam makro.

Anda juga dapat menggunakan Jalih-alih gJsaat merekam makro, yang biasanya akan bergabung dengan baris dengan koma dan spasi. Namun, jika baris saat ini memiliki spasi spasi, koma akan muncul setelah spasi tanpa spasi mengikutinya. Juga, tidak termasuk ruang jika baris berikutnya dimulai dengan ), dan menempatkan dua spasi setelah koma jika joinspacesdiatur dan garis ujung saat ini dengan ., !atau ?. Peringatan ini dijelaskan di bawah :help J.

Lithis
sumber