3

考虑以下示例:我想使用 ido 从 minibuffer 中读取文件,但要合并到我经常使用的所有目录中。我不能只是执行

(ido-find-file)
(ido-merge-work-directories)

因为第二个 sexp 只会在用户完成选择文件后执行。那么问题是:在迷你缓冲区的命令循环中执行命令的最佳/最干净的方法是什么?

我知道这样做的唯一方法是将我想要的命令绑定到一个键序列,并将该序列添加到 unread-command-events 以便在我们进入 minibuffer 命令循环后该键运行:

(setq unread-command-events (append (listify-key-sequence (kbd "M-s")) unread-command-events)) ; std key-binding for ido-merge-work-directories
(ido-find-file)

但这很hacky,我想知道是否有更好的解决方案。

谢谢!

编辑:澄清一下,这个问题与 ido 无关。让我解释。当您调用诸如 find-file、switch-to-buffer 或任何需要 minibuffer 交互的函数时,会创建“递归编辑”——即命令循环内的命令循环。

所以,代码:

(message "A")
(recursive-edit) 
(message "B")

打印 A,然后暂停函数的执行并重新进入命令循环。您可以四处移动、打开文件等,直到您离开递归编辑,然后打印“B”。

所以,让我重新表述我的问题:如果您创建一个递归编辑,那么您如何在创建的新命令循环中执行一个命令(在同一函数中)?如果我必须输入额外的键,这不算数。对于 ido 示例,要合并目录,必须运行 ido:在调用 ido 之前执行合并目录不在 ido 的命令循环内。如果你之后执行它,那么 ido 会破坏它的命令循环。

4

3 回答 3

1

所以我认为你的问题有三个答案:

  • 您可以在 minibuffer 映射中绑定键,就像其他任何键一样。有几个可能相关的键映射。

  • ido有许多钩子可用于更改各种函数的行为,特别是ido-make-*-hook变量似乎相关。(如果你从未使用过它,M-x describe-variable又名\C-h v,是你的朋友。)

  • 如果你想普遍改变一个函数的行为并且没有可用的钩子,你应该考虑defadvice. 在你的情况下,我认为你会很好(未经测试!):

    (defadvice ido-find-file (before)
       (ido-merge-work-directories))
    (ad-activate ido-find-file)
    

    您可以将这些行添加到您的.emacs

    (when (require 'ido)
      (defadvice ido-find-file (before)
         (ido-merge-work-directories))
      (ad-activate ido-find-file))
    
于 2012-07-08T20:55:22.380 回答
1

引用手册:

一般来说,我们会尽量减少 GNU Emacs 中递归编辑级别的使用。这是因为它们限制你以特定的顺序“返回”——从最内层到顶层。如果可能,我们会在单独的缓冲区中呈现不同的活动,以便您可以随意在它们之间切换。一些命令切换到新的主要模式,该模式提供了切换回来的命令。这些方法使您可以更灵活地按照您选择的顺序返回未完成的任务。

那么您能描述一下您实际需要执行此操作的场景吗?Ido 在这种情况下的工作方式非常奇怪。

于 2012-07-10T01:30:22.887 回答
1

我不清楚你在问什么,但这听起来有点像你在问如何以交互方式调用一个命令,当你不在顶层时,该命令从迷你缓冲区中读取。

如果这是问题,那么答案很简单:绑定enable-recursive-minibuffers到非nil围绕命令调用。

于 2013-10-21T03:14:45.587 回答