【问题标题】:Clean way to perform commands in the Emacs minibuffer在 Emacs minibuffer 中执行命令的干净方式
【发布时间】:2012-07-08 05:35:05
【问题描述】:

考虑以下示例:我想使用 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 会破坏它的命令循环。

【问题讨论】:

  • 您是否总是要合并其他目录?
  • 这只是一个例子,但对于我正在编写的应用程序(项目管理库),答案是肯定的。我主要对一般问题的答案感兴趣:如果我进入 minibuffer 命令循环,我如何干净地执行该循环中的命令?

标签: emacs elisp


【解决方案1】:

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

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

  • 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))
    

【讨论】:

  • 这些都不起作用。当然,我可以在 minibuffer 映射中绑定键,但我不希望用户输入更多内容。 ido 有钩子,但我没有看到允许您在其循环中执行任意代码,而且问题不是专门关于 ido 的。建议也不起作用,如果您在此之前提出建议,那么代码会在 ido 创建其命令循环之前执行...如果您在之后执行此操作,那么该命令会在 ido 已经关闭其命令循环时执行。
【解决方案2】:

引用手册:

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

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

【讨论】:

  • 我知道它们“不受欢迎”,但是每个 minibuffer 操作都会调用递归编辑,所以这并不是一个罕见的情况。我的帖子中的示例是促使我发布此问题的示例,但我过去也需要将 minibuffer 输入注入提供糟糕 API 的第三方库中。我对“解决我的 ATM 实际问题的不同方法”不感兴趣;我已经找到了一个有效的技巧。我纯粹想知道是否有一种干净的方法可以在内部递归编辑命令循环中执行命令,如果没有一种干净的方法,我会在某个时候破解一个补丁。
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-15
    • 2014-01-27
    • 2012-04-24
    • 1970-01-01
    • 2020-02-27
    • 2015-09-30
    • 2015-04-13
    • 2010-12-19
    相关资源
    最近更新 更多