Emacs: як видалити текст без kill ring?


81

Я хотів би просто видалити якийсь текст, щоб я міг вирвати якийсь інший текст замість нього. Як я можу це зробити? Cw вирізає виділений текст, щоб убити кільце, і я опиняюся без тексту, який я хотів рвати.

Крім того, чи можна рвати текст безпосередньо замість якогось тексту, навіть не натискаючи кнопки, щоб убити його?


Дивіться також: stackoverflow.com/questions/5823495 / ...
Филс

2
зверніться до моєї відповіді нижче, ви можете використовувати клавішу Backspace на клавіатурі для 1-го питання, позначити текст для 2-го питання
Kevin Zhu

Чи не просто Cx rk після того, як ви визначили свій блок?
yalu2015

Відповіді:


49

Я набираю M-x delete-regionдосить часто, але ви можете прив’язати його до ключа.

У режимі « Видалити виділення» в нових версіях Emacs не потрібно вводити команду, просто починайте вводити:

За замовчуванням вставка тексту відбувається зазвичай, навіть якщо позначка активна - наприклад, введення символу "a" вводить символ, а деактивує позначку. Режим видалення виділення, другорядний режим, змінює таку поведінку: якщо ви вмикаєте цей режим, тоді вставлення тексту, коли позначка активна, спочатку видаляє текст у регіоні. Крім того, команди, які зазвичай видаляють лише один символ, наприклад, C-dабо DEL, замість цього видаляють всю область. Щоб увімкнути або вимкнути режим «Видалити виділення», введітьM-x delete-selection-mode.


33
Крім того, з останньою версією Emacs вам навіть не потрібно прив'язувати delete-regionключ, оскільки Backspace робить це зараз. Backspace видаляє вибрану область, а не вбиває її, іншими словами, Backspace стирає виділений текст, не зберігаючи / не натискаючи його на кільце вбивства. Це тому, що значення delete-active-regionє, tякщо ви не налаштуєте його на якесь інше значення.
Jisang Yoo


21

У мене була та сама проблема. Найближче, що я отримав на даний момент, це просто зробити невелику функцію, яка по суті:

(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
Чому не просто (регіон видалення (лінія-початок-позиція) (лінія-кінець-позиція))?
CodyChan

Перелічена функція звучала добре, але в цілому для мене не працювала. Зокрема, я виявив, що це призведе до того, що покажчик yank вказуватиме на інший кінець кільця вбивств, що загалом (насправді майже завжди?) Не є наступним елементом у списку! (Stll намагається зламати функцію, яка надійно працює через делегування на `` kill-line '' ... можливо, я просто
вданусь

11

Взято з EmacsWiki :

Еквівалент ‘kill-line’( ‘C-k’), але без побічних ефектів кільцевих кілець:

(delete-region (point) (line-end-position))

Найкраща відповідь IMO. І я зв’язав ctrl-shift-W, щоб видалити регіон: (global-set-key (kbd "CSw") 'delete-region)
Tongfa,

5

Mx eval-expression (setq kill-ring (cdr kill-ring)) - видаляє останній елемент із kill-ring


Це лише дивно для поточної сесії. Поза emacs він не знімається з кільця вбивства!
PascalVKooten

4

Для вашого другого питання, як варіант DeleteSelectionMode, ви можете ввімкнути режим CUA, який додатково надає вам гарний режим вибору прямокутника, увімкнений C-Return. Режим CUA є частиною emacs з 22.1.


3

Знайшов відповідь на це.

Опублікував його спочатку тут .

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

Проблема полягає в тому, що ця команда завжди також видаляє новий рядок, тоді як рядок вбивства видаляє новий рядок лише в тому випадку, якщо значення змінної kill-whole-line не дорівнює нулю. Краще було б змінити "(delete-char 1)" на "(if kill-whole-line (delete-char 1))".
Алан

3

Більшість функцій вбивства використовують kill-regionдля фактичної роботи з вбивства тексту. Я використовую макрос lisp для створення функцій видалення з функцій 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)))

Як це працює? Чи маєте Ви більше інформації щодо цього? Це дивно.
sinekonata

1
cl-letfможе створити локальне прив'язування функції з динамічним обсягом. Це означає, що він діє лише для коду всередині cl-letf, але він застосовується до всього дерева викликів (наприклад kill-region, не відображається безпосередньо в body, але kill-wordвикликає, kill-regionі це замінено на delete-region).
jpkotta

Ви навіть можете викликати оригінальну функцію з її заміни, якщо спочатку прив'язати її до іншого імені в cl-letf. cl-letfпрацює як let*у цьому сенсі.
jpkotta

Я зрозумів суть цього, він все ще занадто технічний для мене. Я ледве маю проміжний досвід роботи з python. Яка загальна назва цієї функції "перезапису" / перезапису / розгалуження? Це специфічна особливість таких мов, як lisp?
sinekonata

