在Emacs中,什么';在不破坏其他窗口的情况下退出键盘的最佳方法是什么?

在Emacs中,什么';在不破坏其他窗口的情况下退出键盘的最佳方法是什么?,emacs,elisp,dot-emacs,Emacs,Elisp,Dot Emacs,编辑:我知道存在键盘退出(通常绑定到C-g);但我更感兴趣的是了解如何处理Emacs附带的编辑功能(如本例)。我经常遇到这种情况,当我只想更改一些内置函数时 在emacs中,当您按M-ESC(或ESC三次)时,您可以摆脱很多情况,如瞬态标记等。但我习惯性地按了比我预期更多的escape键(我实际上将其重新映射为按escape键的一次),这最终会破坏我的windows配置,这是非常烦人的。simple.el中定义了键盘退出退出功能: (defun keyboard-escape-quit ()

编辑:我知道存在键盘退出(通常绑定到C-g);但我更感兴趣的是了解如何处理Emacs附带的编辑功能(如本例)。我经常遇到这种情况,当我只想更改一些内置函数时

在emacs中,当您按M-ESC(或ESC三次)时,您可以摆脱很多情况,如瞬态标记等。但我习惯性地按了比我预期更多的escape键(我实际上将其重新映射为按escape键的一次),这最终会破坏我的windows配置,这是非常烦人的。simple.el中定义了键盘退出退出功能:

(defun keyboard-escape-quit ()
  "Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
  (interactive)
  (cond ((eq last-command 'mode-exited) nil)
    ((> (minibuffer-depth) 0)
     (abort-recursive-edit))
    (current-prefix-arg
     nil)
    ((and transient-mark-mode mark-active)
     (deactivate-mark))
    ((> (recursion-depth) 0)
     (exit-recursive-edit))
    (buffer-quit-function
     (funcall buffer-quit-function))
    ((not (one-window-p t))
     (delete-other-windows))
    ((string-match "^ \\*" (buffer-name (current-buffer)))
     (bury-buffer))))
我可以看出我不想要台词:

    ((not (one-window-p t))
     (delete-other-windows))

但修改此函数的最佳方法是什么?我只能看到两种方法:1)修改simple.el 2)将此函数复制到我的.emacs文件中并在那里进行修改。两种方法都不是很好;理想情况下,我希望看到一些关于defadvice的信息,但我不知道在这种情况下如何做到。

我通常发现“键盘退出(C-g)”可以摆脱所有这些情况

但是,如果您真的想拥有此函数的变体,我认为复制到.emacs文件(并重命名,我通常使用前缀bp)并在那里进行编辑可能是最好的选择

编辑,作为对编辑的响应:通常,每当我想要一个emacs函数的编辑版本时,我要么自己编写,要么将它复制到我的.emacs中,将它重命名为bp,然后进行适当的编辑


这样做的缺点是my.emacs非常庞大,而且可能非常粗糙,带有不再使用的古老功能。。。好处是,每当我需要写新的东西时,我都有大量的示例代码要看……

您可以使用around advice并重新定义有问题的函数来做您想做的事情(即one-window-p应始终返回t):


这种类型的行为类似于(let…),但必须更加复杂,因为您需要覆盖有限范围内的函数,而不是变量。

按一下Escape键,默认情况下,充当元前缀键;也就是说,涉及元键的键绑定

三次按Escape键将运行键盘Escape quit,这类似于键盘退出,但更多的是“按我的意思做”行为

此代码可能对您的用例有所帮助。您可以在Emacs init文件中使用此选项:

;;; esc always quits
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'keyboard-quit)

下面是另一条更简单的建议,它利用了
键盘退出退出
在关闭窗口之前调用
缓冲区退出功能
这一事实:

(defadvice keyboard-escape-quit
  (around keyboard-escape-quit-dont-close-windows activate)
  (let ((buffer-quit-function (lambda () ())))
    ad-do-it))
使用Emacs 25.1。(我最初使用@scottfrazer的建议,但在25.1中不太满意。还没有调试过。)

我更感兴趣的是了解如何处理Emacs附带的编辑功能(如本例)。我经常遇到这种情况,当我只想更改一些内置函数时

这正是我创建库的目的。您可以将其放在init文件中:

(el-patch-defun keyboard-escape-quit ()
  "Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
  (interactive)
  (cond ((eq last-command 'mode-exited) nil)
    ((> (minibuffer-depth) 0)
     (abort-recursive-edit))
    (current-prefix-arg
     nil)
    ((and transient-mark-mode mark-active)
     (deactivate-mark))
    ((> (recursion-depth) 0)
     (exit-recursive-edit))
    (buffer-quit-function
     (funcall buffer-quit-function))
    (el-patch-remove
      ((not (one-window-p t))
       (delete-other-windows)))
    ((string-match "^ \\*" (buffer-name (current-buffer)))
     (bury-buffer))))

使用flet的更好的单行程序版本(即let的功能版本):(defadvice键盘escape quit(在我的键盘escape quit激活周围)(flet((一个窗口-p(&可选的nomini all frames)t))ad do it)您可能还需要将
flet
更改为
cl flet
。完美。非常感谢。
(el-patch-defun keyboard-escape-quit ()
  "Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
  (interactive)
  (cond ((eq last-command 'mode-exited) nil)
    ((> (minibuffer-depth) 0)
     (abort-recursive-edit))
    (current-prefix-arg
     nil)
    ((and transient-mark-mode mark-active)
     (deactivate-mark))
    ((> (recursion-depth) 0)
     (exit-recursive-edit))
    (buffer-quit-function
     (funcall buffer-quit-function))
    (el-patch-remove
      ((not (one-window-p t))
       (delete-other-windows)))
    ((string-match "^ \\*" (buffer-name (current-buffer)))
     (bury-buffer))))