Emacs模式:“;命令试图在minibuffer中使用minibuffer";
情景:Emacs模式:“;命令试图在minibuffer中使用minibuffer";,emacs,elisp,modal-dialog,Emacs,Elisp,Modal Dialog,情景: 我开始键入M-x以键入命令 我切换到另一个emacs窗口/缓冲区,因为我意识到我在错误的窗口中执行命令 我再次开始键入M-x以在正确的窗口中执行命令 结果:我得到了可怕的“命令试图在minibuffer中使用minibuffer” 在使用emacs时,这种情况每天会发生多次,而不仅仅是在这种情况下。这种行为对用户非常有害(参考Jef Raskin的《人性化界面》中的模式和伪模式) 有没有一种方法可以自定义emacs行为,这样它就不用给出这个错误,而是取消第一个迷你缓冲区并用一个新的替
- 我开始键入M-x以键入命令
- 我切换到另一个emacs窗口/缓冲区,因为我意识到我在错误的窗口中执行命令
- 我再次开始键入M-x以在正确的窗口中执行命令
有没有一种方法可以自定义emacs行为,这样它就不用给出这个错误,而是取消第一个迷你缓冲区并用一个新的替代它?我不确定是否有这样的自定义,但是我避免这样做的方法是点击CTRL G来取消我在MiBiffFER中写的命令。 < P>你可以设置变量<代码>允许递归的微布告器< /C> >,这将阻止错误消息的出现。但它只支持对minibuffer的多个调用—它不会将当前minibuffer的命令重定向到新的缓冲区。您可以尝试一下,但我认为它会更加混乱,因为原始操作仍在等待
M-x
绑定到'execute-extended-command
,为该命令重新托管(更改原始缓冲区)有点像是使用continuation编程。i、 你从位置X调用一个子程序,但是当完成后你没有返回到X,而是返回到Y。我个人认为这会带来更多的混乱,而不是解决问题。但是我理解这种挫折感(也知道其他人也有同样的挫折感)。因为我的第一个答案并没有直接给出你想要的,所以我想我会想出一个真正的解决办法。这就是我所拥有的:
(defvar my-execute-extended-command-source-buffer nil
"var holding the buffer to which the extended-execute-command should apply")
(defvar in-my-execute-extended-command nil
"internal use - indicates whether we're in a 'recursive edit' of sorts")
(defun my-execute-extended-command (command)
"home-grown version of execute-extended-command that supports re-hosting the buffer"
(interactive (list (if in-my-execute-extended-command
nil
(let ((in-my-execute-extended-command t))
(setq my-execute-extended-command-source-buffer (current-buffer))
(completing-read "My-x " obarray 'commandp t nil 'extended-command-history nil nil)))))
(if in-my-execute-extended-command
(progn (setq my-execute-extended-command-source-buffer (current-buffer))
(select-window (minibuffer-window)))
(switch-to-buffer my-execute-extended-command-source-buffer)
(call-interactively (symbol-function (intern command)))))
我已经用这种方法测试过了。我把它绑在一把钥匙上(F10
在我的情况下,b/c我不想丢失M-x
)。然后,打开两个窗口,每个窗口显示不同的缓冲区(例如a和B):
F10 isearch for
C-x o
C-x o
F10
ward RET
M-x
功能,而不是从M-x
调用的命令。此外,此版本不支持前缀参数
希望这就是你想要的。有人能改进以下方面吗 我已经放弃,只想在打开新的迷你缓冲区之前设置\C-w以取消以前的任何迷你缓冲区(如执行\C-g\C-w) 到目前为止,多亏了特雷,我得到了:
(defun cancel-completing-read ()
(if (> (minibuffer-depth) 0) (exit-minibuffer))
(completing-read "My-x " obarray 'commandp t nil 'extended-command-history nil nil))
(defun cancel-and-execute-command (command)
(interactive (list (cancel-completing-read)))
(call-interactively (symbol-function (intern command))))
(global-set-key "\M-x" 'cancel-and-execute-command)
我应该使用什么命令来代替上面的exit minibuffer
我试过了
keyboard-escape-quit
exit-minibuffer
keyboard-quit
事实上,这个emacs“特性”是咄咄逼人和令人讨厌的。
我发现这是问题的正确答案。很可能是因为你用鼠标而不是minibuffer命令切换窗口,所以你失去了minibuffer的焦点。因此,每当您使用鼠标失去焦点时,小缓冲区将被清除。查看这篇文章。它对我来说很有效,而且比递归的迷你缓冲区要好得多,这会让人头疼
给你:
;; automatically cancel the minibuffer when you switch to it, to avoid
;; "attempted to use minibuffer" error.
;; cy was here
(provide 'cancel-minibuffer)
(defun cancel-minibuffer-first (sub-read &rest args)
(let ((active (active-minibuffer-window)))
(if active
(progn
;; we have to trampoline, since we're IN the minibuffer right now.
(apply 'run-at-time 0 nil sub-read args)
(abort-recursive-edit))
(apply sub-read args))))
(advice-add 'read-from-minibuffer :around #'cancel-minibuffer-first)
另一种看问题的方式是,上面的工作流被破坏了,而不是emacs。在更改缓冲区以设置新区域或其他任何内容之前,G-G退出minibuffer,而不是尝试递归(正如您所做的)嗯,在这种情况下,听起来您比emacs更具用户敌意!由应用程序来适应用户的工作流程,否则为什么要实施撤销?不,这根本不是递归。虽然我很欣赏现代设计实践避免了模态,但emacs是在遥远的过去设计的,具有丰富的模态。如果emacs的模式有问题,我坦率地建议不要使用它。Emacs对用户怀有敌意。就我个人而言,我克服了它,学会了使用它,并发现了很多可用的功能,但那是在emacs当之无愧的时候。这些天我很少接触它。如果什么东西坏了,那是工具,而不是用户(作为第一近似值)。EoghanM感到困惑是有原因的。在这种情况下,因为minibuffer总是可见的,所以它与缓冲区没有特别的关系,那么为什么M-x命令应该保留在它启动的缓冲区上呢?Emacs甚至没有指明该命令将应用于哪个缓冲区。谢谢伙计们-Godeke,你能在回答中推荐一个更好的编辑器吗?显然VI也是高度模态的。几年前我确实尝试过Archy,但我认为它已经死了。谢谢,我知道ctrl-g并经常使用它,但在这种情况下,我似乎无法将其纳入我的工作流中-我认为原因是我不想取消该命令,只需将其重定向到另一个窗口。谢谢Trey,我会将其绑定到m-x,然后看看我如何继续。我看到了一个直接的问题,即在第5步执行命令后,缓冲区A被缓冲区B替换(因此现在我在两个窗口中都有两个B缓冲区)。也许这是我的设置有点奇怪-你给了我足够的时间来继续开发适合我的答案。缓冲区的变化也发生在我身上,我不知道如何解决这个问题。我认为
interactive
的处理强制命令从您启动的窗口开始。但这只是猜测。我无法用的save-window-shiftion
解决这个问题(这是我想到的第一件事)。这对我来说很有效