Emacs:如何删除文本而无需杀死戒指?


80

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

另外,是否可以直接拉动文本而不是直接拉动某些文本而无需按按钮将其杀死?



2
请参阅下面的答案,您可以使用键盘上的Backspace按钮来回答第一个问题,将文本标记为第二个问题
Kevin Zhu

定义完块后不只是Cx rk吗?
yalu2015 2014年

Answers:


49

M-x delete-region经常键入,但是您可以将其绑定到键上。

使用较新版本的Emacs中的Delete Selection Mode,您不必键入命令就可以开始键入:

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


33
另外,在最新版本的Emacs中,您甚至不需要绑定delete-region键,因为Backspace现在可以这样做。Backspace删除选定的区域而不是将其杀死,换句话说,Backspace会删除选定的文本而不将其保存/推入kill环。这是因为该值delete-active-regiont,除非你把它定义为其他值。
Jisang Yoo


20

我有同样的问题。到目前为止,我最接近的事情是只是创建一个本质上小的功能:

(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
为什么不只是(delete-region(line-beginning-position)(line-end-position))?
CodyChan

列出的功能听起来不错,但总体上对我不起作用。特别是,我发现它会导致yank指针指向kill-ring的另一端,该指针通常(实际上几乎总是?)不是列表中的下一个元素!(Stll试图破解一个可以通过委托“ kill-line”可靠运行的功能……也许我会像其他人一样诉诸于delete-region ...)
pnkfelix

11

摘自EmacsWiki

等效于‘kill-line’‘C-k’),但没有致命环副作用:

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

最佳答案IMO。然后将ctrl-shift-W绑定到删除区域:(全局设置键(kbd“ CSw”)'删除区域)
Tongfa

5

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


它只会对当前会话进行奇怪的处理。在emacs之外,它不会从kill ring中删除!
PascalVKooten 2012年


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-line仅在变量kill-whole-line的值不为nil时才删除换行符。最好将“((delete-char 1))”更改为“(if kill-whole-line(delete-char 1))”。
艾伦(Alan)

3

大多数kill函数用于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-letfcl-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-regiondelete-region和切换forward-wordbackward-word。这样,它确实不会影响kill-ring,与其他情况(在emacs之外,我注意到kill-ring受影响)不同。


2
我更喜欢这个答案,因为它不会破坏从OS剪贴板粘贴的位置(在此处删除终止环中的最后一件事没有帮助,因为OS剪贴板中的内容丢失了)
Brel

请查看我的答案,以找到一种无需复制kill函数的定义的方法。
jpkotta 2015年

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。

;; 对delete-region进行键绑定可提供良好的“ Windows CUT Ctrl-x等效项”。
;; 选择哪种键绑定是很尴尬的选择。
;; 使用Cv“ Windows PASTE Ctrl-v”是一种颠覆性的选择。
;; Cv =在没有用的emacs中向上滚动。
(全局设置密钥(kbd“ Cv”)'删除区域)

;; 要获得Ck(杀伤线)的“ Windows CUT”替代方案,可以这样做:
(defun delete-line()“删除行,将其从kill ring中删除。将此函数绑定到Cz”
 (互动)
 (setq最后一个命令的'删除行')
 (杀线)
 (setq kill-ring(cdr kill-ring))
 (setq kill-ring-yank-pointer kill-ring)
 (setq最后一个命令的'删除行')
)
(全局设置密钥(kbd“ Cz”)'删除行)
;; 没有设置最后一个命令2+ C-zs弄乱了kill-ring

1

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

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

对于第二个问题,是的,您始终可以先在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现在可以删除文本而无需更改kill-ring。


0

如何删除文本而无须杀死戒指?

delete-region功能将删除所选区域而不将其添加到杀死环

另外,是否可以直接拉动文本而不是直接拉动某些文本而无需按按钮将其杀死?

我想您是在问如何用已放置在kill ring上的内容替换选定区域中的文本。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.