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ć?



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.


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


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)))

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))

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


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.


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)

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)))

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.


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)

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ń

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


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.


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


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.