Emacs: jak usunąć tekst bez pierścienia zabijania?

81

Chciałbym po prostu usunąć jakiś tekst, aby zamiast niego wyszarpnąć inny tekst . Jak mogę to zrobić? Cw wycina zaznaczony tekst, aby zabić pierścień, i kończy się bez tekstu, który chciałem szarpnąć.

Czy można też bezpośrednio szarpać tekst zamiast jakiegoś tekstu bez naciskania przycisków, aby go zabić?

mannicken
źródło
2
zapoznaj się z moją odpowiedzią poniżej, możesz użyć przycisku Backspace na klawiaturze przy pierwszym pytaniu, zaznacz tekst na drugim pytaniu
Kevin Zhu
Czy to nie jest po prostu Cx rk po zdefiniowaniu bloku?
yalu2015

Odpowiedzi:

49

Piszę M-x delete-regiondość często, ale można to powiązać z klawiszem.

Dzięki trybowi usuwania zaznaczenia w nowszych wersjach Emacsa nie musisz wpisywać polecenia, po prostu zacznij pisać:

Domyślnie wstawianie tekstu następuje normalnie, nawet jeśli znak jest aktywny - na przykład wpisanie znaku „a” powoduje wstawienie znaku „a”, a następnie dezaktywację znaku. Tryb Usuń zaznaczenie, tryb pomocniczy, modyfikuje to zachowanie: jeśli włączysz ten tryb, wstawienie tekstu, gdy znacznik jest aktywny, spowoduje najpierw usunięcie tekstu w regionie. Ponadto polecenia, które zwykle usuwają tylko jeden znak, na przykład C-dlub DEL, usuwają zamiast tego cały region. Aby włączyć lub wyłączyć tryb usuwania zaznaczenia, wpiszM-x delete-selection-mode.

Ashawley
źródło
33
Ponadto, z najnowszą wersją Emacsa, nie musisz nawet łączyć delete-regionsię z klawiszem, ponieważ Backspace robi to teraz. Backspace usuwa wybrany region zamiast go zabijać, innymi słowy, Backspace usuwa zaznaczony tekst bez zapisywania / wypychania go do pierścienia zabijania. Dzieje się tak, ponieważ wartość delete-active-regionjest równa, tchyba że dostosujesz ją do innej wartości.
Jisang Yoo
36

Możesz użyć M-yafter, C-yaby wstawić poprzedni przedmiot z pierścienia zabijania lub użyć pakietu Browse-kill-ring .

Jeśli chodzi o drugie pytanie, zobacz DeleteSelectionMode .

Eugene Morozov
źródło
21

Miałem ten sam problem. Najbliższą rzeczą, jaką udało mi się do tej pory, jest po prostu utworzenie małej funkcji, która zasadniczo:

(defun ruthlessly-kill-line ()
  "Deletes a line, but does not put it in the kill-ring. (kinda)"
  (interactive)
  (move-beginning-of-line 1)
  (kill-line 1)
  (setq kill-ring (cdr kill-ring)))
Haakon Løtveit
źródło
1
Dlaczego nie po prostu (delete-region (line-start-position) (line-end-position))?
CodyChan
Wymieniona funkcja brzmiała dobrze, ale generalnie nie działała. W szczególności odkryłem, że spowodowałoby to, że wskaźnik szarpania wskazywałby drugi koniec pierścienia zabijania, który generalnie (właściwie prawie zawsze?) Nie jest kolejnym elementem na liście! (Stll próbuje włamać się do funkcji, która działa niezawodnie przez delegację do `kill-linii” ... może będę po prostu uciekają do usunięcia-region jak inni zrobili ...)
pnkfelix
11

Zaczerpnięte z EmacsWiki :

Odpowiednik ‘kill-line’( ‘C-k’), ale bez efektów ubocznych pierścienia zabijania:

(delete-region (point) (line-end-position))
John J. Camilleri
źródło
Najlepsza odpowiedź IMO. I powiązałem ctrl-shift-W, aby usunąć region: (global-set-key (kbd "CSw") 'delete-region)
Tongfa
5

MX eval-expression (setq kill-ring (cdr kill-ring)) - usuwa ostatni przedmiot z kill-ring

Evgeny
źródło
Dziwnie robi to tylko dla bieżącej sesji. Poza emacsem nie jest usuwany z pierścienia zabijania!
PascalVKooten
4

Jeśli chodzi o twoje drugie pytanie, alternatywnie do DeleteSelectionMode możesz włączyć tryb CUA, który dodatkowo daje ci ładny tryb wyboru prostokąta włączony przez C-Return. Tryb CUA jest częścią emacsa od 22.1.

danielpoe
źródło
3

Znalazłem odpowiedź na to.

Opublikowałem go jako pierwszy tutaj .

;; Ctrl-K with no kill
(defun delete-line-no-kill ()
  (interactive)
  (delete-region
   (point)
   (save-excursion (move-end-of-line 1) (point)))
 (delete-char 1)
)
(global-set-key (kbd "C-k") 'delete-line-no-kill)
Ole
źródło
Problem polega na tym, że to polecenie zawsze usuwa również znak nowej linii, podczas gdy kill-line usuwa znak nowej linii tylko wtedy, gdy wartość zmiennej kill-whole-line jest różna od zera. Lepiej byłoby zmienić „(usuń znak 1)” na „(jeśli zabij całą linię (usuń znak 1))”.
Alan
3

Większość funkcji zabijania używa kill-regiondo wykonywania rzeczywistej pracy zabijania tekstu. Używam makra lisp do tworzenia funkcji usuwania z funkcji kill.

(defmacro jpk/delete-instead-of-kill (&rest body)
  "Replaces `kill-region' with `delete-region' in BODY."
  `(cl-letf (((symbol-function 'kill-region)
              (lambda (beg end &optional yank-handler)
                (delete-region beg end))))
     ,@body))

(defun jpk/delete-word (arg)
  "Like `kill-word', but does not save to the `kill-ring'."
  (interactive "*p")
  (jpk/delete-instead-of-kill (kill-word arg)))
