Czy w Vimie można usunąć bez wpisywania tekstu do rejestru?

470

Korzystając z Vima, często chcę zastąpić blok kodu blokiem, który właśnie szarpnąłem.

Ale kiedy usuwam blok kodu, który ma zostać zastąpiony, sam blok przechodzi do rejestru, który usuwa blok, który właśnie szarpnąłem. Mam więc zwyczaj szarpania, następnie wstawiania, a następnie usuwania tego, czego nie chciałem, ale przy dużych blokach kodu robi się bałagan, próbując zachować wstawiony blok i blok do oddzielenia.

Jaki jest najszybszy i najszybszy sposób na zamianę tekstu w Vimie?

  • czy istnieje sposób na usunięcie tekstu bez umieszczania go w rejestrze?
  • czy można powiedzieć np. „zamień następne słowo” lub „zamień do następnego akapitu”
  • czy jest najlepszym sposobem na skorzystanie z funkcji rejestracji wielu?
Edward Tanguay
źródło
1
vim-easyclip ( github.com/svermeulen/vim-easyclip ) został zaprojektowany, aby rozwiązać dokładnie ten problem
Steve Vermeulen
1
Zadałem pytanie, nieświadomie (w tym czasie), powielając twój rzeczywisty problem , ale nie tyle tytułowego pytania. TL; DR - zamień na to, co szarpałeś za pomocą viwp(dla word).
OJFord

Odpowiedzi:

429

Aby usunąć coś bez zapisywania go w rejestrze, możesz użyć „rejestru czarnej dziury”:

"_d

Oczywiście możesz również użyć dowolnego innego rejestru, który nie zawiera niczego, co Cię interesuje.

Christian Berg
źródło
4
Na początku myślałem, że to polecenie nie działa poprawnie. Potem zdałem sobie sprawę, że używam amerykańskiej klawiatury „martwych klawiszy”. W tym układzie klawiatury muszę pisać "<space>_d. Potrzebne jest miejsce do wpisania „.
Sebastián Grignoli
4
Jakieś pomysły na robienie tego selektywnie tylko na pustych liniach? (Jeśli jestem ddna pustej linii, idzie do czarnej dziury, w przeciwnym razie jest ddto normalne).
Jonathan Dumaine
6
Aby usunąć jedną postać, spróbuj:"_x
kenorb
54
Jest to obszar, w którym wygrywa standardowy edytor tekstu. Po prostu naciśnij klawisz usuwania.
Vince Panuccio,
22
Możesz także szarpać coś za pomocą yy„3yy” (lub cokolwiek innego), co umieszcza go w rejestrze bez nazwy, ale także w 0. Możesz dalej wklejać go "0p, mimo że używałeś go dpóźniej.
Halfgaar,
102

Tak. Jest to nieco bardziej skomplikowane niż usuwanie „starego” tekstu, ale:

Zaczynam od…

line1
line2
line3
line4

old1
old2
old3
old4

I shift+ vzaznaczam wiersz 1, wiersz 2, 3 i 4 i usuwam je za pomocą dpolecenia

Następnie usuwam stare 1-4 wiersze w ten sam sposób.

Więc zrób

"2p

To wklei ostatnie szarpane linie (linia 1-4). "3pzrobi trzecią od ostatniej i tak dalej ...

Skończyło się na tym

line1
line2
line3
line4

Odniesienie: Dokumentacja Vima dotycząca rejestru numerowanego

dbr
źródło
Jeśli wybierzesz linie za pomocą <Shift-v>, usuniesz je tylko d, a nie dd
Heikki Naski
31
Od 1 do 9 działa na usuwanie. Aby wkleić ostatnią naprawdę szarpaną (za pomocą „y”), musisz użyć „0p. Jest to przydatne w przypadkach, gdy najpierw szarpniesz coś, co zamierza zastąpić coś innego, ale potem coś innego zastępuje domyślny rejestr wklejania.
Rafael de F. Ferreira,
Aby uzyskać więcej cofania wyrafinowania wymeldowania z Gundo (Graphical cofania) skryptu .
Lumi
@ RafaeldeF.Ferreira: Twój komentarz nie jest odpowiedzią na to pytanie, ale faktycznie rozwiązuje prawdopodobnie faktyczny problem, który spowodował, że OP postawił pytanie. Dla mnie to był prawdziwy problem.
0xc0de,
76

