使用ido插入文件名

3

我在我的.emacs中有以下函数,我经常使用它将本地文件的文件名/路径放入当前缓冲区。它运作得很好,但是我想要它具有ido自动完成功能。但我好像无法实现这一点...也许你可以帮助我。

(defun insert-file-name (filename &optional args)
  "Insert name of file FILENAME into buffer after point.

  Prefixed with \\[universal-argument], expand the file name to
  its fully canocalized path.  See `expand-file-name'.

  Prefixed with \\[negative-argument], use relative path to file
  name from current directory, `default-directory'.  See
  `file-relative-name'.

  The default with no prefix is to insert the file name exactly as
  it appears in the minibuffer prompt."
  ;; Based on insert-file in Emacs -- ashawley 20080926
  (interactive "*fInsert file name: \nP")
  (cond ((eq '- args)
         (insert (expand-file-name filename)))
        ((not (null args))
         (insert (filename)))
        (t
         (insert (file-relative-name filename)))))
1个回答

4
启用ido-everywhere后,(interactive "f")通常会使用ido-read-file-name,这不仅为您的函数提供自动完成,而且几乎在任何地方都可以使用。
如果您只想在此函数中使用ido完成,而不是在所有地方都使用,您可以在交互式表单中明确调用ido-read-file-name。在您的情况下使用ido的一个副作用是它似乎总是返回完整路径,使得filename(expand-file-name filename)之间的区别无效。
(defun insert-file-name (filename &optional args)
  "Insert name of file FILENAME into buffer after point.

  Prefixed with \\[universal-argument], expand the file name to
  its fully canocalized path.  See `expand-file-name'.

  Prefixed with \\[negative-argument], use relative path to file
  name from current directory, `default-directory'.  See
  `file-relative-name'.

  The default with no prefix is to insert the file name exactly as
  it appears in the minibuffer prompt."
  ;; Based on insert-file in Emacs -- ashawley 20080926
  (interactive `(,(ido-read-file-name "File Name: ")
                 ,current-prefix-arg))
  (cond ((eq '- args)
         (insert (expand-file-name filename)))
        ((not (null args))
         (insert filename))
        (t
         (insert (file-relative-name filename)))))

我已经重新检查了,尽管 ido-everywheret,但旧函数并没有使用 ido 进行补全。也许 ido-everywhere 与函数使用的 interactive 格式不兼容? - elemakil
好的,经过更多的调查,我找到了这个问题,它引导我找到了解决方案:一个人绝不能使用(setq ido-everywhere t),而应该使用(ido-everywhere t),这与大多数初学者指南和预选的.emacs.d配置相反。 - elemakil
在我的系统上(GNU Emacs 23.2.1,Debian版本),即使没有任何初始化文件,它也可以正常工作。您是否尝试禁用您的初始化文件以检查ido-everywhere是否因其中的某些自定义而损坏?(运行emacs -q,评估您的defun,激活ido-modeido-everywhere,然后查看是否有任何变化) - François Févotte
请查看我的第二条评论;更改ido-everywhere激活的方式非常重要...您上面呈现的代码在任何情况下都有效! - elemakil
是的,我在发布我的评论后看到了你的评论。无论如何,在Emacs中,模式激活是一个非常重要的广泛采用的约定:应该使用(mode-name +1)来激活模式,并使用(mode-name -1)来停用模式。仅仅使用(mode-name)切换模式可能会导致不可预测的结果。仅仅设置变量是不够的,正如你刚刚发现的那样。 - François Févotte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接