Sierra対応のためにkeyhacの設定ファイルをいじった


## 概要

Karabinerが使えないため、昔使っていた設定を下地にしつつごにょごにょして使ってみた

## 設定

```
# -*- coding: utf-8 -*-

"""
設定ファイル
Windowsから引き継いでコメントアウトしつつMacへ
"""

import datetime
# import os
import subprocess
# import sys

from keyhac import *
# from keyhac_clipboard import cblister_FixedPhrase
# from pyauto import *

def configure(keymap):
    """
    設定を書く
    """

    # _flg_1 = 1
    # _flg_0 = 0

    # --------------------------------------------------------------------
    # config.py編集用のテキストエディタの設定
    # Text editer setting for editting config.py file
    # Setting with program file path (Simple usage)

    keymap.editor = "Visual Studio Code"

    # --------------------------------------------------------------------
    # Customizing the display

    # Font
    keymap.setFont("Osakalt-Mono", 21)
    # Theme
    keymap.setTheme("black")

    # --------------------------------------------------------------------
    # キーの単純な置き換え

    # Mac英数
    keymap.replaceKey(102, "LCmd")
    # Macかな
    keymap.replaceKey(104, "RCmd")

    # --------------------------------------------------------------------
    # ユーザモディファイアキーの定義

    # 機能拡張に使うUser0
    keymap.defineModifier("(94)", "User0")

    # カーソル移動に使うUser1
    # スペース
    keymap.defineModifier("Space", "User1")

    # keymap.defineModifier("Shift-Cmd", "Shift-Cmd")
    # keymap.defineModifier("Shift-Cmd", "Shift-Cmd")

    # --------------------------------------------------------------------
    # キーマップ設定

    # どのウインドウにフォーカスがあっても効くキーマップ
    keymap_global = keymap.defineWindowKeymap()

    # --------------------------------------------------------------------
    # Mac版にて置き換えした「かな」でのアプリ切替の際にShiftを押すと選択される

    # keymap_global["Shift-(102)"] = "Shift-LCmd" # , "U-Ctrl"
    # keymap_global["Shift-LCmd"] = "Shift-LCmd" # , "U-Ctrl"
    # keymap_global["Shift-(104)"] = "Shift-RCmd" # , "U-Ctrl"
    # keymap_global["Shift-RCmd"] = "Shift-RCmd" # , "U-Ctrl"

    # --------------------------------------------------------------------
    # ウインドウ操作キーマップ

    # USER0-↑↓←→ : 10pixel単位のウインドウの移動
    keymap_global["User0-Left"] = keymap.MoveWindowCommand(-10, 0)
    keymap_global["User0-Right"] = keymap.MoveWindowCommand(+10, 0)
    keymap_global["User0-Up"] = keymap.MoveWindowCommand(0, -10)
    keymap_global["User0-Down"] = keymap.MoveWindowCommand(0, +10)

    # USER0-Shift-↑↓←→ : 1pixel単位のウインドウの移動
    keymap_global["User0-Shift-Left"] = keymap.MoveWindowCommand(-1, 0)
    keymap_global["User0-Shift-Right"] = keymap.MoveWindowCommand(+1, 0)
    keymap_global["User0-Shift-Up"] = keymap.MoveWindowCommand(0, -1)
    keymap_global["User0-Shift-Down"] = keymap.MoveWindowCommand(0, +1)

    # USER0-Ctrl-↑↓←→ : 画面の端まで移動
    keymap_global["User0-Ctrl-Left"] = keymap.MoveWindowToMonitorEdgeCommand(0)
    keymap_global["User0-Ctrl-Right"] = keymap.MoveWindowToMonitorEdgeCommand(2)
    keymap_global["User0-Ctrl-Up"] = keymap.MoveWindowToMonitorEdgeCommand(1)
    keymap_global["User0-Ctrl-Down"] = keymap.MoveWindowToMonitorEdgeCommand(3)

    # --------------------------------------------------------------------
    # クリップボード履歴

    # リスト表示
    keymap_global["Ctrl-Shift-Z"] = keymap.command_ClipboardList
    # 直近の履歴を末尾に回す
    keymap_global["Ctrl-Shift-X"] = keymap.command_ClipboardRotate
    # 直近の履歴を削除
    keymap_global["Ctrl-Shift-Alt-X"] = keymap.command_ClipboardRemove
    # 引用貼り付け時の記号
    keymap.quote_mark = "> "

    # --------------------------------------------------------------------
    # カーソル操作キーマップ
    # Ctrl-?の最後にU-Ctrlがあるのは、Ctrl-?の連続操作が効かなくなる問題への対策らしい

    keymap_global["User1-F"] = "Right" # , "U-Ctrl"
    keymap_global["User1-B"] = "Left" # , "U-Ctrl"
    keymap_global["User1-N"] = "Down" # , "U-Ctrl"
    keymap_global["User1-P"] = "Up" # , "U-Ctrl"

    keymap_global["User1-A"] = "Cmd-Left" # , "U-Ctrl"
    keymap_global["User1-E"] = "Cmd-Right" # , "U-Ctrl"
    keymap_global["User1-D"] = "Delete" # , "U-Ctrl"
    keymap_global["User1-H"] = "Back" # , "U-Ctrl"
    keymap_global["User1-M"] = "Return" # , "U-Ctrl"

    keymap_global["Shift-User1-F"] = "Shift-Right" # , "U-Ctrl"
    keymap_global["Shift-User1-B"] = "Shift-Left" # , "U-Ctrl"
    keymap_global["Shift-User1-N"] = "Shift-Down" # , "U-Ctrl"
    keymap_global["Shift-User1-P"] = "Shift-Up" # , "U-Ctrl"

    keymap_global["Shift-User1-A"] = "Shift-Cmd-Left" # , "U-Ctrl"
    keymap_global["Shift-User1-E"] = "Shift-Cmd-Right" # , "U-Ctrl"
    keymap_global["Shift-User1-D"] = "Shift-Delete" # , "U-Ctrl"
    keymap_global["Shift-User1-H"] = "Shift-Back" # , "U-Ctrl"
    keymap_global["Shift-User1-M"] = "Shift-Return" # , "U-Ctrl"

    keymap_global["Ctrl-User1-F"] = "Ctrl-Right" # , "U-Ctrl"
    keymap_global["Ctrl-User1-B"] = "Ctrl-Left" # , "U-Ctrl"
    keymap_global["Ctrl-User1-N"] = "Ctrl-Down" # , "U-Ctrl"
    keymap_global["Ctrl-User1-P"] = "Ctrl-Up" # , "U-Ctrl"

    keymap_global["Ctrl-User1-A"] = "Ctrl-Cmd-Left" # , "U-Ctrl"
    keymap_global["Ctrl-User1-E"] = "Ctrl-Cmd-Right" # , "U-Ctrl"
    keymap_global["Ctrl-User1-D"] = "Ctrl-Delete" # , "U-Ctrl"
    keymap_global["Ctrl-User1-H"] = "Ctrl-Back" # , "U-Ctrl"
    keymap_global["Ctrl-User1-M"] = "Ctrl-Return" # , "U-Ctrl"

    keymap_global["User1-U"] = "Shift-Home", "Delete" # , "U-Ctrl"
    keymap_global["User1-K"] = "Shift-End", "Delete" # , "U-Ctrl"

    # keymap_global["User1-Space"] = "Space" # , "U-Ctrl"

    # --------------------------------------------------------------------
    # local keymap

    # keymap_local = {}
    # for app in ["com.googlecode.iterm2", "org.vim.MacVim"]:
    #     keymap_local[app] = keymap.defineWindowKeymap(app_name=app)
    #     keymap_local[app]['Ctrl-b'] = 'Ctrl-b'
    #     keymap_local[app]['Ctrl-f'] = 'Ctrl-f'
    #     keymap_local[app]['Ctrl-n'] = 'Ctrl-n'
    #     keymap_local[app]['Ctrl-p'] = 'Ctrl-p'
    #     keymap_local[app]['Ctrl-w'] = 'Ctrl-w'
    #     keymap_local[app]['Alt-b'] = 'Alt-b'
    #     keymap_local[app]['Alt-d'] = 'Alt-d'
    #     keymap_local[app]['Alt-f'] = 'Alt-f'

    # for app in ["org.mozilla.firefox", "com.google.Chrome"]:
    #     keymap_local[app] = keymap.defineWindowKeymap(app_name=app)
    #     keymap_local[app]['Ctrl-b'] = 'Ctrl-b'
    #     keymap_local[app]['Ctrl-f'] = 'Ctrl-f'

    # for app in ["com.microsoft.Outlook"]:
    #     keymap_local[app] = keymap.defineWindowKeymap(app_name=app)
    #     keymap_local[app]['Ctrl-a'] = 'Home'
    #     keymap_local[app]['Ctrl-e'] = 'End'

    # --------------------------------------------------------------------
    # ワンショットモディファー

    # --------------------------------------------------------------------
    # Macのかなと英数の機能を左右のコマンドへあてる

    keymap_global["O-LCmd"] = keymap.InputKeyCommand("(102)")
    keymap_global["O-RCmd"] = keymap.InputKeyCommand("(104)")
    # keymap_global[ "O-LCmd" ] = "Cmd-Space"
    # keymap_global[ "O-RCmd" ] = "Cmd-Shift-Space"

    # --------------------------------------------------------------------
    # macのちょっと拡張された（？）JIS配列の一番右上

    # keymap_global["(93)"] = keymap.InputKeyCommand("RAlt-(93)")
    # keymap_global["LAlt-(93)"] = keymap.InputKeyCommand("(93)")
    keymap_global["(93)"] = "BackQuote"

    # --------------------------------------------------------------------
    # macのちょっと拡張された（？）JIS配列の一番右下

    # keymap_global["(94)"] = keymap.InputKeyCommand("RAlt-(94)")
    # keymap_global["LAlt-(94)"] = keymap.InputKeyCommand("(94)")
    keymap_global["Shift-(94)"] = "Shift-BackQuote"

    # --------------------------------------------------------------------
    # ユーザーモディファーのキーを一定組み合わせでワンショットモディファーにする
    # Space押しながら、Shift+Space押しながら、、、と定義していく

    for any_str in ("", "Shift-", "Ctrl-", "Ctrl-Shift-",
                    "Alt-", "Alt-Shift-",
                    "Alt-Ctrl-", "Alt-Ctrl-Shift-", "Fn-",
                    "Fn-Shift-", "Fn-Ctrl-",
                    "Fn-Ctrl-Shift-", "Fn-Alt-", "Fn-Alt-Shift-",
                    "Fn-Alt-Ctrl-", "Fn-Alt-Ctrl-Shift-"):
        keymap_global[any_str + "O-Space"] = any_str + "Space"
        # keymap_global[any_str + "User2-1"   ] = any_str + "F1"

    # --------------------------------------------------------------------
    # 自作関数の定義

    def _test_debug():
        """
        テスト キーデバッグ
        """
        if keymap.debug is True:
            keymap.debug = False
        elif keymap.debug is False:
            keymap.debug = True
        # print keymap.debug
    keymap_global["User0-D"] = _test_debug

    def _test_profile():
        """
        テスト プロファイル
        """
        if keymap.profile is True:
            keymap.profile = False
        elif keymap.profile is False:
            keymap.profile = True
        # print keymap.profile
    keymap_global["User0-P"] = _test_profile

    keymap_global["User0-C"] = keymap.command_EditConfig

    # def _config_reload():
    #     """
    #     設定の読み込み（Macだと再起動しないと読み込みできないことが多い）
    #     """
    #     keymap.command_ReloadConfig()
    #     keymap.configure()
    # keymap_global["User0-R"] = _config_reload

    # クリップボード履歴リスト表示のカスタマイズ

    def date_and_time(fmt):
        """
        日時をペーストする機能
        """
        def _date_and_time():
            """
            日時をペーストする機能
            """
            return datetime.datetime.now().strftime(fmt)
        return _date_and_time

    # 定型文（サンプルのまま。ベタ書きは避けたほうがいいかという気がする。）
    fixed_items = [
        (u"name@server.net", u"name@server.net"),
        (u"住所", u"〒東京都品川区123-456"),
        (u"電話番号", u"03-4567-8901"),
        (u"config.pyを編集", keymap.command_EditConfig),
        (u"config.pyをリロード", keymap.command_ReloadConfig),
    ]

    # 日時
    date_and_time_items = [
        (u"YYYY/MM/DD HH:MM:SS", date_and_time("%Y/%m/%d %H:%M:%S")),
        (u"YYYY/MM/DD", date_and_time("%Y/%m/%d")),
        (u"HH:MM:SS", date_and_time("%H:%M:%S")),
        (u"YYYYMMDD_HHMMSS", date_and_time("%Y%m%d_%H%M%S")),
        (u"YYYYMMDD", date_and_time("%Y%m%d")),
        (u"HHMMSS", date_and_time("%H%M%S")),
    ]

    keymap.cblisters += [
        (u"定型文", cblister_FixedPhrase(fixed_items)),
        (u"日時", cblister_FixedPhrase(date_and_time_items)),
    ]
```