jpkotta
źródło
Jak to działa? Czy masz więcej informacji na ten temat? To jest niesamowite.
sinekonata
1
cl-letfmoże tworzyć lokalne powiązanie funkcji z zakresem dynamicznym. Oznacza to, że obowiązuje tylko dla kodu wewnątrz cl-letf, ale odnosi się do całego drzewa wywołań (np. kill-regionNie pojawia się bezpośrednio w body, ale kill-wordwywołuje kill-regioni jest zastępowane przez delete-region).
jpkotta
Możesz nawet wywołać oryginalną funkcję z jej zamiany, jeśli najpierw powiążesz ją z inną nazwą w cl-letf. cl-letfdziała tak jak let*w tym sensie.
jpkotta
Rozumiem sedno, nadal jest to dla mnie zbyt techniczne. Ledwo mam średniozaawansowane doświadczenie z Pythonem. Jaka jest ogólna nazwa funkcji „nadpisywania” / przepisywania / rozwidlania? Czy jest to specyficzna cecha języków takich jak seplenienie?
sinekonata
Nie jestem do końca pewien, jaka jest ogólna nazwa tej techniki. Myślę, że opisałbym to jako dynamiczny zakres funkcji i nie jest powszechny w większości języków, ponieważ może być bardzo łatwy do nadużycia. Emacs powoli przechodzi do zakresu leksykalnego, którego używa większość języków. Nie jestem pewien, czy możesz to zrobić w Pythonie w ogóle, musiałbyś zaprojektować swój kod, aby umożliwić przesłanianie funkcji w określonym zakresie.
jpkotta
2

Technicznie rzecz biorąc, inne odpowiedzi są błędne w pierwszej części.

Oto moja realizacja i motywacja:

(defun delete-word (arg)
  "Delete characters backward until encountering the beginning of a word.
With argument ARG, do this that many times."
  (interactive "p")
  (delete-region (point) (progn (backward-word arg) (point))))

Zaadaptowałem tutaj kod z „ kill-word” w simple.el. Przeszedłem kill-regionz delete-regioni forward-worddo backward-word. W ten sposób PRAWDZIWIE nie wpływa to na kill-ring, w przeciwieństwie do innych sytuacji, w których poza emacsem zauważyłem, że kill-ringbył pod wpływem.

PascalVKooten
źródło
2
Wolę tę odpowiedź, ponieważ nie schrzanię wklejania ze schowka systemu operacyjnego (gdzie upuszczenie ostatniej rzeczy z pierścienia zabijania nie pomaga, ponieważ to, co jest w schowku systemu operacyjnego, zostało utracone)
Brel
Sprawdź moją odpowiedź, aby dowiedzieć się, jak to zrobić bez kopiowania definicji funkcji kill.
jpkotta
1
(defun copy-to-register-z (p1 p2)
  "Copy text selection to register named “z”."
  (interactive "r")
  (copy-to-register ?z p1 p2))
(defun replace-register-content-z (p1 p2)
  "Replace register named “z”'s content."
  (interactive "r")
  (delete-region p1 p2)
  (insert-register ?z))
