在迷你缓冲区中显示当前文件的完整路径的功能


98

我需要获取正在使用emacs编辑的文件的完整路径。

  • 有功能吗?
  • 如果不是,获取该功能的elisp函数将是什么?
  • 如何将结果(路径名)复制到剪贴板,以便可以重复使用?

我正在使用Mac OS X和Aqumacs。

(setq filepath (get-fullpath-current-file)) ???
(copy-to-clipboard 'filepath) ???

添加

(defun show-file-name()
  “在迷你缓冲区中显示完整的路径文件名。”
  (互动)
  (消息(缓冲文件名))
  (kill-new(文件真名缓冲文件名))
)
(全局设置键“ \ C-cz”'显示文件名)

结合我得到的两个答案,我可以得到想要的东西。感谢您的回答。还有更多问题。

  • (file-truename)是做什么用的?
  • 我可以将路径名复制到System(OS)的剪贴板中,而不是复制到kill ring上,以便可以将信息与其他应用程序一起使用吗?

Answers:


91

它是内置功能buffer-file-name,可为您提供文件的完整路径。

最好的办法是让emacs窗口始终显示系统名称和当前正在编辑的缓冲区的完整路径:

(setq frame-title-format
      (list (format "%s %%S: %%j " (system-name))
        '(buffer-file-name "%f" (dired-directory dired-directory "%b"))))

您还可以执行以下操作:

(defun show-file-name ()
  "Show the full path file name in the minibuffer."
  (interactive)
  (message (buffer-file-name)))

(global-set-key [C-f1] 'show-file-name) ; Or any other key you want

7
在emacs 24中buffer-file-name是一个变量
barracel

5
...但仍然是一个功能
phils,

16
如果它是一个函数,那么为什么不出现在其中M-x
asmeurer 2014年

8
asmeurer -因为它不是互动
本·菲茨杰拉德

2
@Talespin_Kit是的,绝对如此。Elisp是“ lisp-2”,而不是“ lisp-1”,这意味着有两个独立的名称空间(变量和函数)。因此,每个符号都有一个“功能插槽”和一个“值插槽”,访问哪个插槽取决于上下文。在实践中有很多示例(例如,任何次要模式名称都将是函数和变量)。这也是为什么您需要使用like funcall来调用存储为变量值的函数的foo原因,因为如果使用的(foo)话,您将使用函数槽foo而不是值槽。
菲尔斯

73

要借鉴JérômeRadix的答案,如果您只是想快速查看当前缓冲区的文件路径,可以执行M-: buffer-file-name

或者,(buffer-file-name)在某处键入缓冲区并C-x C-e在右括号上运行(这可以在任何模式下运行,而不仅限于lisp模式)。


3
谢谢,我认为buffer-file-name作为一个函数,但它不会出现在M-x,但似乎在M-:emacs eval有我可以运行命令,感谢你的答案:)
PeterZD

6
是的,M-x仅运行交互功能,而M-:运行任何elisp功能。
asmeurer

40

我的窍门是做一个C-x C-f像打开文件一样的操作,它将用当前文件路径预填充minibuff,然后C-g退出。M-: buffer-file-name比任何其他方法都要快,但要丑得多。


我也是 它不是emacs-y的核心,但如果我只关心当前文件的路径,那么它就可以工作。
andrunix

如果您打开一个文件(例如A),然后跳转到另一个文件(例如B),例如使用某个插件的跳转定义功能,则此方法将显示A的路径,而不是B!因此,此答案并不总是提供OP的要求。
Abhishek Anand

4
Cx Cv不仅会显示当前路径,还会显示当前文件的名称
kuzzooroo

@kuzzooroo适用于非ido-mode用户(使用ido-mode时,名称显示在Cx Cf中)。
朱利安·帕拉德

16

您想要的直接实现是:

(defun copy-full-path-to-kill-ring ()
  "copy buffer's full path to kill ring"
  (interactive)
  (when buffer-file-name
    (kill-new (file-truename buffer-file-name))))

就是说,我发现能够获得迷你缓冲区中内容的完整路径非常有用,这就是我所使用的:

(define-key minibuffer-local-completion-map "\C-r" 'resolve-sym-link)
(defun resolve-sym-link ()
  "Try to resolve symbolic links into true paths."
  (interactive)
  (beginning-of-line)
  (let* ((file (buffer-substring (point)
                                 (save-excursion (end-of-line) (point))))
         (file-dir (file-name-directory file))
         (file-true-dir (file-truename file-dir))
         (file-name (file-name-nondirectory file)))
    (delete-region (point) (save-excursion (end-of-line) (point)))
    (insert (concat file-true-dir file-name))))

然后,如果我想在剪贴板中使用它,则只需删除行(C-a C-k)。但是我们可以轻松地在上面的命令中将真实名称复制到剪贴板,只需将最后一行更改为:

(insert (kill-new (concat file-true-dir file-name)))))

新的部分是'kill-new将字符串放入kill环的调用。


您能否详细说明如何使用此设置?“ \ Cr”是什么意思?
建模者

没关系。我想到了。我认为在ido模式下并指向文件时,这很有用,然后按Cr获取该文件的完整路径。确实有用。不过,我仍然不知道为什么使用\ C,而不是C.
建模

11

不需要额外的功能

M-! pwd

尽管这可以工作,但是它在Windows系统上不起作用,并且无法说明emacs的当前工作目录可能与当前缓冲区的文件目录不同的事实。您可以通过访问C-x C-f,运行M-! pwd,然后M-x cd选择另一个目录,然后M-! pwd再次运行来访问文件。
josaphatv

3

我已经使用了以下代码很长时间了。当我在模式行中按缓冲区名称上的鼠标中键时,它将完整的文件路径复制到kill ring。当我在模式行中按缓冲区名称上的shift-mouse-2时,它仅将缓冲区名称复制到kill-ring。

(defun copy-buffer-file-name (event &optional bufName)
  "Copy buffer file name to kill ring.
If no file is associated with buffer just get buffer name.
"
  (interactive "eP")
  (save-selected-window
    (message "bufName: %S" bufName)
    (select-window (posn-window (event-start event)))
    (let ((name (or (unless bufName (buffer-file-name)) (buffer-name))))
      (message "Saved file name \"%s\" in killring." name)
      (kill-new name)
      name)))

(define-key mode-line-buffer-identification-keymap [mode-line mouse-2] 'copy-buffer-file-name)
(define-key mode-line-buffer-identification-keymap [mode-line S-mouse-2] '(lambda (e) (interactive "e") (copy-buffer-file-name e 't)))

3

C-x C-d,也可以通过调用M-x list-directory,它将为您显示当前文件的目录,您只需按“ Enter”键即可清除小型缓冲区。其他详细信息在这里


我最喜欢的答案,简单,快捷,容易!
壁虱

2

C-x C-b 显示缓冲区列表以及每个缓冲区的文件路径(如果适用)。



1

我可以将路径名复制到System(OS)的剪贴板中,而不是复制到kill ring上,以便可以将信息与其他应用程序一起使用吗?

您可以使用xclip(Linux),pbcopy(Mac)和putclip(Cygwin)之类的东西。

我个人使用包装器脚本cp分别用于复制和粘贴,首先从标准输入中读取内容,然后从标准输入中读取内容。这样,它就可以在我所有的开发平台上运行:

(shell-command (format "echo '%s' | c" buffer-file-name))

我发现这比使用Emacs剪贴板支持更加可靠和可配置。例如,我的c命令将输入​​复制到Linux上的所有3个剪贴板(主要,辅助,剪贴板),因此可以使用Ctrl-V或单击鼠标中键进行粘贴。


这应该可以,但是对我来说不行。(Ubuntu的14.04.1。)即,date | xclipxclip file两个工作像广告(存储日期或文件到初级的内容)如果键入的壳。但是,如果我在M-之后键入这些命令之一!在emacs中(并按回车键)什么也没发生;光标停留在迷你缓冲区中,就好像期望更多的输入一样;如果我中断以重新获得控制权,则没有任何东西存储在主目录中。
Silvio Levy 2015年

好的,您的想法可以用xsel代替xclip很好地工作:(shell-command (format "echo '%s' | xsel -i" buffer-file-name))-并且当被做成交互式命令时(如上面@JeromeRadix最赞成的回答所建议),这是一个大赢家!谢谢!
Silvio Levy

0

最简单的方法是

(buffer-name)<(C-x)(C-e)> for the file name to appear in the echo area

(buffer-name)<(C-u)(C-x)(C-e)> would print the location <here>

从Trey Jackson借来的东西我想到了:

(defun buffer-kill-path ()
  "copy buffer's full path to kill ring"
  (interactive)
  (kill-new (buffer-file-name)))

您可以在网站上找到更多信息


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.