目的
emacsのキーバインドをEclipseやAtomなど、使いたいアプリケーションに応じて、個別に調べて設定するのは大変。にもかかわらず、本当にあったらうれしいキーバインドはC-hなどシンプルなものだけ。であれば、OSのキーバインドをフックして全般的に変えてくれる系がうれしい。
そこで、AutoHotkeyを使って自分が必要な最低限のキーバインドだけを残し、かつIMEのトグルとAutoHotkey自信のON/OFFも切り替えられるように調べてScriptを作る。
ダウンロード&インストール
AutoHotkeyからWindowsインストーラをダウンロード。
そのインストーラを叩くだけ。
設定の作成
ネットにあるemacsのSciptを参考に作る。変更後の設定は、この最後尾に載せる。
emacsキーバインドで有効にしているもの
各ソフトのキーバインドと被るので、最小限のみ。
- C-f, C-b, C-n, C-pの十字移動
- C-a, C-eの先頭末尾移動
- C-h, C-dの削除
- C-mの改行
IMEの設定
IMEはC-oで切り替えたいので、AutoHotkeyを流行らせるアップローダ跡地から089のIMEの切り替えよう関数の設定をダウンロードして、下記のコードを埋め込む。
#Include IME.ahk
^o::
If is_target()
Send %A_ThisHotkey%
Else
{
getIMEMode := IME_Get()
If (%getIMEMode% = 0)
{
IME_SET(1)
Return
}
Else
{
IME_SET(0)
Return
}
}
Return
AutoHotkeyのON/OFF切り替え
どうしてもほかのソフトとバッティングする場合は、一時停止したい。C-@にSuspendを割り当てる。通知領域にAutoHotkeyを表示しておくと、Suspend中はSになる。
^@::
Suspend, Toggle
Return
全設定
;;
;; An autohotkey script that provides emacs-like keybinding on Windows
;;
#InstallKeybdHook
#UseHook
#Include IME.ahk
; The following line is a contribution of NTEmacs wiki http://www49.atwiki.jp/ntemacs/pages/20.html
SetKeyDelay 0
; turns to be 1 when ctrl-x is pressed
is_pre_x = 0
; turns to be 1 when ctrl-space is pressed
is_pre_spc = 0
; Applications you want to disable emacs-like keybindings
; (Please comment out applications you don't use)
is_target()
{
IfWinActive,ahk_class ConsoleWindowClass ; Cygwin
Return 1
IfWinActive,ahk_class MEADOW ; Meadow
Return 1
IfWinActive,ahk_class cygwin/x X rl-xterm-XTerm-0
Return 1
IfWinActive,ahk_class MozillaUIWindowClass ; keysnail on Firefox
Return 1
; Avoid VMwareUnity with AutoHotkey
IfWinActive,ahk_class VMwareUnityHostWndClass
Return 1
IfWinActive,ahk_class Vim ; GVIM
Return 1
; IfWinActive,ahk_class SWT_Window0 ; Eclipse
; Return 1
; IfWinActive,ahk_class Xming X
; Return 1
; IfWinActive,ahk_class SunAwtFrame
; Return 1
; IfWinActive,ahk_class Emacs ; NTEmacs
; Return 1
; IfWinActive,ahk_class XEmacs ; XEmacs on Cygwin
; Return 1
Return 0
}
delete_char()
{
Send {Del}
global is_pre_spc = 0
Return
}
delete_backward_char()
{
Send {BS}
global is_pre_spc = 0
Return
}
kill_line()
{
Send {ShiftDown}{END}{SHIFTUP}
Sleep 50 ;[ms] this value depends on your environment
Send ^x
global is_pre_spc = 0
Return
}
open_line()
{
Send {END}{Enter}{Up}
global is_pre_spc = 0
Return
}
quit()
{
Send {ESC}
global is_pre_spc = 0
Return
}
newline()
{
Send {Enter}
global is_pre_spc = 0
Return
}
indent_for_tab_command()
{
Send {Tab}
global is_pre_spc = 0
Return
}
newline_and_indent()
{
Send {Enter}{Tab}
global is_pre_spc = 0
Return
}
isearch_forward()
{
Send ^f
global is_pre_spc = 0
Return
}
isearch_backward()
{
Send ^f
global is_pre_spc = 0
Return
}
kill_region()
{
Send ^x
global is_pre_spc = 0
Return
}
kill_ring_save()
{
Send ^c
global is_pre_spc = 0
Return
}
yank()
{
Send ^v
global is_pre_spc = 0
Return
}
undo()
{
Send ^z
global is_pre_spc = 0
Return
}
find_file()
{
Send ^o
global is_pre_x = 0
Return
}
save_buffer()
{
Send, ^s
global is_pre_x = 0
Return
}
kill_emacs()
{
Send !{F4}
global is_pre_x = 0
Return
}
move_beginning_of_line()
{
global
if is_pre_spc
Send +{HOME}
Else
Send {HOME}
Return
}
move_end_of_line()
{
global
if is_pre_spc
Send +{END}
Else
Send {END}
Return
}
previous_line()
{
global
if is_pre_spc
Send +{Up}
Else
Send {Up}
Return
}
next_line()
{
global
if is_pre_spc
Send +{Down}
Else
Send {Down}
Return
}
forward_char()
{
global
if is_pre_spc
Send +{Right}
Else
Send {Right}
Return
}
backward_char()
{
global
if is_pre_spc
Send +{Left}
Else
Send {Left}
Return
}
scroll_up()
{
global
if is_pre_spc
Send +{PgUp}
Else
Send {PgUp}
Return
}
scroll_down()
{
global
if is_pre_spc
Send +{PgDn}
Else
Send {PgDn}
Return
}
^f::
If is_target()
Send %A_ThisHotkey%
Else
forward_char()
Return
^d::
If is_target()
Send %A_ThisHotkey%
Else
delete_char()
Return
^h::
If is_target()
Send %A_ThisHotkey%
Else
delete_backward_char()
Return
^o::
If is_target()
Send %A_ThisHotkey%
Else
{
getIMEMode := IME_Get()
If (%getIMEMode% = 0)
{
IME_SET(1)
Return
}
Else
{
IME_SET(0)
Return
}
}
Return
^g::
If is_target()
Send %A_ThisHotkey%
Else
quit()
Return
^m::
If is_target()
Send %A_ThisHotkey%
Else
newline()
Return
!s::
If is_target()
Send %A_ThisHotkey%
Else
isearch_forward()
Return
;$^{Space}::
^vk20sc039::
If is_target()
Send {CtrlDown}{Space}{CtrlUp}
Else
{
If is_pre_spc
is_pre_spc = 0
Else
is_pre_spc = 1
}
Return
^@::
Suspend, Toggle
Return
^a::
If is_target()
Send %A_ThisHotkey%
Else
move_beginning_of_line()
Return
^e::
If is_target()
Send %A_ThisHotkey%
Else
move_end_of_line()
Return
^p::
If is_target()
Send %A_ThisHotkey%
Else
previous_line()
Return
^n::
If is_target()
Send %A_ThisHotkey%
Else
next_line()
Return
^b::
If is_target()
Send %A_ThisHotkey%
Else
backward_char()
Return