Help us understand the problem. What is going on with this article?

【NTEmacsユーザー向け】find-fileの入力時に、ミニバッファにヤンクしたファイルパスの`\`が`/`に変わるようにした

検証version: emacs26

動機

チャットやメールなどに貼ってもらった共有フォルダ内のパスを使ってDiredを開きたいけど、
パス中のフォルダの区切りがバックスラッシュになっているので開けない。スラッシュに置換するのがめんどくさい。。。
しょうがなく、エクスプローラーを使っていた。

実現したいこと

流れ

  1. Windowsのファイルパスをクリップボードにコピー
    • こんなやつ → C:\フォルダ1\フォルダ1.1\ファイルA.txt
  2. Emacsをアクティブにし、find-fileをインタラクティブに実行(C-x C-f)
  3. クリップボードからkill-ringの先頭へ追加された1のファイルパスをyankする(C-y)
    Find file: C:/フォルダ1/フォルダ1.1/ファイルA.txt
  ファイルA.txt

また、冒頭でも述べたように、使いたいファイルパスは共有フォルダのもの。
find-fileのミニバッファにヤンクしたとき以下のように変わってくれると、とても嬉しいですね。

クリップボードにコピーしたパス

  • 10.35.83.2\フォルダ1\フォルダ1.1\
 Find file: U:/フォルダ1/フォルダ1.1/
./
../
ファイルA
ファイルB
ファイルC

※ 共有フォルダのあるサーバをネットワークドライブとして登録しておくと、Emacsから開けるようになります。上の例でUドライブに設定しています。

前提

  1. OSのクリップボードとEmacsのkill-ringの同期を有効になっている

    確認方法
    変数save-interprogram-paste-before-killを評価してください。

    出力がnilであれば無効になっているので、下のS式をロードパスの通ったEmacs-Lispのファイルに追加しましょう。

     (setq save-interprogram-paste-before-kill t)
    
  2. 対象の共有フォルダがネットワークドライブとして割り当てられている

    確認方法
    こちらを参照してください。

  3. cl.elが読み込まれている

    以下が、ロードパスの通ったEmacs-Lispファイルのどこかに書いてあることを確認してください。

(require 'cl)

Common Lispのcase関数を使います。

方法

以下をロードパスの通ったEmacs-Lispのファイルに追加してください。

(defvar network-drives '(("u:" . "//10.35.83.2")
                         ("U:" . "//10.35.83.2")
             ;;↑の例のように、前提の2で確認、または新規登録したドライブをコンスセルとして書いておく
             ))

(add-hook 'minibuffer-inactive-mode-hook
          '(lambda ()
             (let ((clipbord (gui-selection-value)))
               (unless (null clipbord)
                 (setq kill-ring (cons clipbord kill-ring))
                 (setq kill-ring-yank-pointer kill-ring)))
             (unless (null kill-ring)
               (unless (null kill-ring-yank-pointer)
                 (let ((a (s-replace "\\" "/" (car kill-ring)))
                       (number 0))
                   (while (< number (length network-drives))
                     (case (string-match (cdr (nth number network-drives)) a)
                       (0
                        (setq kill-ring (cons (s-replace (cdr (nth number network-drives)) (car (nth number network-drives)) a) kill-ring ))
                        (setq number (length network-drives)))
                       (t
                        (setq kill-ring (cons a kill-ring))
                        (setq number (1+ number))
                        ))
                     (setq kill-ring-yank-pointer kill-ring)
                     ))))))

逆のケース

共有フォルダの中のファイルをEmacsで開いていて、そのパスを共有したいときもあるのではないでしょうか。

以下の関数を実行すると、クリップボードに現在のファイルのパスが入ります。
このとき、ファイルパスのスラッシュはバックスラッシュになり、ネットワークドライブの表示は登録したもとのパスに置換されます。

(defun put-current-path-to-clipboard ()
  (interactive)
  (let ((file-path buffer-file-name)
        (dir-path default-directory))
    (defun convert-path-as-windows(path)
      (let ((a path)
            (number 0))
        (while (< number (length network-drives))
          (when (string-match (car (nth number network-drives)) a)
            (setq a (s-replace (car (nth number network-drives)) (cdr (nth number network-drives)) a))
            (setq number (length network-drives))
            )
          (setq number (1+ number)))
        (s-replace "/" "\\" a)))
    (cond (file-path
           (kill-new (convert-path-as-windows file-path))
           (message "(%s) --> clipboard" (convert-path-as-windows file-path)))
          (dir-path
           (kill-new (convert-path-as-windows dir-path))
           (message "(%s) --> clipboard" (convert-path-as-windows dir-path)))
          (t
           (error-message-string "Fail to get path name.")))))

上記関数を好みのキーバインドに設定するとより良いと思います。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした