在Emacs中将文件路径复制到剪贴板

51

最简单的方法是将当前完整文件名和文件路径发送到剪贴板,我现在使用的是消息缓冲区:我复制出现在那里的文件名,保存文件后。但是,我认为应该有更简单的方法。


请参见https://dev59.com/U3A65IYBdhLWcg3wuRF8 - Alan
10个回答

44

为什么没有人告诉我简单的解决方案。

只需进入您的dired缓冲区,然后按下0 wC-u 0 w

这将调用dired-copy-filename-as-kill,它会给你一个文件的完整路径。如果你想要当前目录,只需删除末尾的文件名,或者你可以使用下面的函数,然后将其绑定到您喜欢的任何键。

(defun my/dired-copy-dirname-as-kill ()
  "Copy the current directory into the kill ring."
  (interactive)
  (kill-new default-directory))

PS:个人喜欢使用dired-jump从文件缓冲区跳转到当前目录


2
总体形式:C-x C-j 0 w - LionKimbro
你可以使用 C-x C-j C-x C-j C-0 w 来获取目录的路径,而不是使用 my/dired-copy-dirname-as-kill - Ben

32

我使用这个:

(defun my-put-file-name-on-clipboard ()
  "Put the current file name on the clipboard"
  (interactive)
  (let ((filename (if (equal major-mode 'dired-mode)
                      default-directory
                    (buffer-file-name))))
    (when filename
      (with-temp-buffer
        (insert filename)
        (clipboard-kill-region (point-min) (point-max)))
      (message filename))))

6
不需要使用临时缓冲区,可以使用"kill-new"命令来实现:(let ((x-select-enable-clipboard t))(kill-new filename)) - sanityinc

27

Emacs Prelude中,我使用:

(defun prelude-copy-file-name-to-clipboard ()
  "Copy the current buffer file name to the clipboard."
  (interactive)
  (let ((filename (if (equal major-mode 'dired-mode)
                      default-directory
                    (buffer-file-name))))
    (when filename
      (kill-new filename)
      (message "Copied buffer file name '%s' to the clipboard." filename))))

2
prelude-copy-file-name-to-clipboard 命令已不再是 Prelude 的一部分。正如删除它的提交消息所建议的那样,考虑使用 easy-kill 包替代。 - ack

22
如果你想要编写当前缓冲区的名称/路径,可以输入C-u M-:,然后选择(buffer-file-name)获取完整路径或者选择(buffer-name)获取缓冲区名称。

即:

M-: + ellisp表达式会在迷你缓冲区中评估一个ellisp表达式

C-u将输出写入当前缓冲区

这并没有确切回答问题,但如果有人偶尔使用此函数或其他函数,并且不希望在每次启动时初始化该函数,则可能会有用。同时请注意保留HTML标记。

2
为了正确回答这个问题,可以随后使用M-- C-M-k(杀死上一个sexp)。猜想这有点繁琐,但可以用作宏。 - rsenna
4
M-: (kill-new (buffer-file-name)) 将完整的文件名/路径复制到剪贴板/kill-ring,或者 M-: (kill-new (buffer-name)) 只复制文件名。 - Rob H

18
在 Spacemacs 分发版中,你可以按下 Spacefyy。它会弹出许多选项供你选择复制(例如缓冲区名称、文件名称、带行号的文件路径等等)。 spacemacs/copy-file-name 函数似乎源自这篇博客文章:Emacs: Show Buffer File Name
(defun camdez/show-buffer-file-name ()
  "Show the full path to the current file in the minibuffer."
  (interactive)
  (let ((file-name (buffer-file-name)))
    (if file-name
        (progn
          (message file-name)
          (kill-new file-name))
      (error "Buffer not visiting a file"))))

这个实现的源代码简短而精炼。我会将其复制/粘贴到这里,以便即使链接更改,答案仍然可用。我最喜欢这段代码。 - PatS
1
@PatS 好建议。我注意到这个函数最初是由别人编写的,所以我也添加了一个礼貌链接到那篇博客文章。 - Dag Høidahl
在更新的Spacemacs上,SPC f y会带出许多选项;例如,SPC f y y会复制完整路径,而SPC f y Y则会复制相对于存储库根目录的路径。非常方便! - Fred Schoen

6
如果你使用Doom Emacs,可以通过SPC f y完成。

6

这里有一个名为buffer-extension的工具,它具有copy-buffer-file-name-as-kill函数。它甚至会询问您要复制什么:名称,完整名称还是目录名称。

编辑

我使用从buffer-extension.el中修改过的copy-buffer-file-name-as-kill函数:

(defun copy-buffer-file-name-as-kill (choice)
  "Copyies the buffer {name/mode}, file {name/full path/directory} to the kill-ring."
  (interactive "cCopy (b) buffer name, (m) buffer major mode, (f) full buffer-file path, (d) buffer-file directory, (n) buffer-file basename")
  (let ((new-kill-string)
        (name (if (eq major-mode 'dired-mode)
                  (dired-get-filename)
                (or (buffer-file-name) ""))))
    (cond ((eq choice ?f)
           (setq new-kill-string name))
          ((eq choice ?d)
           (setq new-kill-string (file-name-directory name)))
          ((eq choice ?n)
           (setq new-kill-string (file-name-nondirectory name)))
          ((eq choice ?b)
           (setq new-kill-string (buffer-name)))
          ((eq choice ?m)
           (setq new-kill-string (format "%s" major-mode)))
          (t (message "Quit")))
    (when new-kill-string
      (message "%s copied" new-kill-string)
      (kill-new new-kill-string))))

4

这里有很多好的答案,但我认为对于问题中描述的“最简单的方法”,还有改进的空间。以下是我想出来的(感谢其他答案提供的部分):

M-: (kill-new (buffer-file-name)) RET

这正是你要求的--获取当前缓冲区的文件名,并将其放入“kill ring”中,根据你的设置,也可能放入系统剪贴板。(有关此部分的更多详细信息,请参见emacswiki/CopyAndPaste。)

如果您想经常执行此操作,则设置一个类似其他答案中列出的函数,并将其绑定到可用的键序列上,将使其更容易频繁执行。但以上操作无需任何先前设置,我认为这更“简单”。


1
喜欢这个答案,与历史记录中的C-r很搭配,尤其是如果您持久保存它的话。 - joao

0

将当前文件路径粘贴到缓冲区中,我看到最简单的方法是执行:C-u M-! pwd(这可能在Windows系统上无法正常工作)。

或者,您可以使用C-x C-b来显示所有打开缓冲区的文件路径。


0

这是在MacOS 10.15.7和GNU Emacs 27.1上对我有效的方法。

(defun copy-current-buffer-file-name ()
  (interactive)
  (shell-command (concat "echo " (buffer-file-name) " | pbcopy")))

将按键绑定设置为"C-x M-f":

(global-set-key (kbd "C-x M-f") 'copy-current-buffer-file-name)

提醒一下:对于真正的初学者来说,你需要将这些行添加到你的init.el文件中。


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