📖

AutoHotKey を使って Windows で Mac の Emacs 風キーバインドモードの有効/無効を切り替えられるようにする

2024/12/16に公開

概要

このスクリプトは、Emacs風キーバインド(Ctrl+hCtrl+b など)をWindows上で再現し、テキスト編集時の操作性を向上させるものです。また、Ctrl+Alt+E というショートカットで、これらのEmacs風キーバインドを有効化・無効化できるようにしているため、他のアプリケーションのショートカット操作と干渉する場合でも簡単にオン・オフを切り替えられます。

自分がMacで使っているショートカットのみ設定を書いたので、すべてのショートカットを移行してはいない点はご注意ください。

さらに、Alt+a を押すことで元々の Ctrl+a(全文選択)の動作を呼び出せます。これにより、Emacsモードをオンにしていても手軽に全文選択が可能になります。

なお、設定には AutoHotKey を使用しています。

記載するコードの説明は行いますが、AutoHotKey 自体の解説はドキュメントをご参照ください。

以下の記事もわかりやすかったです。

コード全文

#Requires AutoHotkey v2.0

global EmacsMode := false

; Ctrl+Alt+E で Emacsモードをトグル
^!e:: {
    global EmacsMode
    EmacsMode := !EmacsMode
    ToolTip(EmacsMode ? "Emacs Mode: ON" : "Emacs Mode: OFF")
    SetTimer(() => ToolTip(""), -1000) ; 1秒後にツールチップを消す
}

#HotIf EmacsMode

$^h::Send("{Backspace}")
$^b::Send("{Left}")
$^f::Send("{Right}")
$^n::Send("{Down}")
$^p::Send("{Up}")
$^e::Send("{End}")
$^a::Send("{Home}")
$^d::Send("{Delete}")
$^k::Send("{Shift down}{End}{Shift up}^x")
$!a::Send("{Ctrl down}a{Ctrl up}")

#HotIf

コード解説

ヘッダー部分

#Requires AutoHotkey v2.0

この行は「このスクリプトはAutoHotkey v2.0以降で実行する必要がある」ことを明示します。

global EmacsMode := false

EmacsModeというグローバル変数を定義します。
初期値はfalse(オフ)で、後述のショートカットでオン・オフを切り替えます。

Emacsモードのトグル(ON/OFF)

^!e:: {
    global EmacsMode
    EmacsMode := !EmacsMode
    ToolTip(EmacsMode ? "Emacs Mode: ON" : "Emacs Mode: OFF")
    SetTimer(() => ToolTip(""), -1000)
}

^!e は「Ctrl+Alt+E」を意味します。
このホットキーでEmacsModeの値を反転させ、ON/OFFを切り替えます。
ToolTip()で状態を表示し、SetTimer()で1秒後にツールチップを消します。

HotIfディレクティブとEmacsキーバインド

#HotIf EmacsMode

#HotIfは条件付きでホットキーを有効/無効にするディレクティブです。
EmacsModeがtrueのときのみ、以下のホットキーが有効になります。

Emacs風キーバインド

$^h::Send("{Backspace}")
$^b::Send("{Left}")
$^f::Send("{Right}")
$^n::Send("{Down}")
$^p::Send("{Up}")
$^e::Send("{End}")
$^a::Send("{Home}")
$^d::Send("{Delete}")
$^k::Send("{Shift down}{End}{Shift up}^x")

Ctrl+h → Backspace
Ctrl+b → 左矢印(←)
Ctrl+f → 右矢印(→)
Ctrl+n → 下矢印(↓)
Ctrl+p → 上矢印(↑)
Ctrl+e → Endキー
Ctrl+a → Homeキー
Ctrl+d → Deleteキー
Ctrl+k → 行末まで選択し、Ctrl+xでカット(Emacsのキルライン操作)

HotIfの解除

#HotIf

ここで#HotIfを解除し、以降のホットキーはEmacsModeの状態に依存しなくなります。

全文選択ショートカット

!a::Send("{Ctrl down}a{Ctrl up}")

Alt+aでCtrl+aを送信し、全文選択を実行します。

使い方

スクリプトを.ahk拡張子で保存します。
AutoHotkey v2がインストールされていれば、スクリプトをダブルクリックで実行可能です。
起動時にこのファイルが有効になってほしい場合はスタートアップに登録してください。

Ctrl+Alt+EでEmacs風キーバインドをオンにできます。Emacs Mode: ONと表示されます。
オフにする場合は再度Ctrl+Alt+Eを押します。Emacs Mode: OFFと表示されます。
EmacsMode の場合、Alt+aで全文選択が可能です。

注意点

Emacsモード有効時はCtrl+aなどが本来の動作(全文選択)を上書きします。
他のアプリケーションで通常使うCtrl+aなどのショートカットを再利用するには、EmacsModeをオフにしてください。

まとめ

最初は各ショートカットの挙動自体を別の挙動に変える方向で設定を書いていたのですが、アプリケーションや状況によってはデフォルトの挙動であってほしいというのを叶えるためにこのような設定ファイルを書きました。

より良いやり方がほかにあれば知りたいです。

Discussion