## 挙動についての所感

JIS配列のままつかい、チルダの入力と自分用のキーマップを追加。
文字列を入力してからスペースでの変換が遅延する時がある感じがある。
動き的には、例えば、
文節が多い文章とかをIMEが入力していたり区切っている間に、
スペースの処理の受付を逃してしまうような感じの印象。
スムースに入力できることも多い。
制御がOSじゃなくて別プロセスだから遅延処理を綺麗にできないというような感じかしら。
今しがた、ことえりをやめてGoogle日本語入力にしたら改善された気がするが気のせいかもしれない。

## 追記、翻訳処理

```
    def _transrate(trans_opt):
        """
        翻訳
        """
        # import locale
        # enc = locale.getpreferredencoding()
        # env['PYTHONIOENCODING'] = enc
        command0 = '/usr/bin/pbpaste'
        command1 = '/usr/local/bin/perl -pe "s/\n/ /g"' # 改行をスペースに変更
        command2 = '/usr/local/bin/trans' + trans_opt
        #command3 = '/usr/local/bin/perl -pe "s/。 ?/。\n/g"' # 「句（読）点（＋スペース）」を改行付きに変更
        command3 = 'perl -pe "s/(。|、) */\\1\n/g"' # 句点を改行付きに変更
        command4 = '/usr/bin/pbcopy'
        env = os.environ.copy()
        env["PATH"] = "/usr/bin:/usr/local/bin/:" + env['PATH']
        # command0
        process0 = subprocess.Popen(shlex.split(
            command0), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        process0.wait()  # wait()は簡易的な実装
        # command1
        process1 = subprocess.Popen(shlex.split(
            command1), stdin=process0.stdout, stdout=subprocess.PIPE, env=env)
        process1.wait()  # wait()は簡易的な実装
        # Allow ps_process to receive a SIGPIPE if grep_process exits.
        process0.stdout.close()
        # command2
        process2 = subprocess.Popen(shlex.split(
            command2), stdin=process1.stdout, stdout=subprocess.PIPE, env=env)
        process2.wait()  # wait()は簡易的な実装
        # command3
        process3 = subprocess.Popen(shlex.split(
            command3), stdin=process2.stdout, stdout=subprocess.PIPE, env=env)
        process3.wait()  # wait()は簡易的な実装
        # command4
        process4 = subprocess.Popen(shlex.split(
            command4), stdin=process3.stdout, stdout=subprocess.PIPE, env=env)
        process4.wait()  # wait()は簡易的な実装

        # Allow ps_process to receive a SIGPIPE if grep_process exits.
        process1.stdout.close()
        process2.stdout.close()
        process3.stdout.close()
        process4.stdout.close()

        """
        通知
        """
        process0 = subprocess.Popen(shlex.split(
            command0), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        process0.wait()  # wait()は簡易的な実装
        output = process0.communicate()[0].decode('utf-8')
        process0.stdout.close()
        command3 = '/usr/bin/osascript -e \'display notification "'+output+'" with title "翻訳"\''
        subprocess.Popen(shlex.split(command3), env=env)

    def transrate_j2e():
        """
        翻訳
        """
        _transrate(' -b ja:en')
    def transrate_e2j():
        """
        翻訳
        """
        _transrate(' -b en:ja')
```