Czy mogę sprawić, aby Vim zapisał również „małe usunięcia” w rejestrze „1”?

14

Niedawno usunąłem wtyczkę YankRing z mojej konfiguracji częściowo dlatego, że powodowało to pewne problemy z makrami, ale głównie dlatego, że zdecydowałem, że lepiej wytrenować się, aby korzystać z rejestrów Vima - w szczególności sposób, w jaki usunięty tekst jest początkowo zapisywany w rejestrze "1a następnie przesunąć w górę przez "2, "3itd jako kolejne skreślenia są wykonane jest bardzo przydatna.

Jednak gdy usunięcie / zmiana usuwa mniej niż jeden wiersz tekstu, jest on zapisywany w "-małym rejestrze usuwania (z kilkoma wyjątkami dla niektórych poleceń ruchu). Jeśli zostaną wykonane kolejne małe usunięcia, ten fragment tekstu zostanie utracony.

Czy jest możliwe, aby Vim zapisał wszystkie usunięcia w rejestrze "1?

nnoremap d "1d prawie działa, ale kończy się to tekstem w obu rejestrach "1 i "2 .

Nie mam nic przeciwko temu, czy wpłynie to na funkcjonalność małego skasowanego rejestru. Sugerowanie zmiany mojego zachowania, aby zapisać małe skreślenia w nazwanym rejestrze, zdecydowanie nie byłoby pomocną odpowiedzią - właśnie to robię.

Bogaty
źródło

Odpowiedzi:

10

Kiedyś to działało w starszych wersjach Vima 7.3 :set clipboard=unnamed(patrz dyskusja Reddit , w wyniku błędu, który tutaj zgłosiłem) .

Wątek zawiera łatkę autorstwa Aryeh Leib Taurog, która wprowadza 'regone'opcję. To znalazło się na (zbyt długiej) liście rzeczy do zrobienia, ale jest mało prawdopodobne, że zostanie wkrótce włączone. Tak więc obecnie masz tylko opcję przejścia na przestarzały Vim lub sam zbuduj Vima z tą łatką (i poproś o adopcję na liście mailingowej vim_dev ).

Ingo Karkat
źródło
1
Ciekawy! (Zwłaszcza twój pomysł na temat progu.) Dzięki za informację. Na razie wstrzymam się od głosowania / akceptacji, próbując zachęcić kogoś do wymyślenia jakiegoś szalonego VimScript do zrobienia tego w międzyczasie.
Bogaty
5

Mam rozwiązanie sprawdzające koncepcję, które działa dla dpolecenia za pomocą ruchów i w trybie wizualnym. Nie jest to jeszcze w pełni niezawodne rozwiązanie (na przykład d[count]dnie działa i nie działa [count]D), ale prawie obejmuje wszystkie moje rzeczywiste przypadki użycia.

Działa poprzez ustawienie funkcji operatora klienta, która:

  1. przechowuje zawartość rejestrów 1–8 w słowniku,
  2. dokonuje usunięcia do rejestru 1,
  3. ustawia rejestry 2–9 na poprzednio zapisaną zawartość rejestrów 1–8.

Zobacz :help map-operatorwyjaśnienie działania funkcji operatora.

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 
Bogaty
źródło
Przepraszamy za komentowanie starej odpowiedzi. Przyjąłem to rozwiązanie yi, cale dla cmojego nvim nie wchodzi w tryb wstawiania po akcji ... Obecnie muszę execute li startinsertco nie jest poprawną poprawką (jak ustawiłbym c$kursor w niewłaściwej pozycji). Jakieś pomysły?
Sunny Pun