(global-set-key (kbd "C-c c") 'copy-to-register-z)
(global-set-key (kbd "C-c v") 'replace-register-content-z)
ZBeginner
źródło
Podoba mi się to, ale ponieważ nie używam trybu znaczników przejściowych, wolę "insert-register-content-z" ze wszystkimi liniami oprócz usuwania regionu.
Joshua Goldberg
1

Dodaj odpowiednik usuwania kluczy regionu zabicia i linii zabicia Cw i Ck w następujący sposób. Związany z klawiszami Cv i Cz.

;; Przypisanie klawisza do usuwania regionu daje dobry „odpowiednik Windows CUT Ctrl-x”.
;; Wybór przypisania klawiszy jest trudny do wyboru.
;; użycie Cv "Windows WKLEJ Ctrl-v" jest dość wywrotową opcją.
;; Cv = przewiń w górę w emacs, do którego nie mam pożytku.
(global-set-key (kbd "Cv") 'usuń-region)

;; Aby mieć również alternatywę „Windows CUT” dla Ck (linia zabicia), można to zrobić:
(defun delete-line () "usuń linię, wyjmij ją z pierścienia zabijania. powiąż tę funkcję z Cz"
 (interaktywny)
 (setq last-command 'delete-line)
 (linia zabicia)
 (setq kill-ring (cdr kill-ring))
 (setq kill-ring-yank-pointer-ring-pointer)
 (setq last-command 'delete-line)
)
(global-set-key (kbd "Cz") 'delete-line)
;; bez ustawiania ostatniej komendy 2+ C-zs psują zabójczy pierścień
James Coleman
źródło
1

Moja odpowiedź na pierwsze pytanie: zaznacz tekst w emacs (używając myszki lub set mark C-SPC) i naciśnij przycisk "<- Backspace" na klawiaturze zamiast C-w. W ten sposób nadal możesz wkleić tekst w schowku systemowym, bez obawy, że schowek został zastąpiony przez tekst zabity przezC-w

Tło dla tej odpowiedzi: czasami, gdy otrzymałem tekst poza emacsem, którego chcę użyć do zastąpienia regionu w emacsie, często popełniałem błąd, najpierw kopiując ten tekst do schowka systemowego (np. W systemie Windows Ctrl + C), a następnie robiąc C-ww emacsie „ usuń "region tekstu, który chcę zastąpić, z nadzieją, że później będzie M-wmógł odzyskać mój tekst w schowku z zabójczego pierścienia. Niestety schowek zostałby po prostu zastąpiony tekstem zabitym przezC-w , a oryginalna wiadomość w schowku nigdy nie byłaby wyświetlana w pierścieniu zabijania.

Drugie pytanie brzmi: tak, zawsze możesz najpierw zaznaczyć tekst w emacsie, a potem bezpośrednio C-y

Kevin Zhu
źródło
0

Oto wersja kill-region, która nie wymusza wartości w pierścieniu zabijania.

(defun kill-or-delete-region (beg end prefix)
  "Delete the region, storing it in the kill-ring.
If a prefix argument is given, don't change the kill-ring."
  (interactive "r\nP")
  (if prefix
      (delete-region beg end)
    (kill-region beg end)))

(global-set-key (kbd "C-w") 'kill-or-delete-region)

Dzięki temu możesz zrobić to C-wjak poprzednio, ale C-u C-wteraz usuwa tekst bez zmiany pierścienia zabijania.

Wilfred Hughes
źródło
0

jak usunąć tekst bez zabicia pierścienia?

delete-regionfunkcja usunie wybrany obszar bez dodawania go do ringu kill

Czy można też bezpośrednio szarpać tekst zamiast jakiegoś tekstu bez naciskania przycisków, aby go zabić?

Myślę, że pytasz, jak zastąpić tekst w wybranym regionie czymś, co już umieściłeś na pierścieniu zabijania.

Ustawienie (delete-selection-mode 1)pozwoli ci na szarpanie / wklejanie w wybranym regionie. Pozwala również na wpisanie i zastąpienie wybranego regionu.

W wersji 25.1.1 na OS XI również musiałem dodać, (setq select-enable-primary nil)aby zapobiec kopiowaniu wybranego regionu do pierścienia zabijania

kevincasey
źródło
0

Jako uzupełnienie wszystkich odpowiedzi. Jeśli napiszesz kod elisp do usunięcia, możesz wywoływać funkcje, które zabijają, o ile używasz lokalnego obiektu pierścienia zabijania, takiego jak ten:

(defun delete-something()
  "Delete something without storing in kill ring."
  (let (kill-ring)
     (kill-something)))

Użyj dowolnej funkcji, która coś zabije zamiast zabicia czegoś. Funkcja zostanie usunięta i nic nie zostanie zapamiętane w prawdziwym pierścieniu zabijania.

PRouleau
źródło