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


【お知らせ】


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

<2020/10/27 追記>
WSL2 では、UNC パスをマウントしているマウントポイント配下がカレントディレクトリの状態で Windows の exe コマンドを実行するとエラー終了します。wslclient にこの対策を行いました。

<2020/05/06 追記>
WSL2 で動かすために emacsclientw.exe コマンドの見直しを行いました。

<2019/11/14 追記>
emacsclient のオプションの解説は、以下を参照してください。

<2019/10/23 追記>
wslclient コマンドに、リターンコードと標準出力等に対応する対策を行いました。これで git のエディタとして利用する際のコミットキャンセルにも対応できるようになりました。

<2019/08/19 追記>
wslemacs-start.exe のタスクトレイアイコンのメニューにコンソールを表示/非表示する機能を追加しました。コンソール表示後、非表示に戻す際は、コンソールの閉じるボタン(☓)をクリックするのではなく、アイコンメニューから非表示(Hide Console)を選択してください。また、メニューの Exit は Kill Emacs という機能に変更しました。これは、AutoHotKey のアプリを終了させるのではなく、Emacs を終了させる機能に見直したことによります。Emacs が終了することにより、結果として AutoHotKey のアプリも終了します。(逆に、Emacs に「(kill-emacs)」を送っても Emacs が終了しない場合(Emacs が起動中の場合など)は、AutoHotKey のアプリも終了しません。)
なお、Emacs のアイコンをタスクトレイに常に表示させるようにすると、メニューを選択し易くなります。設定方法は次のページを参照してください。

<2019/08/09 追記>
1) に「<フレームの高さを補正する設定>」の説明を追記しました。

<2019/07/19 追記>
wslemacs-start.exe プロセス終了時、起動している Emacs に「(kill-emacs)」を送信するように見直しました。ただし、AutoHotKey の仕様でシャットダウンやログオフの場合に終了処理(OnExit)が走ることになっているのですが、実際にはうまく動作していないようです。

<2019/07/16 追記>
Emacs をデーモンモードで起動した際、起動した bash のコンソールを維持した場合と終了した場合とで、次の実行結果が異なることが分かりました。
 (shell-command-to-string "cmd.exe /c echo 'あああ' | nkf -g")
この結果から、Emacs を起動した bash を終了すると Emacs から exe コマンドを利用する際に不都合が発生することが分かりましたので、wslemacs-start.exe で起動する Emacs のオプションを --daemon から --fg-daemon に変更し、Emacs が起動中は bash が終了しないように対策しました。⇒(2019/07/23 追記)その後、Emacs を exec で起動しても問題ないことが分かりましたので、そのように見直しました。
この対策をした結果の副産物として、タスクトレイに wslemacs-start.exe の Emacs アイコンが表示されるようになり、Emacs デーモンが起動している状態を確認できるようになりました。

<2019/07/14 追記>
次の機能の不具合対策を行いました。

【本題】


Windows Subsystem for Linux の emacsclient を Windows から利用するための設定です。

1) 次のページを参考とし、Emacs が GWSL を使って起動できるように設定を行う。
上記の 10) の設定は行ってください。GWSL の起動や DISPLAY 環境変数の設定を行っています。
また、13) の「<フレームの高さを補正する設定>」も行ってください。WSL Emacs on GWSL でフレームを開く際、高さが低く作成される状況が改善されます。
さらに、21) で紹介している次の設定を行ってください。この設定は、本設定を使う上での 前提条件 となっています。
この設定をすることで、Emacs で指定するパスに Windows パスや UNC パスを指定できるようになり、以降で説明する wslclient 系コマンドが利用可能となります。

⇒ (注)ただし、wslclient.exe を起動するのみであれば、上記設定は不要です。wslemacs-start.exe を起動して Alt+e を押下した場合にも wslclient.exe が起動されていますが、このような使い方のみであれば、上記設定は不要となります。

