Bisakah saya membuat Vim juga menyimpan "penghapusan kecil" ke dalam register "1?

14

Saya baru-baru ini menghapus plugin YankRing dari pengaturan saya sebagian karena itu menyebabkan beberapa masalah dengan makro, tetapi kebanyakan karena saya memutuskan akan lebih baik untuk melatih diri saya sendiri untuk menggunakan register Vim - khususnya, cara teks yang dihapus disimpan pada awalnya di register. "1dan kemudian bergeser melalui "2, "3, dll sebagai penghapusan lanjut yang dibuat sangat berguna.

Namun, ketika penghapusan / perubahan menghapus kurang dari satu baris teks, alih-alih disimpan dalam "-register penghapusan kecil (dengan beberapa pengecualian untuk perintah gerakan tertentu). Jika penghapusan kecil berikutnya dilakukan, potongan teks itu hilang.

Apakah mungkin untuk membuat Vim menyimpan semua penghapusan dalam daftar "1?

nnoremap d "1d hampir berfungsi, tetapi Anda berakhir dengan teks di kedua register "1 dan "2 .

Saya tidak keberatan apakah fungsi register hapus yang kecil terpengaruh atau tidak. Menyarankan saya mengubah perilaku saya untuk menyimpan penghapusan kecil ke register bernama pasti tidak akan menjadi jawaban yang membantu - itulah yang saya lakukan saat ini.

Kaya
sumber

Jawaban:

10

Ini digunakan untuk bekerja dalam versi Vim 7.3 yang lebih lama ketika Anda :set clipboard=unnamed(lihat diskusi Reddit ini , sebagai akibat dari bug, yang saya laporkan di sini .

Utas itu berisi tambalan oleh Aryeh Leib Taurog yang memperkenalkan 'regone'opsi. Ini telah membuatnya menjadi daftar todo (terlalu panjang), tetapi tidak mungkin untuk dimasukkan segera. Jadi, saat ini Anda hanya memiliki opsi untuk menurunkan versi ke Vim yang sudah ketinggalan zaman, atau membuat Vim sendiri dengan tambalan itu (dan mendorong untuk diadopsi pada milis vim_dev ).

Ingo Karkat
sumber
1
Menarik! (Terutama idemu tentang ambang batas.) Terima kasih atas informasinya. Akan menunda upvote / menerima untuk sementara waktu dalam upaya untuk mendorong seseorang untuk datang dengan beberapa VimScript gila untuk melakukan ini untuk sementara.
Rich
5

Saya punya solusi proof-of-concept yang berfungsi untuk dperintah dengan gerakan dan dalam mode visual. Ini belum merupakan solusi yang sepenuhnya kuat (misalnya, d[count]dtidak berfungsi , dan tidak juga [count]D), tetapi hampir mencakup semua kasus penggunaan aktual saya.

Ini bekerja dengan menetapkan fungsi operator pelanggan yang:

  1. menyimpan isi register 1–8 dalam kamus,
  2. melakukan penghapusan ke dalam register 1,
  3. set register 2-9 ke isi register yang disimpan sebelumnya 1-8.

Lihat :help map-operatorpenjelasan tentang cara kerja fungsi operator.

function! ShiftingDeleteOperator(type)
  let reg_dict = {}
  for k in range(1, 8)
    execute printf("let reg_dict[%d]=getreg('%d', 1)", k, k)
  endfor

  if a:type ==# 'v'
    execute 'normal! `<v`>d'
  elseif a:type ==# 'V'
    execute 'normal! `<V`>d'
  elseif a:type ==# "\<C-V>"
    execute "normal! `<\<C-V>`>d"
  elseif a:type ==# 'char'
    execute 'normal! `[v`]d'
  elseif a:type ==# 'line'
    execute "normal! '[V']d"
  else
    return
  endif

  let deleted = getreg('"', 1)
  call setreg(1, deleted)

  for [k, v] in items(reg_dict)
    execute printf("call setreg(%d, v)", k + 1)
  endfor
endfunction

" Call the function for d{motion} via operatorfunc
nnoremap <silent> d :set operatorfunc=ShiftingDeleteOperator<CR>g@
" Call the function when d or x are hit in visual mode
vnoremap d :<C-U>call ShiftingDeleteOperator(visualmode())<CR>
vnoremap x :<C-U>call ShiftingDeleteOperator(visualmode())<CR>
" Use the d{motion} as defined above to add limited support for `D` command
nmap D d$
" Use the standard dd command
nnoremap dd dd 
Kaya
sumber
Maaf telah mengomentari jawaban lama. Saya mengadopsi solusi ini untuk ydan ctetapi untuk cnvim saya tidak masuk ke mode memasukkan setelah tindakan ... Saat ini saya harus execute ldan startinsertyang bukan perbaikan yang tepat (seperti c$akan meletakkan kursor di posisi yang salah). Ada ide?
Sunny Pun