删除不匹配的Isearch字符串部分,如果完全匹配则删除最后一个字符


11

我有以下

(defun isearch-del-fail-or-char ()
  "Delete failed isearch text, or if there is none, a single character."
  (interactive)
  (if (isearch-fail-pos)
      (delete-region (isearch-fail-pos) (point))
    (isearch-del-char)))

(define-key isearch-mode-map (kbd "DEL") 'isearch-del-fail-or-char)

该代码的目的是delete在isearch中删除整个失败的字符串(或者如果没有失败的字符串,则仅删除一个字符)。

但是,delete-region是从isearch正在搜索的缓冲区中删除文本,而不是从isearch缓冲区本身删除。

正确的方法是什么?也欢迎批评我的emacs lisp样式的其余部分:)

Answers:


12

是的。Isearch会读取您键入的键,在其中查找它们isearch-mode-map,然后在当前缓冲区中调用它们。

尽管有外观,但Isearch 并未使用minibuffer。它使用回声区域。也就是说,您看到的实际上是输出消息,包括您键入的字符的回声。

这应该按照您的要求进行:

(defun mydelete ()
  "Delete the failed portion of the search string, or the last char if successful."
  (interactive)
  (with-isearch-suspended
      (setq isearch-new-string
            (substring
             isearch-string 0 (or (isearch-fail-pos) (1- (length isearch-string))))
            isearch-new-message
            (mapconcat 'isearch-text-char-description isearch-new-string ""))))

(define-key isearch-mode-map (kbd "DEL") 'mydelete)

(顺便说一句,您的问题是delete字符,但您写了DEL,这是退格字符。)


正如@Malabarba在注释中指出的那样,当您将新的搜索字符串设置为""(空字符串)时,with-isearch-suspended将通过搜索最后一个搜索字符串来恢复,而不是从一个空的搜索字符串开始。

通常,这是的“ 功能with-isearch-suspended。但是因为有时您可能真的想清空搜索字符串以恢复,所以with-isearch-suspendedisearch + .el的版本中,我添加了variable isearchp-if-empty-prefer-resuming-with-last来控制它。如果将其绑定到nil并且设置isearch-new-string为,""则搜索将以空的搜索字符串继续。

因此,使用Isearch +,您可以使用以下定义执行所需的操作:

(defun mydelete ()
  "Delete the failed portion of the search string, or the last char if successful."
  (interactive)
  (let ((isearchp-if-empty-prefer-resuming-with-last  nil))
    (with-isearch-suspended
        (setq isearch-new-string
              (substring
               isearch-string 0 (or (isearch-fail-pos) (1- (length isearch-string))))
              isearch-new-message
              (mapconcat 'isearch-text-char-description isearch-new-string "")))))

我也注意到现在的Emacs 24.4引入了回归,我已经提交的Emacs的bug#20466对,这意味着绑定DELisearch-mode-map是不够的。他们增加了一个单独的结合<backspace>,除了一个DEL。也就是说,对于Isearch,<backspace>不再将其翻译为DEL,(但对于Emacs来说,仍然确实如此)。

因此,如果您希望Backspace键执行您在Emacs 24.4或更高版本中所要求的操作,则不能仅绑定DELmydelete。您需要绑定<backspace>mydelete。哑巴,AFAICT,n'arrete pas le progres上的舞者 ...


我已经添加了一个类似的命令,以ISEARCH +和它绑定到C-M-l(用于去除在完成失配相同的密钥冰柱)。

C-g还要注意的是,在Isearch中,如果存在不匹配的情况,也将删除不匹配的文本。(但C-g在搜索成功时也会起作用。)


我应该提到,Isearch +在相当长的一段时间内也具有类似行为的可选行为。M-k在Isearch期间,在3个行为之间切换,这些行为由option的值控制isearchp-drop-mismatch

  • replace-last-您当前的输入将替换最后一个不匹配的文本。即使输入不匹配,您也始终可以看到您的最后输入。并且可以使用进行编辑M-e

  • nil -即使先前输入的部分不匹配,也会附加当前的输入。

  • 其他-您当前输入的内容如果不匹配,将被忽略(删除)。搜索字符串始终具有成功的匹配项。


顺便说一句,自从我添加了对失败部分的突出显示(几年前,在我将其添加到GNU Emacs之前)以来,我就一直在考虑向Isearch +添加类似的命令,但是我从来没有去过。我现在已经做到了。(但是,我不包括删除字符。如果没有失败的部分,我添加的命令将是no-op。)
Drew

我在OS X上。我的意思是向后删除。
asmeurer

isearch + replace-last行为看起来非常不错。但是,有什么方法可以使它在每次搜索失败时都不会响起来吗?
asmeurer 2015年

2
我上传了的新版本isearch+.el。它(a)修复了自动删除不匹配问题,从而使环绕效果正常的问题。并且它添加了一个选项,isearchp-ring-bell-function您可以使用它来抑制搜索过程中的铃声。
Drew

3
马拉巴巴,有趣。我参加了一个射击的bug,并结束了与。多数情况下,货物都是从isearch-del-char德鲁的答案中汲取的,但它似乎按预期工作。该with-isearch-suspended宏是罪魁祸首。
jbm
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.