Я не зовсім впевнений, що загальна назва цієї техніки. Думаю, я б описав це як динамічну сферу функцій, і це не є поширеним явищем у більшості мов, оскільки ним дуже легко зловживати. Emacs повільно переходить до лексичного обсягу, яким користується більшість мов. Я не впевнений, що ви можете це зробити в Python загалом, вам доведеться розробити свій код, щоб дозволити перевизначення функції в певній області.
jpkotta

2

Технічно, інші відповіді помилкові з першої частини.

Ось моє впровадження та мотивація:

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

Я адаптував код тут з " kill-word" в simple.el. Я перейшов kill-regionз delete-regionі forward-wordна backward-word. Таким чином це ВІСНОВНО не впливає на kill-ring, на відміну від інших ситуацій, коли поза emacs я помітив, що на kill-ringце вплинуло.


2
Я віддаю перевагу цій відповіді, оскільки вона не псує вставлення з буфера обміну ОС (де випадання останньої речі з кільця вбивства не допомагає, оскільки те, що є в буфері обміну ОС, втрачено)
Брел,

Перевірте мою відповідь, як це зробити, не копіюючи визначення функції 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)

Мені це подобається, але оскільки я не використовую режим перехідних позначок, я віддаю перевагу "insert-register-content-z" з усіма рядками, окрім видалення-області.
Джошуа Голдберг,

1

Додайте еквівалент видалення клавіш Cw та Ck в області вбивства та лінії вбивства, як показано нижче. Прив'язаний до клавіш Cv і Cz.

;; Прив'язка клавіш до області видалення дає хороший "еквівалент Windows CUT Ctrl-x".
;; Яке сполучення клавіш використовувати незручно вибирати.
;; використання Cv "Windows PASTE Ctrl-v" є цілком підривним варіантом.
;; Cv = прокрутка вгору в emacs, який мені не потрібен.
(global-set-key (kbd "Cv") 'регіон видалення)

;; Щоб також мати альтернативу "CUT для Windows" Ck (лінія вбивства), це можна зробити:
(defun delete-line () "видалити рядок, вийняти його з кільця вбивства. прив'язати цю функцію до Cz"
 (інтерактивний)
 (setq last-command 'delete-line)
 (лінія вбивства)
 (setq кільце вбивства (вбивство CDR))
 (setq kill-ring-yank-pointer kill-ring)
 (setq last-command 'delete-line)
)
(global-set-key (kbd "Cz") 'рядок видалення)
;; без налаштування останньої команди 2+ C-zs зіпсувати кільце вбивства

1

Моя відповідь на перше запитання: позначте текст у emacs (за допомогою миші або встановленої позначки C-SPC) і натисніть клавішу "<- Backspace" на клавіатурі замість C-w. Таким чином, ви все ще можете вставляти текст у системний буфер обміну, не турбуючись про те, що буфер обміну замінений вбитим текстомC-w

Передумови для цієї відповіді: іноді коли я отримував текст за межами emacs, який я хочу використовувати для заміни регіону в emacs, я часто робив помилку, спершу скопіювавши цей текст у системний буфер обміну (тобто в Windows Ctrl + C), а потім роблячи C-wв emacs до " видалити "область тексту, яку я хочу замінити, з надією, що пізніше M-wможна буде відновити мій текст у буфері обміну з kill-ring. На жаль, буфер обміну буде просто замінений текстом, убитим C-w, а оригінальне повідомлення в буфері обміну ніколи не відображатиметься в кільці вбивства.

Для 2-го питання, так, ви завжди можете спочатку позначити текст у emacs, а потім безпосередньо C-y


0

Ось версія kill-region, яка не нав'язує значення в кільце вбивства.

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

Це дозволяє робити так C-wсамо, як і раніше, але C-u C-wтепер видаляє текст, не змінюючи кільця вбивства.


0

як видалити текст без вбивства кільця?

delete-regionфункція видалить обрану область без додавання його в список знищень

Крім того, чи можна рвати текст безпосередньо замість якогось тексту, навіть не натискаючи кнопки, щоб убити його?

Думаю, ви запитуєте, як замінити текст у вибраній області чимось, що ви вже наділи на кільце вбивства.

Налаштування (delete-selection-mode 1)дозволить вам перетягувати / вставляти вибраний регіон. Це також дозволяє просто ввести та замінити вибраний регіон.

У версії 25.1.1 на OS XI також довелося додати, (setq select-enable-primary nil)щоб запобігти копіюванню вибраної області на кільце вбивства


0

Як доповнення до всіх відповідей. Якщо ви пишете код elisp для видалення, ви можете викликати функції, які вбивають, якщо ви використовуєте локальний об'єкт кільця вбивства, як це:

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

Використовуйте будь-яку функцію, яка вбиває щось замість цього. Потім функція буде видалена, і в справжньому кільці вбивства нічого не запам'ятається.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.