きっかけ
ひさしぶりにデスクトップでデュアルブートしていたUbuntu 16.04を開こうとしたらくたばっていて、仕方なく18.04を新規インストールしてセットアップしているとかつてキーマップをどういじっていたのか思っていた操作ができない…
xmodmapとxcapeでなにやらいろいろやっていた覚えがあったのでやってみるも、fcitxにぶっ壊されてしまうし、キーマップがうまく動作していないように感じ、セットアップに無限に時間が吸われていってしまう…
調べてみるとxkeysnailというツールがたいへんよさそう。
というわけで導入、設定してみました。
環境
$ cat /etc/os-release NAME="Ubuntu" VERSION="18.04 LTS (Bionic Beaver)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 18.04 LTS" VERSION_ID="18.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic
xkeysnailとは
LinuxでうごくPython3で書かれたキーマッパです。Linux版Keyhacというところ。
xmodmapやxcapeがsudoなしに実行できるのに対し、xkeysnailはより低レイヤー(evdev
およびuinput
)で動作するためにsudoを必要とします。
そのため、使用に際し、権限を持たないユーザは使用できません。
また、X windowに依存するため、自動起動させる際にも注意が必要でしょう。今回はGnomeのautostart機能を利用しています。
- メリット
- fcitxと競合して設定が消し飛んだりしない
- アプリケーションごとにキーマップを設定可能
- multi strokeをサポート(
C-x
C-c
をC-q
にしたりできる) - キーリマップするだけでなく、Pythonの関数などを割り当てたりもできる
- いわゆるoneshot modifierが簡単にできる
- 低レベルレイヤーで動作するため、ほとんどの場合においてキーマップが動作する
- デメリット
- 情報が少ない
- sudoが必要
導入
xkeysnailのインストール
pipでインストールできます。
$ sudo apt install python3-pip $ sudo pip3 install xkeysnail $ which xkeysnail /usr/local/bin/xkeysnail $ xkeysnail -h
こうなります。
設定
基本的にここの2つの内容をそのまま踏襲させていただきました。
自動起動
自動起動させる方法も上記サイトに載ってはいますが、Gnomeでのベストプラクティスがよくわからなかったので、~/.config/autostart/
以下に.desktop
ファイルを配置することで起動スクリプトをログイン時に自動実行させることにしました。
まずは起動スクリプトです。
#!/usr/bin/env bash if [ -x /usr/local/bin/xkeysnail ]; then xhost +SI:localuser:xkeysnail sudo -u xkeysnail DISPLAY=:1 /usr/local/bin/xkeysnail /etc/opt/xkeysnail/config.py & fi
xhost
コマンドでxkeysnailユーザにアクセスを許可し、バックグラウンドでxkeysnailを起動します。これを/etc/opt/xkeysnail
に配置しておきます。
[Desktop Entry] Type=Application Version=1.0 Name=xkeysnail GenericName=Keymapper Exec=/etc/opt/xkeysnail/start-xkeysnail.sh Hidden=false NoDisplay=false X-GNOME-Autostart-enabled=true
あとは上記を適当にxkeysnail.desktop
などとして~/.config/autostart/
以下に配置すれば自動起動の一覧に表示されます。
キーリマップ
注意
僕はHHKB ProfessionalのUS配列を使用しています。
config.py
configはPythonで記述します。つまり文法はPythonそのものになるので下手なものを書けば当然syntax errorで落ちます。詳細はgithubのREADMEやexampleを見ましょう。
雛形はこうです。
# -*- coding: utf-8 -*- import re from xkeysnail.transform import * # something remap
Ctrl(またはCaps)単押しでEsc
まずはVimを使っている人には必須であろう(?)configを書きます。
# -*- coding: utf-8 -*- import re from xkeysnail.transform import * define_multipurpose_modmap({ Key.CAPSLOCK: [Key.ESC, Key.LEFT_CTRL], # CapsLockではなくCtrlの場合 # Key.LEFT_CTRL: [Key.ESC, Key.LEFT_CTRL], })
今までxmodmapとxcapeでごにょごにょやっていたのは何だったのか…
SandS
Space単押しでSpace、他のキーと組み合わせてShiftにします。
# -*- coding: utf-8 -*- import re from xkeysnail.transform import * define_multipurpose_modmap({ # SandS Key.SPACE: [Key.SPACE, Key.LEFT_SHIFT], })
Mac風IME切り替え
Ctrl + Space使いづらいので…
スペースの両側にあるAltをそれぞれ変換、無変換キーに割り当て、fcitxでそれぞれIMEのオン/オフに使用します。
# -*- coding: utf-8 -*- import re from xkeysnail.transform import * define_multipurpose_modmap({ Key.LEFT_ALT: [Key.MUHENKAN, Key.LEFT_CTRL], Key.RIGHT_ALT: [Key.HENKAN, Key.RIGHT_CTRL] })
fcitxの設定からそれぞれ入力メソッドのオン/オフに指定します。
Vim like cursor
Ctrl + hjklで矢印キーを入力します。
# -*- coding: utf-8 -*- import re from xkeysnail.transform import * define_keymap(None, { K('C-h'): Key.LEFT, K('C-j'): Key.DOWN, K('C-k'): Key.UP, K('C-l'): Key.RIGHT, }, "Vim-like cursor")
ログを見るとactive keymaps = [Vim-like cursor]
が出力されていると思います。このキーマップはすべてのアプリケーションで動作することを示しています。
Escしたときに自動でIMEオフ
Vimを使っているときに入力モードから抜ける際、日本語入力のままになっていると毎回IMEをオフにしないといけないのが面倒です。
Vimを使っているかどうかを検知することはできませんが、ターミナルを触っている際にEscを押したら自動で無変換を送信し、IMEをオフにしましょう。
# -*- coding: utf-8 -*- import re from xkeysnail.transform import * # 標準の端末ならGnome-terminal define_keymap(re.compile('Terminator'), { K('esc'): [K('muhenkan'), K('esc')] }, "Esc and IME off")
ターミナルにフォーカスがあたっているときだけログにactive keymaps = [Esc and IME off]
が出力されることがわかるかと思います。
ansible-role-xkeysnail
勉強のためにansible-galaxyにroleを登録してみました。Ubuntu 18.04 LTSで検証しています。
やっていることはセットアップの内容をそのまま記述しているだけです。
- python3-pipのインストール
- xkeysnailのインストール
- xkeysnail実行用グループおよびユーザの設定
/etc/udev/rules.d/40-udev-xkeysnail.rules
の記述/etc/modules-load.d/uinput.conf
の記述/etc/sudoers.d/
以下にxkeysnail用のNOPASSWD設定を記述- 起動スクリプトおよびconfig.pyの配置
~/.config/autostart/
以下に自動起動用.desktop
ファイルの追記
まとめ
しばらく常用していますがめちゃくちゃ安定していて最高です。
頑張って~/.Xmodmap
を書いたりするよりいいと思うのでおすすめです。