【試み】macOS SierraでEmacsライクなキー操作(のごく基本的な部分)を再現する

シェアする

  • このエントリーをはてなブックマークに追加
  • 277
MacBook 12inch

Mac OS用のキー操作変更ソフトとして長年愛用してきたKarabinerがSierraでは動かないということで、どうしたものかと困っていました。

個人的にはEmacsライクにカーソルの移動とコピペができれば文句はないので、Keyhac for Macを使って簡単な操作だけできるようにしました。


スポンサーリンク

Keyhac for Mac

Keyhac for Macはキー入力をフックして、その動作をPythonのスクリプトで書いたとおりにカスタマイズできるという素晴らしいソフトウェアです。

Keyhac – Pythonによる柔軟なキーカスタマイズツール
https://sites.google.com/site/craftware/keyhac-ja

以前からWindows用を愛用していますが、今回はMac用を使わせていただきます。

思い通りの動作をさせるには自分でPythonのスクリプトをいじらなくてはなりませんが、同梱のスクリプトや詳しいマニュアルが用意されているので、それらを見ればなんとかなるでしょう。(今回は簡単なキーの置き換えだけなので、なんとかなると信じてやりました)


できるようにしたこと

今回できるようにしたのは次の項目です。

  • カーソルの上下左右への移動(Control+[P][N][F][B])
  • カーソルの行頭・行末への移動(Control+[A][E])
  • バックスペース(Control+[H])
  • Delete(Control+[D])
  • 範囲選択の開始(Control+スペース)
  • 選択部分のカット(Control+[W])
  • 選択部分のコピー(Esc-[W])
  • クリップボードからペースト(Control+[Y])
  • 行のカーソル位置以降のカット(Control+[K])
  • ページアップ(Esc-[V])
  • ページダウン(Control-[V])

これらのうちいくつかはMac OSでは初めからできたりするのですが、私が愛用しているMicrosoft OneNoteではなぜかうまくいかないものがあるので、OneNoteでこれらの動作をさせることを目標としました。

で、用意したスクリプトがこちらです。

import time
import sys
import os.path
import re


from keyhac import *
from keyhac_keymap import *
from keyhac_hook import *


def configure(keymap):

    # Global keymap which affects any windows
    keymap_global = keymap.defineWindowKeymap()


    # 以下、キー操作の置き換え定義
    # Ctrl-?の最後にU-Ctrlがあるのは、Ctrl-?の連続操作が効かなくなる問題への対策

    # カーソルの移動
    keymap_global[ "Ctrl-A" ] = "Cmd-Left" , "U-Ctrl"
    keymap_global[ "Ctrl-E" ] = "Cmd-Right" , "U-Ctrl"
    keymap_global[ "Ctrl-F" ] = "Right" , "U-Ctrl"
    keymap_global[ "Ctrl-B" ] = "Left" , "U-Ctrl"
    keymap_global[ "Ctrl-P" ] = "Up" , "U-Ctrl"
    keymap_global[ "Ctrl-N" ] = "Down" , "U-Ctrl"

    # 改行
    keymap_global[ "Ctrl-M" ] = "Enter" , "U-Ctrl"

    # 削除
    # Ctrl-HのShiftキー押し・放しはOneNoteでCtrl-Hが機能しないことがある問題への対策
    keymap_global[ "Ctrl-H" ] = "D-Shift" , "U-Shift" , "Back" , "U-Ctrl" 
    keymap_global[ "Ctrl-D" ] = "Delete" , "U-Ctrl"

    # 範囲選択・カット・コピー・ペースト・スクロール
    keymap_global[ "Ctrl-K" ] = "D-Shift" , "Cmd-Right" , "U-Shift" , "Cmd-X" , "U-Ctrl"
    keymap_global[ "Ctrl-Y" ] = "Cmd-V" , "U-Ctrl"
    keymap_global[ "Ctrl-Space" ] = "D-Shift" , "U-Ctrl"

    keymap_global[ "Esc" ] = keymap.defineMultiStrokeKeymap("Esc")
    keymap_global[ "Esc" ][ "W" ] = "U-Shift" , "Cmd-C"
    keymap_global[ "Esc" ][ "V" ] = "Ctrl-Up"
    keymap_global[ "Esc" ][ "Esc" ] = "Esc"

    keymap_global[ "Ctrl-W" ] = "U-Shift" , "Cmd-X" , "U-Ctrl"
    keymap_global[ "Ctrl-V" ] = "Ctrl-Down" , "U-Ctrl"

スクリプトとか言ってますが、実際はただ置換の定義を書いただけです。

これで大体のケースには対応できていますが、一つだけ不満があります。

  • OneNoteでControl-Kが一発では効かない
    OneNoteでControl-Kとやると、一度目はカーソル以降行末までの選択のみが行われ、二度目でようやくカットされます。
    一度目もちゃんとCommand-Xの呼び出しはしているのですが、OneNoteによって無効と判定されているようです。「ブッ」というエラー音が鳴って失敗します。
    範囲選択からCommand-Xの間にディレイを入れてみることも試しましたが、効果はありませんでした。

まあ、これでやりたいことはほとんどできているので、当分の間はこの設定で戦いたいと思います。

以上、同じようなことをやりたい方の参考になれば。