ChatGPT解决这个技术问题 Extra ChatGPT

Emacs:如何在没有杀环的情况下删除文本?

我只想删除一些文本,这样我就可以拉出一些其他文本来代替它。我怎样才能做到这一点? Cw 剪切选定的文本以杀死环,我最终没有想要拉出的文本。

此外,是否可以直接拉文本而不是某些文本,甚至无需按下按钮来杀死它?

请参阅下面我的回答,您可以使用键盘上的 Backspace 按钮进行第一个问题,标记文本为第二个问题
定义块后不只是 Cx rk 吗?

a
ashawley

我经常输入 M-x delete-region,但您可以将它绑定到一个键。

在较新版本的 Emacs 中使用 Delete Selection Mode,您不必键入命令,只需开始键入:

默认情况下,即使标记处于活动状态,文本插入也会正常进行 - 例如,键入 a 会插入字符“a”,然后停用标记。删除选择模式(一种次要模式)会修改此行为:如果启用该模式,则在标记处于活动状态时插入文本会导致该区域中的文本首先被删除。此外,通常只删除一个字符的命令(例如 Cd 或 DEL)将改为删除整个区域。要打开或关闭删除选择模式,请键入 Mx delete-selection-mode。


此外,使用最新版本的 Emacs,您甚至不需要将 delete-region 绑定到一个键,因为 Backspace 现在可以做到这一点。 Backspace 删除所选区域而不是杀死它,换句话说,Backspace 删除所选文本而不将其保存/推送到 kill ring。这是因为 delete-active-region 的值是 t,除非您将其自定义为其他值。
E
Eugene Morozov

您可以在 C-y 之后使用 M-y 插入来自 kill ring 的上一个项目,或使用 browse-kill-ring 包。

至于第二个问题,见DeleteSelectionMode


H
Haakon Løtveit

我有同样的问题。到目前为止,我所做的最接近的事情就是制作一个本质上是这样的小功能:

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

为什么不只是 (delete-region (line-beginning-position) (line-end-position))?
列出的功能听起来不错,但总的来说对我不起作用。特别是,我发现它会导致 yank 指针指向 kill-ring 的另一端,通常(实际上几乎总是?)不是列表中的下一个元素! (仍然试图破解一个通过委派到“kill-line”可靠工作的功能......也许我会像其他人一样诉诸删除区域......)
J
John J. Camilleri

取自 EmacsWiki

相当于 'kill-line' ('C-k') 但没有 kill-ring 副作用: (delete-region (point) (line-end-position))


最佳答案海事组织。我绑定 ctrl-shift-W 删除区域: (global-set-key (kbd "CSw") 'delete-region)
E
Evgeny

Mx eval-expression (setq kill-ring (cdr kill-ring)) - 从 kill-ring 中删除最后一项


奇怪的是,它仅对当前会话执行此操作。在 emacs 之外,它不会从 kill ring 中删除!
d
danielpoe

对于第二个问题,除了 DeleteSelectionMode,您可以启用 CUA Mode,它还为您提供了一个由 C-Return 启用的漂亮的矩形选择模式。 CUA 模式是自 22.1 以来 emacs 的一部分。


j
jpkotta

大多数终止函数使用 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)))

它是如何工作的?你有更多这方面的信息吗?这真太了不起了。
cl-letf 可以创建具有动态范围的函数的本地绑定。这意味着它仅对 cl-letf 内的代码有效,但它适用于整个调用树(例如 kill-region 不直接出现在 body 中,但 kill-word 调用 kill-region 并替换为delete-region)。
如果您首先将其绑定到 cl-letf 中的不同名称,您甚至可以从其替换中调用原始函数。在这个意义上,cl-letf 的工作方式与 let* 类似。
我明白了它的要点,它对我来说仍然太技术性了。我几乎没有使用 python 的中级经验。这个“覆盖”/重写/分叉函数的通用名称是什么?它是像 lisp 这样的语言的特定功能吗?
我不确定这种技术的通用名称是什么。我想我会将它描述为函数的动态范围,并且在大多数语言中并不常见,因为它很容易被滥用。 Emacs 正在慢慢转向大多数语言使用的词法范围。我不确定您通常可以在 Python 中执行此操作,您必须设计代码以允许在特定范围内覆盖该函数。
C
Community