2) DrvFs ファイルシステム上にフォルダを作成し、そのフォルダのパスを PATH に登録する。そして、そのフォルダに 次のリポジトリにあるコマンドを配置する。
※ Windows 10 1903 を利用している場合、PATH に登録するパスは DrvFs のフォルダへの実際のパス(シンボリックリンクではないパス)としてください。シンボリックリンクのパスを PATH に登録すると、exe コマンドが実行できなくなります。

3) wslclient.exe をコピーして、次の名称のコマンドを上記と同じフォルダ内に作成する。
wslclient.exe    # wait version (コピー元)
wslclient-n.exe  # no-wait version
wslclient-c.exe  # create-frame and wait version
wslclient-cn.exe # create-frame and no-wait version
※ 2) で紹介したリポジトリには、コピーを作成するための wslclient-copy.sh スクリプトも格納しています。

4) Emacs にタイトルフォーマットの設定("emacs" で始まるタイトルとする設定)を行う。上記でインストールした wslclient 系コマンドを使う場合に必要となる。
(setq frame-title-format (format "emacs-%s - %%b " emacs-version))
※ 別途公開している sglstart コマンドを利用している場合、%%b の後のスペースは必要

5) Emacs に emacs-server を立上げる設定を行う。これで、WSL 側で emacsclient が利用可能となる。(以降で紹介する Emacs のデーモンモードを利用する際には、server-start が自動起動されるため本設定は不要となります。)
(require 'server)

(unless (server-running-p)
  (server-start))
※ EDITOR 環境変数の設定をすることにより、git などとも連携が可能となります。
export EDITOR=emacsclient
※ WSL コンソールから Emacs on GWSL を間接的に使いたい場合は、次のようにすることもできます。(ウインドウフォーカスが移動します。)
export EDITOR=wslclient

6) Emacs をデーモンモードで起動する。

WSL コンソール起動時(bash 起動時)にインタラクティブな応答(例えば、 keychain や ssh-add 実行時のパスフレーズの入力など)が 無い 使い方をしている場合には、wslemacs-start.exe を実行することで Emacs を起動することができます。Windows の Startup フォルダに wslemacs-start.exe のショートカットを置くことで、ログイン時に自動起動させることもできます。

wslemacs-start.exe を終了するには、タスクトレイのアイコンを右クリックして Kill Emacs を選択してください。もしくは、wslemacs-stop.exe を実行することでも終了できます。

WSL コンソール起動時にインタラクティブな応答がある場合は、WSL コンソールを起動してから Emacs --daemon で Emacs を起動してください。
(2019/07/16 追記)次のページで紹介されている ssh-agent-wsl を利用することで、keychain や ssh-add 実行時のパスフレーズの入力を回避できる(OS を再起動しても ssh-add で登録した秘密鍵が保持され、パスフレーズの入力が不要となる)ことが分かりました。お試しください。
(2019/08/21 追記)wslemacs-start.exe を起動したときのタスクトレイのメニューにコンソールを表示する機能(Show Console)を追加しました。この機能を使えば、インタラクティブな応答がある場合でも、コンソールを表示して入力することができるようになりました。

Emacs を常時立ち上げて利用されている方は、デーモンモードでなく Emacs を直接立ち上げることでも構いません。

7) 次のページの方法で、3) で作成した wslclient 系コマンドの中から適当なコマンドのショートカットを SendTo フォルダに作成する。
これで Explorer の右ボタンメニューの「送る」機能で、ファイルやフォルダを wslclient 系コマンドに送る(で開く)ことができるようになります。作成するショートカットの名前を「n」で始めておくと、右ボタンでメニューを開いた後に n を二回押下するだけで、wslclient 系コマンドを開くことが可能となります。

上記の方法以外に、次の方法でも wslclient 系コマンドを起動させることができます。
  • wslclient 系コマンドとファイルの結びつけを行い、そのファイルをダブルクリックする。
  • wslclient 系コマンドのアイコンに開きたいファイルやフォルダをドラック&ドロップする。
