我可以在任何地方都使用 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-function
或find-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-function
或find-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 吗?的主要内容,如果未能解决你的问题,请参考以下文章