■ Windows版 Emacs 共通の設定
■ Windows Subsystem for Linux の Emacs で利用できる設定


【お知らせ】


<2021/02/05 追記>
本ページの内容は WSL2 でも動作します。DrvFs や VolFs の記載がある場合には、Windows 側のファイルシステム、WSL2 側のファイルシステムと読み替えてください。

<2018/06/27 追記>
こちらの情報を参考としています。ありがとうございます。

<2018/06/21 追記>
Emacs-26系では、default- で始まる変数が廃止されたため、本設定が正常に動作しなくなりました。その対策を行いました。

<2017/09/04 追記>
Emacs への影響が最小限となるように見直したバージョンを次のページにまとめました。本ページの設定よりもこちらの設定の利用をお勧めします。



<2017/06/21 追記>
本設定は、Windows Subsystem for Linux 上で動作している Emacs から Windows ファイルシステムを参照する場合にも利用可能です。次の設定と組み合わせてご利用ください。(21番は必須の設定です。)

<2017/05/01 追記>
本設定は、VirtualBox 上の Linux 上で動作している Emacs から Windows ファイルシステムを参照する場合にも利用可能です。次の設定(最低、4番までの設定が必要)と組み合わせてご利用ください。
※ NTFS シンボリックリンクも辿りたい場合は、全ての設定が必要です。

<2017/04/13 追記>
w32-symlinks.el の中で再定義(defun)している insert-file-contents-literally は、既に Emacs 本体に統合されたコードのように見えます。insert-file-contents-literally が定義されているところにあるコメントにも、一時的にコードを載せているものであることが書かれています。実際に insert-file-contents-literally の定義の部分をコメントとしても、w32-symlinks.el は問題なく動作しているようです。(Emacs-24.5 で確認。)
また、もう一つ再定義(defun)している find-file についても、定義している箇所にあるコメントの内容から判断すると、本体側の find-file を使うことで問題ないようにも見えます。実際に定義をコメント化しても問題なく動作しているようです。
とりあえず、私は insert-file-contents-literally と find-file の再定義(defun)の部分はコメント化して利用してみています。今のところ、問題は出ていません。これが問題なければ、w32-symlinks.el をもう少し延命して使っていけるのではないかと思っています。

<2017/04/12 追記>
ショートカットファイルの仕様の資料が次にあります。

<2017/04/12 追記>
insert-file-contents-literally に対して適用していたアドバイスを次の内容に基づき変更しました。

<2015/05/16 追記>
gnupack-12.00 以降の Cygwin版 Emacs では、Cygwin の ln -s で作成したショートカットをシンボリックリンクとして認識してくれます。
(CYGWIN 環境変数がデフォルト設定である winsymlinks:lnk となっている場合です。Windows で作ったショートカットはシンボリックリンクとしては認識してくれません。)
 if set to just winsymlinks or winsymlinks:lnk, Cygwin creates symlinks as Windows shortcuts with a special header and the R/O attribute set.

【本題】



w32-symlinks を dired と連携して使うための設定です。

1) 次のページの elisp を有効にする。

2) ls-lisp を有効にする。
(require 'dired)
(require 'ls-lisp)

;; ls-lisp を使う
(setq ls-lisp-use-insert-directory-program nil)

;; dired の並び順を Explorer と同じにする
(setq ls-lisp-ignore-case t)          ; ファイル名の大文字小文字無視でソート
(setq ls-lisp-dirs-first t)           ; ディレクトリとファイルを分けて表示
(setq dired-listing-switches "-alG")  ; グループ表示なし
(setq ls-lisp-UCA-like-collation nil) ; for 25.1 or later

3) melpa から noflet package をインストールする。
(参考) http://emacs.rubikitch.com/noflet/

4) 以下の設定を行う。(その1)

Cygwin を使っている場合は、Emacs を起動する前に CYGWIN環境変数に次の意味合いの設定を行ってください。(gnupack-12.00 以降を使っている場合は、startup_config.ini の中に設定箇所があります。)
export CYGWIN="$CYGWIN winsymlinks:lnk"
Cygwin を使っていない場合は、このページに添付している w32-symlinks-ln-s.js というスクリプトを適当なフォルダに格納し、次のような設定を行ってください。(格納フォルダに合わせてパスの変更は適宜行ってください。)
(custom-set-variables '(w32-symlinks-ln-script (expand-file-name "~/w32-symlinks-ln-s.js")))

5) 以下の設定を行う。(その2)
(require 'noflet)

(custom-set-variables '(w32-symlinks-handle-shortcuts t))
(require 'w32-symlinks)

;; ショートカットのターゲット名の表示の仕方を決定する(non-nil -- just convert \ to /)
(custom-set-variables '(w32-symlinks-shortcut-target t))

;; ショートカットのターゲット名を表示するように対策する
(advice-add 'ls-lisp-insert-directory
            :around
            (lambda (orig-fun &rest args)
              (noflet ((directory-files-and-attributes
                        (&rest args2)
                        (mapcar (lambda (x) (set-attr-symlink x 'w32-symlinks-parse-symlink) x)
                                (apply this-fn args2))))
                (apply orig-fun args))))

;; ショートカットの判定が正しく機能するようにする
;; ショートカットのターゲット名が文字化けするのを対策する
;; ショートカットファイルをリネームや削除する際に出るエラーを抑制する
(advice-add 'w32-symlinks-parse-shortcut
            :around
            (lambda (orig-fun &rest args)
              (when (file-exists-p (nth 0 args))
                (noflet ((w32-symlinks-unicode-to-ascii (in)
                                                        (decode-coding-string in 'utf-16le))
                         (decode-coding-string (string coding-system)
                                               (funcall this-fn string
                                                        (if (eq coding-system 'utf-16le)
                                                            'utf-16le
                                                          ;; (detect-coding-string string t)))))
                                                          'undecided)))
                         (insert-file-contents-literally (filename)
                                                         (set-buffer-multibyte nil)
                                                         (funcall this-fn filename)))
                  (apply orig-fun args)))))

;; dired でシンボリックリンクとして認識される行(".lnk" を含まない行)は、w32-symlinks.el
;; で設定している dired-get-filename に対するアドバイスの処理を回避するように対策する
(advice-add 'dired-get-filename
            :around
            (lambda (orig-fun &rest args)
              (noflet ((looking-at (regexp)
                                   (funcall this-fn
                                            (replace-regexp-in-string "\\?" "" regexp))))
                (apply orig-fun args)))
            '((depth . -1)))

6) w32-symlinks.el の中の最後の方で再定義(defun)している find-file と insert-file-contents-literally の箇所をコメント化する。

<2017/04/13 追記> の内容による。


<変更履歴>
  • 2014/05/09 フォーマット整形を行った。(内容変更はなし)
  • 2017/04/09 新しいバージョンの Emacs でも正常に動作するように設定を見直しした。
  • 2017/04/20 dired-get-filename に対するアドバイスを追加した。
  • 2017/05/01 dired のソート順を制御する ls-lisp-UCA-like-collation の設定を追加した。
  • 2018/06/21 Emacs-26系では、default- で始まる変数が廃止されたため、本設定が正常に動作しなくなった。その対策を行った。


最終更新:2021年02月05日 09:36
添付ファイル