また、次の方法で Emacs のフレームをアクティブに表示させることができます。
  • wslclient 系コマンドを直接ダブルクリックする。
  • wslemacs-start.exe で Emacs を起動している場合、Alt+e を入力する。
さらに、Thunderbird で外部エディタとして Emacs を使いたい場合は、wait version の wslclient.exe または wslclient-c.exe が利用できます。外部エディタの設定については、MinGW版 Emacs 用に作ったページですが、次の設定が参考になると思います。

8) Keyhac で以下のような設定を行う(オプション)。

この設定により、クリップボードにコピーした Windows パスや UNC パスをワンキーで Emacs で開けるようになります。

※ 「<Windows パス>」の部分は書き換えてお使いください。
※ 「Windows の操作を Emacs のキーバインドで行うための設定 (Keyhac版)」を利用する(している)場合には、拡張機能 emacsclient Extension を有効にしてください。
# -*- mode: python; coding: utf-8-with-signature-dos -*-
# http://qiita.com/hshimo/items/2f3f7e070ae75243eb8b

from keyhac import *

def configure(keymap):

    keymap_global = keymap.defineWindowKeymap()

    # emacsclient プログラムを起動するキーを指定する
    emacsclient_key = "C-Period"

    # emacsclient プログラムを指定する
    emacsclient_name = r"<Windows パス>\wslclient-n.exe"

    # emacsclient プログラムの起動
    def emacsclient():
        clipboard_text = getClipboardText()
        if clipboard_text:
            path = re.sub("\n|\r", "", clipboard_text.strip())
            path = re.sub(r'(\\+)"', r'\1\1"', path)
            path = re.sub('"', r'\"', path)
            path = re.sub('^', '"', path)
            keymap.ShellExecuteCommand(None, emacsclient_name, path, "")()

    keymap_global[emacsclient_key] = emacsclient


<変更履歴>
  • 2018/03/16 このページを作成した。
  • 2018/12/06 clipboard_text からパスを抽出する際、キャリッジリターン(\r)も除去するように対応した。
  • 2019/07/14 デーモンモードで起動した Emacs とでも連携して利用できるように見直した。
  • 2019/07/16 wslemacs-start.exe で起動する Emacs のオプションを --daemon から --fg-daemon に変更した。
  • 2019/07/18 wslemacs-start.exe で Emacs デーモンを起動する際、WSL のホームディレクトリから起動されるように設定を追加した。
  • 2019/07/19 wslemacs-start.exe プロセス終了時、起動している Emacs に (kill-emacs) を送信するように見直しした。
  • 2019/07/20 Alt+e で wslclient.exe が起動するように wslemacs-start.exe を見直しした。
  • 2019/07/26 WSL のスクリプト wslclient を使うための設定を追記した。
  • 2019/07/27 wslclient 系コマンドの wait バージョン wslclient-w.exe を使うための設定を追記した。
  • 2019/07/31 wslclient-w.exe の処理終了時の挙動を変更した。
  • 2019/08/19 wslemacs-start.exe のタスクトレイアイコンのメニューにコンソールを表示/非表示する機能を追加した。
  • 2019/10/20 emacsclientw.exe コマンドを作成し、wslemacs.exe コマンドと wslemacs-w.exe コマンドを emacsclientw.exe コマンドを利用するコマンドに見直した。
  • 2019/10/23 wslclient コマンドに、リターンコードと標準出力等に対応する対策を行った。
  • 2019/10/25 wslclient 系コマンドの仕様を見直した。
  • 2019/10/26 Fakeymacs の設定で、コピペしたパスにダブルコーテーションが含まれている場合の対策を行った。
  • 2020/05/06 WSL2 で動かすために emacsclientw.exe コマンドの見直しを行った。


最終更新:2022年10月20日 12:23