找到了这个问题的答案。

先发布here

;; 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-line 仅在变量 kill-whole-line 的值为非零时删除换行符。最好将“(delete-char 1)”更改为“(if kill-whole-line (delete-char 1))”。
C
Community

从技术上讲,第一部分的其他答案是错误的。

这是我的实施和动机:

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

我从 simple.el 中的“kill-word”改编了这里的代码。我将 kill-region 切换为 delete-region,将 forward-word 切换为 backward-word。这样它真的不会影响 kill-ring,不像其他情况,在 emacs 之外,我注意到 kill-ring 受到了影响。


我更喜欢这个答案,因为它不会搞砸从操作系统剪贴板粘贴(从杀戮环中删除最后一件事无济于事,因为操作系统剪贴板中的内容丢失了)
查看我的答案,了解在不复制 kill 函数定义的情况下执行此操作的方法。
G
Geo
(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)

我喜欢这个,但是因为我不使用瞬态标记模式,所以我更喜欢一个“插入注册内容-z”,除了删除区域行。
J
James Coleman

添加相当于 kill-region 和 kill-line 键 Cw 和 Ck 的删除,如下所示。绑定到键 Cv 和 Cz。

;; A keybinding to delete-region gives a good "Windows CUT Ctrl-x equivalent".
;; What keybinding to use is awkward to choose.
;; using C-v "Windows PASTE Ctrl-v" is quite a subversive option.
;;  C-v = scroll up in emacs which I have no use for.
(global-set-key (kbd "C-v") 'delete-region)

;; To have also a "Windows CUT" alternative to C-k (kill-line) this can be done:
(defun delete-line () "delete line, take it out of kill ring. bind this func to C-z"
 (interactive)
 (setq last-command 'delete-line)
 (kill-line)
 (setq kill-ring (cdr kill-ring))
 (setq kill-ring-yank-pointer kill-ring)
 (setq last-command 'delete-line)
)
(global-set-key (kbd "C-z") 'delete-line)
;; without setting of last-command 2+ C-zs mess up kill-ring

K
Kevin Zhu

我对第一个问题的回答:在 emacs 中标记文本(使用鼠标或设置标记 C-SPC),然后按键盘上的“<- Backspace”按钮而不是 C-w。这样您仍然可以在系统剪贴板中粘贴文本,而不必担心剪贴板被 C-w 杀死的文本覆盖

此答案的背景:有时,当我在 emacs 之外获取要用于替换 emacs 中的区域的文本时,我经常会犯错误,首先将该文本复制到系统剪贴板中(即在 Windows Ctrl + C 上),然后执行 { 2} 在 emacs 中“删除”我要替换的文本区域,希望以后的 M-w 可以从 kill-ring 恢复剪贴板中的文本。不幸的是,剪贴板将被 C-w 杀死的文本简单地覆盖,剪贴板中的原始消息永远不会显示在 kill-ring 中。

对于第二个问题,是的,您始终可以先在 emacs 中标记文本,然后直接C-y


P
PRouleau

作为所有答案的补充。如果你编写 elisp 代码来删除,你可以调用 kill 的函数,只要你使用一个本地的 kill-ring 对象,如下所示:

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

使用任何杀死某些东西的函数来代替 kill-something。然后该功能将被删除,并且在真正的杀戮环中不会记住任何内容。


W
Wilfred Hughes

这是 kill-region 的一个版本,它不会将值强制到 kill-ring 中。

(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 会删除文本而不更改 kill-ring。


k
kevincasey

如何在没有杀环的情况下删除文本?

delete-region 函数将删除所选区域而不将其添加到杀伤环

此外,是否可以直接拉文本而不是某些文本,甚至无需按下按钮来杀死它?

我想你是在问如何用你已经放在杀戮环上的东西替换选定区域中的文本。

设置 (delete-selection-mode 1) 将允许您在选定区域上进行拉拽/粘贴。它还允许您只键入和替换选定的区域。

在 OS XI 上的版本 25.1.1 上,还必须添加 (setq select-enable-primary nil) 以防止其将所选区域复制到杀伤环