LoginSignup
12
8

More than 5 years have passed since last update.

AutoHotkeyでMac USキーボード完全互換を目指す

Last updated at Posted at 2018-08-02

この記事の目的

Windows環境 + MacのUSキーボードを使って、
あたかもMac + USキーボードでKarabinerを使っているような環境を構築する。

方法は、以下のステップで構成する
1,左右のwindowsキーを副作用の無い他のキーに変更する
2,AutoHotkeyを使って、キーコンビネーションを任意の機能に割り当てる
3,IMEの設定で、commandキー単体を押しをIME ON とIME OFFに割り当てる

キーの割り当て変更

まずchangeKeyなどのレジストリのキーボードマップをいじるツールを使って、commandキー(windowsではwinキーと認識される)を副作用の無い他のキーに割り当てる。副作用とは、キーを押したことで何かアクションが起こることを意味します。あとで、AutoHotkeyでコンビネーションショートカットを機能に割り当てますが、その時にキーの元の機能を完全には無効にできないため。

自分の場合は、左のwinキーをPause、右のwinキーをscroll lockに割り当てました。
(後で気づいたんですが、scroll lockの機能は、エクセルなどでカーソルキーで隣のセルに移動するか、スクロールするかを切り替えるので、完全に副作用なしとは行きませんでした。誰か他の副作用の無いキーがあったら教えてください。)

changeKeyで見ると以下のようになります。
(左のAltとctrlは自分の趣味です。ここでは必須では無いです)

changeKey

image.png

AutoHotkey

AutoHotkeyで割り当てを変更したPauseキーと任意のキーコンビネーションに機能を割り当てます。
ここでは、キー単体を押した時の設定は行いません。
あくまでもコンビネーションの割り当てのみです。

AutoHotkey.ahk
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetTitleMatchMode,2
#InstallKeybdHook
#UseHook

#ifWinActive Lightshot.exe

enter::
    winGetTitle, window_title, ahk_exe Lightshot.exe
    if inStr(window_title, "save")
        msgbox, "LWin+4"
;        send {enter}
    else send ^{s}
    return

#ifWinActive

;LControl::LAlt
vkFF::Send, {vk1D}  ;左Windowsキー to 無変換キー
ScrollLock::Send, {vk1C}  ;右Windowsキー to 変換キー
vkFF & Space::Send, ^{Esc}
vkFF & Enter::Send, ^{Enter}
vkFF & n::Send, ^{n}
vkFF & x::Send, ^{x}
vkFF & c::Send, ^{c}
vkFF & v::Send, ^{v}
vkFF & s::Send, ^{s}
vkFF & o::Send, ^{o}
vkFF & p::Send, ^{p}
vkFF & a::Send, ^{a}
vkFF & f::Send, ^{f}
vkFF & l::Send, ^{l}
vkFF & w::Send, ^{w}
vkFF & t::Send, ^{t}
vkFF & g::Send, ^{g}
vkFF & z::Send, ^{z}

Shift & Backspace::Send, {Del}

vkFF & Tab::AltTab

RAlt & Up::Send, {PgUp}
RAlt & Down::Send, {PgDn}
RAlt & Left::Send, {Home}
RAlt & Right::Send, {End}



vkFF & 4::
    If GetKeyState("Shift", "P")
        send, {PrintScreen}
    Else
        msgbox, "LWin+4"
    Return

vkFF & 3::
    If GetKeyState("Shift", "P")
        send, #{s}
    Else
        msgbox, "LWin+4"
    Return


;;
;; An autohotkey script that provides emacs-like keybinding on Windows

; 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 VirtualConsoleClass
    Return 1
  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
}
tab_window()
{
  Send !{Tab}
  global is_pre_spc = 0
  Return
}
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
}



;vkFF & Tab::
;  If is_target()
;    Send %A_ThisHotkey%
;  Else
;    tab_window()
;  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
^w::
  If is_target()
    Send %A_ThisHotkey%
  Else
    kill_region()
  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
^s::
  If is_target()
    Send %A_ThisHotkey%
  Else
    isearch_forward()
  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

IMEの設定

あとは、IMEの設定でキー単体押した時をIME ON とIME OFFに割り当てます。

12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8