Kann ich Vim auch dazu bringen, "kleine Löschungen" in Register "1 zu speichern?

14

Ich habe kürzlich das YankRing-Plugin aus meinem Setup entfernt, teilweise, weil es Probleme mit Makros verursacht hat, aber hauptsächlich, weil ich beschlossen habe, mich besser darin zu üben, stattdessen Vims Register zu verwenden - insbesondere die Art und Weise, wie gelöschter Text anfänglich im Register gespeichert wird "1und dann durch usw. nach oben verschoben werden "2, "3wenn weitere Löschungen vorgenommen werden, ist sehr nützlich.

Wenn eine Löschung / Änderung jedoch weniger als eine Textzeile entfernt, wird sie stattdessen im "-kleinen Löschregister gespeichert (mit einigen Ausnahmen für bestimmte Bewegungsbefehle). Wenn nachfolgende kleine Löschungen vorgenommen werden, geht dieses Textstück verloren.

Ist es möglich, Vim zu veranlassen, alle Löschungen im Register zu speichern "1?

nnoremap d "1d fast funktioniert, aber Sie landen mit dem Text in beiden Registern "1 und "2 .

Es macht mir nichts aus, ob die Funktionalität des kleinen Löschregisters betroffen ist oder nicht. Das Vorschlagen, ich ändere mein Verhalten, um kleine Löschungen in einem benannten Register zu speichern, wäre definitiv keine hilfreiche Antwort - das ist, was ich gerade tue.

Reich
quelle

Antworten:

10

Dies funktionierte früher in älteren Vim 7.3-Versionen, wenn Sie :set clipboard=unnamed(siehe diese Reddit-Diskussion als Ergebnis eines Fehlers, den ich hier gemeldet habe) .

Dieser Thread enthält einen Patch von Aryeh Leib Taurog, der eine 'regone'Option vorstellt . Dies hat es in die (zu lange) ToDo-Liste geschafft, aber es ist unwahrscheinlich, dass es bald aufgenommen wird. Daher haben Sie derzeit nur die Möglichkeit, ein Downgrade auf ein veraltetes Vim durchzuführen oder Vim selbst mit diesem Patch zu erstellen (und auf die Übernahme in die Mailingliste vim_dev zu drängen ).

Ingo Karkat
quelle
1
Interessant! (Vor allem deine Vorstellung von der Schwelle.) Danke für die Info. Ich werde das Upvote vorerst abwarten / akzeptieren, um jemanden zu ermutigen, sich in der Zwischenzeit ein verrücktes VimScript dafür auszudenken.
Rich
5

Ich habe eine Proof-of-Concept-Lösung, die für den dBefehl mit Bewegungen und im visuellen Modus funktioniert . Es ist noch keine vollständig robuste Lösung ( d[count]dfunktioniert beispielsweise nicht und funktioniert auch nicht [count]D), deckt jedoch nahezu alle meine tatsächlichen Anwendungsfälle ab.

Es funktioniert, indem eine Kundenoperatorfunktion eingestellt wird, die:

  1. speichert den Inhalt der Register 1–8 in einem Wörterbuch,
  2. führt die Löschung in Register 1 durch,
  3. Setzt die Register 2–9 auf den zuvor gespeicherten Inhalt der Register 1–8.

In finden Sie :help map-operatoreine Erklärung zur Funktionsweise der Bedienerfunktionen.

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 
Reich
quelle
Entschuldigung, dass Sie eine alte Antwort kommentiert haben. Ich adoptierte diese Lösung yund caber für cmeinen NVIM nicht Einfügemodus nach der Aktion eintritt ... Zur Zeit muß ich execute lund startinsertdas ist keine richtige Korrektur (wie Sie c$die Cursor in der falschen Position bringen würde). Irgendwelche Ideen?
Sunny Pun