Dokumenty VIM: Rejestr numerowany 0 zawiera tekst z ostatniego polecenia yank, chyba że polecenie to określiło inny rejestr za pomocą ["x].

Np. Szarpamy „foo” i usuwamy „pasek” - rejestr 0 nadal zawiera „foo”! Dlatego „foo” można wkleić za pomocą"0p

alex2k8
źródło
53

Przydatne jest łatwe mapowanie, które pozwala zastąpić bieżące zaznaczenie buforem.

Na przykład, gdy umieścisz to w swoim .vimrc

vmap r "_dP       // it's a capital 'p' on the end

następnie, po skopiowaniu czegoś do rejestru (tj. za pomocą „y”), możesz po prostu wybrać tekst, który chcesz zastąpić, i po prostu naciśnij „r” na klawiaturze. Wybór zostanie zastąpiony bieżącym rejestrem.

Wyjaśnienie:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste
João Portela
źródło
1
Aby uzyskać bardziej zaawansowaną wersję, sprawdź: stackoverflow.com/questions/290465/…
Luc Hermitte
Chciałbym użyćvmap <C-P> "_dP
Harry Lee
7
Możesz po prostu wstawić tekst bez usuwania zaznaczenia. Na przykład Vpnatychmiast zastępuje bieżącą linię szarpaną.
Bobby Marinoff,
To rozwiązanie nie rozwiązuje problemu, dktóry jest często używany do usuwania.
Victor Yarema
35

W moim vimrc umieszczam:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Teraz szarpię do rejestru schowka i wkładam go i nie muszę się przejmować tym, co dzieje się z rejestrem domyślnym. Dodatkową korzyścią jest to, że mogę wkleić z innych aplikacji przy minimalnym wysiłku. Wiem, że tracę trochę funkcjonalności, ale i tak nie mogę śledzić więcej niż jednego rejestru / schowka.

Magnus
źródło
6
Zamiast tych wszystkich mapowań możesz również set clipboard=unnamedlub set clipboard=unnamedplus, co zmienia domyślny schowek odpowiednio na *lub +.
Steve
5
@ Steve Jeśli to zrobisz, d nadpisze również ostatni szarpnięcie do rejestru schowka, czego właśnie próbuje uniknąć pytanie.
79E09796
1
@ 79E09796, nie chciałem sugerować, że tak; Komentowałem tę odpowiedź, a nie pierwotne pytanie.
Steve
1
Umieściłem je w moim .vimrc i teraz szarpanie nie działa. Masz pomysł, dlaczego?
tba
2
@tba zamień noremap na nnoremap (dwa n) i powinno działać dobrze.
Meain
24

Dla konkretnego przykładu, który podałeś, jeśli rozumiem pytanie, może to działać:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
EBGreen
źródło
6
Działa to dobrze, z wyjątkiem sytuacji, gdy chcesz wkleić wiele zaznaczeń.
23

Wszystkie operacje szarpania i usuwania są zapisywane domyślnie w rejestrze bez nazwy. Jednak ostatnie szarpnięcie i ostatnie usunięcie są zawsze przechowywane (osobno) w ponumerowanych rejestrach. Rejestr 0zawiera ostatni szarpnięcie. Rejestry 1-9zawierają 9 ostatnich usunięć (z1 czym są najnowsze).

Innymi słowy, usunięcie powoduje nadpisanie ostatniego szarpnięcia w rejestrze bez nazwy, ale nadal znajduje się w 0rejestrze. Sztuczka z rejestracją w blackhole ("_ddWspomniany w innych odpowiedziach ) wspomniany w innych odpowiedziach działa, ponieważ zapobiega zastąpieniu rejestru bez nazwy, ale nie jest konieczny.

Odwołujesz się do rejestru, używając podwójnych cudzysłowów, więc wklejanie ostatnio szarpanego tekstu można wykonać w następujący sposób:

"0p

To doskonała referencja:

Wayne
źródło
16

Aby podkreślić to, co powiedział EBGreen :

Jeśli wkleisz podczas zaznaczania tekstu, zaznaczony tekst zostanie zastąpiony wklejonym tekstem.

Jeśli chcesz skopiować tekst, a następnie wkleić go w wielu lokalizacjach, użyj "0pdo wklejenia. Rejestr numerowany 0 zawiera tekst z ostatniego polecenia szarpnięcia.


Możesz także wyświetlić zawartość wszystkich swoich rejestrów:

:registers

To polecenie ułatwia ustalenie , jakiego rejestru chcesz dokonać, robiąc coś w rodzaju odpowiedzi dbr . Zobaczysz także rejestry /,%, #. (Zobacz także :help registers)


Na koniec sprawdź cWi cWzmień słowo, w tym spację i bez spacji. (Korzystanie z kapitału Wobejmuje interpunkcję).

idbrii
źródło
10

Jeśli używasz Vima, będziesz miał tryb wizualny, który przypomina wybieranie, ale z trybami oddzielania, które są podstawą vi / vim.

To, co chcesz zrobić, to użyć trybu wizualnego, aby wybrać źródło, następnie szarpnąć, a następnie użyć trybu wizualnego, aby wybrać zakres miejsca docelowego, a następnie wkleić do tekstu z domyślnego bufora.

Przykład:

W pliku tekstowym z:

1 | qwer
2 | asdf
3 | zxcv
4 | poiu

w następującej kolejności: ggVjyGVkp skończysz na:

1 | qwer
2 | asdf
3 | qewr
4 | asdf

Wyjaśnione:

  • gg: przejdź do pierwszej linii
  • V: uruchom tryb wizualny z całymi liniami
  • j: zejdź o jedną linię w dół (z zaznaczeniem rozpoczętym w poprzednich liniach zwiększa to zaznaczenie o jedną linię w dół)
  • y: szarpnij do domyślnego bufora (dwie wybrane linie i automatycznie wyjdzie z trybu wizualnego)
  • G: przejdź do ostatniej linii
  • V: uruchom tryb wizualny (tak samo jak poprzednio)
  • k: przejdź w górę o jedną linię (jak poprzednio, z włączonym trybem wizualnym, zwiększa to wybór o jedną linię w górę)
  • p: wklej (po zaznaczeniu dwóch ostatnich linii zastąpi te linie tym, co jest w buforze - w tym przypadku 2 pierwsze linie)

Ma to niewielką niedogodność, która umieszcza ostatni blok w buforze, więc w jakiś sposób nie jest pożądane w przypadku wielokrotnego wklejania tej samej rzeczy, więc będziesz chciał zapisać źródło w nazwanym buforze z czymś podobnym "ay(do bufora o nazwie „a ”) i wklej coś podobnego "ap(ale wtedy, gdy programujesz, prawdopodobnie nie chcesz wklejać kilka razy, ale utworzyć funkcję i wywołać ją, prawda? PRAWO ?).

Jeśli używasz tylko vi, będziesz musiał użyć niewidocznych znaków zamiast trybu wizualnego, :he markaby uzyskać więcej informacji na ten temat, przepraszam, ale nie jestem zbyt dobry z tą rzeczą niewidocznych znaków, jestem dość zanieczyszczony trybem wizualnym.

maeghith
źródło
10

Aby zastąpić słowo, spróbuj cww trybie normalnym.

Aby zastąpić akapit, spróbuj capw trybie normalnym.

Swaroop CH
źródło
1
Aby zamienić do następnego akapitu, spróbuj c}w trybie normalnym.
jabirali
Dlaczego „czapka” to robi? Czy „a” i „p” nie oznaczają „dopisz” i „wklej”?
WiSaGaN
2
@WiSaGaN „ap” oznacza „akapit”: vimhelp.appspot.com/motion.txt.html#object-select
Swaroop CH
9

Minimalne rozwiązanie inwazyjne dla leniwych:

Rejestr 0zawsze zawiera ostatnie szarpnięcie (jak już wspominali Rafael , alex2k8 i idbrii ). Niestety wybór rejestru przez 0cały czas może być dość irytujący, więc byłoby miło, gdyby był pużywany "0domyślnie. Można to osiągnąć, umieszczając następujące wiersze w swoim .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

Pierwszy wiersz odwzorowuje każde ppociągnięcie "0p. Uniemożliwia to jednak pdostęp do innych rejestrów. Dlatego wszystkie ppociągnięcia z jawnie wybranym rejestrem są odwzorowywane na równoważne wyrażenie wiersza poleceń w pętli for. To samo zrobiono dla P.

W ten sposób zachowane jest standardowe zachowanie, z wyjątkiem niejawnych pi Pobrysów, które teraz 0domyślnie używają rejestru .

Wskazówka 1: Polecenie cięcia jest teraz "0dzamiast po prostu d. Ale ponieważ jestem leniwy, jest to dla mnie zdecydowanie za długo;) Dlatego używam następującego mapowania:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

Klucz wiodący jest \domyślnie, więc możesz łatwo wycinać tekst, wpisując \dlub \D.

Wskazówka 2: Domyślny limit czasu dla mapowań z wieloma klawiszami jest dość krótki. Możesz go zwiększyć, aby mieć więcej czasu przy wyborze rejestru. Zobacz :help timeoutlenszczegóły, używam:

set timeout timeoutlen=3000 ttimeoutlen=100
Torben
źródło
7

Najpierw wykonaj to polecenie:

:h d

Wtedy zdasz sobie sprawę, że możesz usunąć do określonego rejestru. W ten sposób nie zmienisz zawartości domyślnego rejestru.

EBGreen
źródło
1
["x]d{motion} Delete text that {motion} moves over [into register x]- Vim:h d
Wes Turner,
5

Moja sytuacja: w Normaltrybie, gdy usuwam znaki za pomocą xnaciśnięcia klawisza, te usunięcia nadpisują mój najnowszy rejestr - komplikując zmiany, w których chcę usunąć znaki, używając xi wklejając coś, co mam w moim ostatnim rejestrze (np. Wklejanie tego samego tekstu na dwa lub więcej miejsc).

Wypróbowałem sugestię w zaakceptowanej odpowiedzi ( "_d), ale nie zadziałała.

Jednak z zaakceptowanej odpowiedzi / komentarzy na /vi/122/performing-certain-operations-with-clearing-register dodałem to do mojej ~/.vimrc, która działa (być może będziesz musiał zrestartować Vima ):

nnoremap x "_x

Oznacza to, że mogę teraz wykonywać moje normalne polecenia yank ( y), delete ( d) i paste ( p) - a znaki, które usuwam, xnie wypełniają już najnowszych rejestrów.

Victoria Stuart
źródło
4

Tekst usunięty w trybie wstawiania nie przechodzi do rejestru domyślnego.


źródło
2
ale usuwanie znacznej ilości tekstu w trybie domyślnym jest WOLNE
Hamish Downer
3

Dwa rozwiązania, których używam we właściwych kontekstach, to:

  • zaznacz, co chcesz zastąpić w VISUALtrybie Vims , a następnie wklej rejestr.

Używam tego głównie z przyzwyczajenia, ponieważ drugie rozwiązanie znalazłem znacznie później, np

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Dzięki tej wtyczce możesz użyć skrótu klawiszowego, <ctrl>+<p>aby zastąpić poprzedni numerowany rejestr tym, który właśnie wkleiłeś.

Zasadniczo zaczynasz wklejać, jak chcesz, ale kiedy zdasz sobie sprawę, że od tego czasu nadpisałeś domyślny rejestr, tracąc to, co naprawdę chciałeś wkleić, możesz <C-P> znaleźć i zastąpić historię YankRing!

Jedna z nich musi mieć wtyczki ...

wydalony
źródło
2

W wersji dla systemu Windows (prawdopodobnie także w systemie Linux) możesz przeciągać do bufora kopiowania / wklejania systemu za pomocą "*y(tj. Poprzedzając polecenie yank podwójnymi cudzysłowami i gwiazdką).

Następnie możesz normalnie usunąć wymienne linie i wkleić skopiowany tekst za pomocą "*p.

JayG
źródło
2

Często popełniam błąd, wykonując polecenia „y'ank, a następnie” „usuń” do czarnej dziury, a następnie „p” wklej. Wolę „y”, a następnie usuń, jak mi się podoba, a następnie „0p” z rejestr 0, do którego wypychany jest ostatni skopiowany tekst.

bezradny
źródło
2

W przypadku użytkowników emacs-evil funkcja (evil-paste-pop)może zostać uruchomiona po wklejeniu i przełącza się między poprzednimi wpisami w pierścieniu zabijania. Zakładając, że jest to związane <C-p>(domyślnie w Spacemacs), uderzyłbyś, pa następnie tyle, <C-p>ile potrzeba.

Adrien Vakili
źródło
1

Dla użytkowników Dvoraka jedną bardzo wygodną metodą jest po prostu usunięcie niepotrzebnego tekstu do rejestru „1 zamiast rejestru„ _ czarna dziura ”, choćby dlatego, że można nacisnąć„ + 1 za pomocą tego samego naciśnięcia Shift i szybkiego różowego ruchu, ponieważ 1 jest klawisz bezpośrednio powyżej ”w Dvorak (PLUS d znajduje się w drugiej ręce, co sprawia, że ​​całe polecenie jest szybkie jak diabli).

Oczywiście rejestr „1 może być używany do innych celów ze względu na wygodę, ale chyba że masz cel bardziej powszechny niż zamiana tekstu, powiedziałbym, że to całkiem dobre wykorzystanie rejestru.

Vic Goldfeld
źródło
1

Dla tych, którzy są przede wszystkim zainteresowani nie nadpisywaniem nienazwanego rejestru podczas zastępowania tekstu za pomocą wirtualnego zaznaczania i wklejania.

Możesz użyć następującego rozwiązania, które jest łatwe i działa najlepiej dla mnie:

xnoremap <expr> p 'pgv"'.v:register.'y'

Pochodzi z odpowiedzi (i komentarzy) tutaj: Jak wkleić bez nadpisywania rejestru

Najpierw minie zaznaczenie, a następnie zaznaczenie z nowym tekstem jest ponownie zaznaczane (gv). Teraz rejestr, który był ostatnio używany w trybie wizualnym (zwykle rejestr bez nazwy, ale działa również bez skutków ubocznych, jeśli używasz innego rejestru do wklejania). Następnie ponownie pociągnij nową wartość do rejestru.

PS: Jeśli potrzebujesz prostszego wariantu, który działa również z symulacją vim-pluginu Intellj Idea, możesz wziąć ten (wada: nadpisać nienazwany rejestr, nawet jeśli podano inny rejestr do wklejenia):

vnoremap p pgvy

kłapnięcie
źródło
0

Sporadyczne preferencje Vima dotyczące złożoności nad praktycznością obciążają użytkownika stosowaniem rejestrów do kopiowania / usuwania akcji - gdy częściej niż nie, wystarczy po prostu wkleić to, co zostało skopiowane i „zapomnieć” o tym, co zostało usunięte.

Jednak zamiast walczyć ze skomplikowanymi rejestrami vima, uczyń je wygodniejszymi: wybierz rejestr „domyślny” do przechowywania ostatniego usunięcia. Na przykład wyślij usunięcia do rejestru d (pozostawiając ac otwarte do użytku ad-hoc; d to niezły mnemonik):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Takie podejście zapobiega kasowaniu szarpnięć, ALE nie powoduje utraty rejestracji - można wkleić (cofnąć) to, co zostało usunięte, zamiast stracić je w czarnej dziurze (jak w zaakceptowanej odpowiedzi). W powyższym przykładzie przywołanie odbywa się za pomocą dwóch mapowań linii odniesienia p. Zaletą tego podejścia jest to, że daje on możliwość wybrania, co należy wkleić: (a) co właśnie zostało szarpane lub (b) co właśnie zostało usunięte.

Gregory
źródło
0

zarejestruj od 0 do 9 to najnowsze rzeczy, które szarpiesz lub wycinasz itp., i NIE dołączaj usuniętych rzeczy itp. Więc jeśli szarpiesz / wycinasz coś, jest ono również w rejestrze 0, nawet jeśli przez cały dzień mówisz o usuniętych rzeczach, zarejestruj 0 jest wciąż ostatnią rzeczą, którą szarpałeś / wycinałeś.

yiw # przechodzi zarówno do rejestru domyślnego, jak i do rejestru 0

wyrywa słowo, w którym znajduje się kursor

usunięte rzeczy itp. przejdą do rejestru domyślnego, ale NIE zarejestrują 0

w trybie standardowym:

„0p # wpisz treść rejestru 0

w trybie wstawiania:

ctrl-r 0 # wpisz treść rejestru 0

Miałem też przyjaciela, który zawsze szarpał / wycinał, aby zarejestrować x lol.

kok
źródło