Puis-je faire en sorte que Vim enregistre également les "petites suppressions" dans le registre "1?

14

J'ai récemment supprimé le plugin YankRing de ma configuration en partie parce qu'il causait des problèmes avec les macros, mais surtout parce que j'ai décidé qu'il serait préférable de me former à utiliser les registres de Vim à la place - en particulier, la façon dont le texte supprimé est stocké initialement dans le registre "1puis déplacé vers le haut à travers "2, "3etc. que d' autres suppressions sont faites est très utile.

Cependant, lorsqu'une suppression / modification supprime moins d'une ligne de texte, elle est plutôt stockée dans le "-petit registre de suppression (à quelques exceptions près pour certaines commandes de mouvement). Si de petites suppressions ultérieures sont effectuées, ce morceau de texte est perdu.

Est-il possible d'obtenir Vim pour stocker toutes les suppressions dans le registre "1?

nnoremap d "1d fonctionne presque , mais vous vous retrouvez avec le texte dans les deux registres "1 et "2 .

Cela ne me dérange pas si la fonctionnalité du petit registre de suppression est affectée ou non. Suggérer que je change mon comportement pour enregistrer de petites suppressions dans un registre nommé ne serait certainement pas une réponse utile - c'est ce que je fais actuellement.

Riches
la source

Réponses:

10

Cela fonctionnait dans les anciennes versions de Vim 7.3 lorsque vous :set clipboard=unnamed(consultez cette discussion sur Reddit , à la suite d'un bogue, que j'ai signalé ici .

Ce fil contient un patch par Aryeh Leib Taurog qui introduit une 'regone'option. Cela a fait partie de la liste des tâches (trop longue), mais il est peu probable qu'elle soit incorporée bientôt. Donc, vous n'avez actuellement que la possibilité de rétrograder vers un Vim obsolète, ou de créer Vim vous-même avec ce correctif (et de pousser pour adoption sur la liste de diffusion vim_dev ).

Ingo Karkat
la source
1
Intéressant! (Surtout votre idée du seuil.) Merci pour l'info. Je vais suspendre le vote positif / accepter pour le moment afin d'essayer d'encourager quelqu'un à proposer un VimScript fou pour le faire dans l'intervalle.
Rich
5

J'ai une solution de preuve de concept qui fonctionne pour la dcommande avec des mouvements et en mode visuel. Ce n'est pas encore une solution entièrement robuste (par exemple, d[count]dne fonctionne pas , et non plus [count]D), mais elle couvre presque tous mes cas d'utilisation réels.

Il fonctionne en définissant une fonction d'opérateur client qui:

  1. stocke le contenu des registres 1 à 8 dans un dictionnaire,
  2. effectue la suppression dans le registre 1,
  3. définit les registres 2–9 sur le contenu précédemment enregistré des registres 1–8.

Voir :help map-operatorpour une explication du fonctionnement des fonctions de l'opérateur.

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 
Riches
la source
Désolé d'avoir commenté une ancienne réponse. J'ai adopté cette solution pour yet cmais pour cmon nvim ne passe pas en mode insertion après l'action ... Actuellement, je dois le faire execute let startinsertce n'est pas un correctif correct (comme c$placer le curseur dans la mauvaise position). Des idées?
Sunny Pun