我可以在任何地方都使用 ido-completing-read 而不是 complete-read 吗?

Posted

技术标签:

【中文标题】我可以在任何地方都使用 ido-completing-read 而不是 complete-read 吗?【英文标题】:Can I use ido-completing-read instead of completing-read everywhere? 【发布时间】:2010-10-28 16:00:32 【问题描述】:

我是ido-mode 的忠实粉丝,以至于我想将它用于describe-functionfind-tag 之类的东西,而不必写像“我能得到 ido -在 Emacs 中搜索标签的模式样式完成?”每一个。

两者

(defalias completing-read ido-completing-read)

(setf 'completing-read 'ido-completing-read)

不起作用,至少部分原因是ido-completing-read 在其主体中调用completing-read,因此任何简单的重新定义都会导致无限递归。

理论上应该是可能的,因为ido-completing-read 的文档字符串的第一行是“内置completing-read 的Ido 替换”。我环顾四周,似乎找不到其他尝试或成功的人。

我意识到Icicles 可能提供了类似的东西,我可能最终还是会使用它,但这比我现在想采取的更冒险。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

编辑:这现在是 Emacs package available from MELPA。它已扩展为成熟的次要模式。开发发生在on GitHub。

原帖:

这是我对 Jacobo 答案的改进。归功于他的原始魔法。我添加了一个覆盖变量,您可以使用它来防止在特定函数中使用ido-completing-read。我还添加了一个检查,如果没有完成,则使用原始的完成读取(这种情况偶尔会发生,例如在 org-mode 的 org-remember-apply-template 中,这与 Jacobo 的原始建议不同)。

(defvar ido-enable-replace-completing-read t
  "If t, use ido-completing-read instead of completing-read if possible.

Set it to nil using let in around-advice for functions where the
original completing-read is required.  For example, if a function
foo absolutely must use the original completing-read, define some
advice like this:

(defadvice foo (around original-completing-read-only activate)
  (let (ido-enable-replace-completing-read) ad-do-it))")

;; Replace completing-read wherever possible, unless directed otherwise
(defadvice completing-read
  (around use-ido-when-possible activate)
  (if (or (not ido-enable-replace-completing-read) ; Manual override disable ido
          (boundp 'ido-cur-list)) ; Avoid infinite loop from ido calling this
      ad-do-it
    (let ((allcomp (all-completions "" collection predicate)))
      (if allcomp
          (setq ad-return-value
                (ido-completing-read prompt
                               allcomp
                               nil require-match initial-input hist def))
        ad-do-it))))

哦,要在 M-x 中使用 ido,请使用 amx。

【讨论】:

【参考方案2】:

Hocus pocus, abracadabra, presto!

(defadvice completing-read
  (around foo activate)
  (if (boundp 'ido-cur-list)
      ad-do-it
    (setq ad-return-value
      (ido-completing-read
       prompt
       (all-completions "" collection predicate)
       nil require-match initial-input hist def))))

这适用于除 subr 之外的所有内容,其中执行扩展命令是重要的(绑定到 M-x 的内容)。但是我们可以从 M-x 得到我们想要的东西

(global-set-key
 "\M-x"
 (lambda ()
   (interactive)
   (call-interactively
    (intern
     (ido-completing-read
      "M-x "
      (all-completions "" obarray 'commandp))))))

【讨论】:

似乎从 Emacs 23.2 开始就被破坏了。将 ido-cur-item 替换为 ido-cur-list 似乎可以让它再次工作。【参考方案3】:

我认为ido-mode 还没有为此做好准备。特别是,ido-completing-read 目前仅适用于字符串,而completing-read 也支持 alist。如果您希望对要完成的项目有不同的用户级描述,这一点非常重要。

因此,我对它还不能开箱即用并不感到惊讶。如果不自己修改代码,最好的办法可能是提交错误报告/功能请求。

【讨论】:

【参考方案4】:

Ido 带有一个应该执行此操作的函数,因此只需在您的 .emacs 文件中调用它:

(ido-无处不在 t)

【讨论】:

我一直希望这会奏效,但 ido 对“无处不在”的看法相当有限,仅限于文件、目录和缓冲区完成。它对describe-functionfind-tag 之类的东西没有任何影响,因为它们正在完成其他事情。我目前的想法是将completing-read 保存到一个变量中,将名称别名为ido-completing-read,然后在ido-completing-read 周围放置一个defadvice,这会在ido 期间恢复原始completing-read。这是相当骇人听闻的,而且可能不值得。【参考方案5】:

使用 Emacs 24.3,ido-ubiquitous 对我不起作用。所以尝试了这个,到目前为止它工作正常:

(defun my-completing-read (prompt collection &optional predicate
                  require-match initial-input
                  hist def inherit-input-method)
  (if (listp collection)
      (ido-completing-read prompt collection predicate require-match
               initial-input hist def inherit-input-method)
    (completing-read-default prompt collection predicate require-match
                 initial-input hist def inherit-input-method)))

(setq completing-read-function 'my-completing-read)

【讨论】:

ido-ubiquitous 现在可以很好地与最近的 Emacsen 配合使用,因为 Ryan 重写了它。【参考方案6】:

只是一个想法:您是否尝试过编辑ido-completing-read 以调用original-completing-read 而不是completing-read,将original-completing-read 定义为当前的completing-read,然后执行您的defalias 或setf 操作?

【讨论】:

以上是关于我可以在任何地方都使用 ido-completing-read 而不是 complete-read 吗?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在任何地方替换全局“operator new()”?

django 在任何地方都提供相同的会话

大结果在任何地方都很慢,但在本地

我如何制作一个成员的实例并在任何地方使用它

结构的多重定义错误,但我在任何地方都看不到错误(C++)

Mac OSX 中的文本大小比使用 Qt 的 Windows 小。我想在任何地方都有相同的尺寸