Linux の X Window System で動作するキーリマップソフト x-set-keys を作りました

# x-set-keys とは

Linux の X Window System で動作するキーバインディング変更ソフトです。

- 配布元 : https://github.com/kawao/x-set-keys
- ライセンス : [GPLv3](http://www.gnu.org/licenses/gpl.html)

# 特徴

- Emacs 風なキーバインドのカット、コピー、ペースト操作に対応しています。
- マルチストロークキーに対応しています。
例えば、 Control+x と Control+c を順にタイプすると、 Alt+F4(アプリケーションの終了) がタイプされたようにすることができます。
また、 Control+k をタイプして、 Shift+End と Constol+x を順にタイプしたのと同じ効果(行削除)をもたらすこともできます。
- アプリケーションに任意のキーを送信することができます。
例えば上の例で、Control+k を行削除だけではなく、 Control+k そのものをアプリケーションに送信することができます。
- Fcitx で日本語入力中は、キーリマップ機能を OFF にすることができます。

サンプルの設定ファイル emacslike.conf を使えば、(ほぼ)全てのアプリケーションを Emacs 風なキーバインドで操作することができます。

# インストール

現在のところ、x-set-keys はソースコードでしか配布されておりませんので、ソースコードを取得して、ご自身でビルドしていただく必要があります。
なお、x-set-keys は、C言語で開発されています。

## ビルドに必要なソフト

- GNU C compiler (Debian/Ubuntu のパッケージは gcc)
- X11 client-side library (Debian/Ubuntu のパッケージは libx11-dev)
- Development files for the GLib library (Debian/Ubuntu のパッケージは libglib2.0-dev)

## ソースコードの取得

[GitHub](https://github.com/kawao/x-set-keys) からアーカイブをダウンロードして展開するか、以下のコマンドを実行して Git リポジトリのクローンを生成します。

```sh
$ git clone https://github.com/kawao/x-set-keys
```

## ビルド＆インストール

以下を実行すると、実行バイナリ(x-set-keys)が/usr/local/bin にインストールされます。

```sh
$ cd x-set-keys
$ make
$ sudo make install
```

$HOME/bin ディレクトリにインストールする場合は、以下のコマンドを実行します。

```sh
$ make PREFIX=$HOME install
```

または、以下でも同じです。

```sh
$ make INSTALLBIN=$HOME/bin install
```

# 設定ファイル

設定ファイルにどのようにキーバインディングを変更するかを記載します。
サンプルの設定ファイル emacslike.conf は、Emacs 風のキーバインディングを実現します。
この節では、このファイルの内容に従って設定ファイルの説明を行います。

## 基本的なキーマップ

```
C-i :: Tab
C-m :: Return
C-g :: Escape
C-h :: BackSpace
C-d :: Delete
```

上記の設定は、以下の意味になります。

- Control+i を Tab に置き換える。
- Control+m を Enter に置き換える。
- Control+g を Escape に置き換える。
- Control+h を BackSpace に置き換える。
- Control+d を Delete に置き換える。

上記の通り、「 :: 」の前に変換前のキーシーケンスを、後ろに変換後のキーシーケンスを記述します。
Control などのモディファイアキーは、下記のように表記します。

- **A-** : Alt
- **C-** : Control
- **M-** : Meta
- **S-** : Shift
- **s-** : super

キーの名前は、ヘッダファイル [X11/keysymdef.h](https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h) に記載されています(先頭の `XK_` を削除してください)。

## カーソル操作

```
C-a :: Home
C-e :: End
C-b :: Left
C-f :: Right
C-p :: Up
C-n :: Down
A-v :: Page_Up
C-v :: Page_Down
A-b :: C-Left
A-f :: C-Right
C-bracketleft S-bracketleft :: C-Up
C-bracketleft S-bracketright :: C-Down
C-bracketleft S-comma :: C-Home
C-bracketleft S-period :: C-End
```

上記は、以下の意味になります。

- Control+a を Home に置き換える。
- Control+e を End に置き換える。
- Control+b を 左矢印 に置き換える。
- Control+f を 右矢印 に置き換える。
- Control+p を 上矢印 に置き換える。
- Control+n を 下矢印 に置き換える。
- Alt+v を Page Up に置き換える。
- Control+v を Page Down に置き換える。
- Alt+b を Control+Left に置き換える(前の単語へ)。
- Alt+f を Control+Right に置き換える(次の単語へ)。
- キーシーケンス Control+\[ \{ を Control+Up に置き換える(前の段落へ)。
- キーシーケンス Control+\[ \} を Control+Down に置き換える(次の段落へ)。
- キーシーケンス Control+\[ < を Control+Home に置き換える(ドキュメントの先頭へ)。
- キーシーケンス Control+\[ > を Control+End に置き換える(ドキュメントの末尾へ)。

上記で、キーシーケンスは、複数のキーを順にタイプすることを意味します。
例えば、 Control+\[ \{ は Control+\[ と \{ を順にタイプすることを意味します。

## カット、コピー、ペースト

```
C-space :: $select
A-w :: C-c
C-w :: C-x
C-y :: C-v
A-d :: S-C-Right C-x
C-k :: S-End C-x
```

上記の **$select** は、選択開始・終了を意味する特別な記法です。

上記の設定で、テキストをコピー(カット)するには、Control+スペース をタイプし、次にテキストカーソルを移動させ(カーソル操作キーを使用)、最後に Alt+w (Control+w) をタイプします。

その他の部分の意味は以下の通りです。

- Control+y を Control+v に置き換える(ペースト)。
- Alt+d を キーシーケンス Shift+Control+Right Constol+x に置き換える(単語削除)。
- Control+k を キーシーケンス Shift+End Constol+x に置き換える(行削除)。

## アンドゥ、ファイル(ウィンドウ)コマンド

```
C-slash :: C-z
C-s :: C-f
C-r :: C-S-g
C-x C-f :: C-o
C-x C-s :: C-s
C-x k :: C-w
C-x C-c :: A-F4
```

上記は、以下の意味になります。

- Control+/ を Control+z に置き換える(アンドゥ)。
- Control+s を Control+f に置き換える(テキスト検索)。
- Control+r を Control+Shift+g に置き換える(前のテキストを検索)。
- キーシーケンス Control+x Control+f を Control+o に置き換える(ファイルを開く)。
- キーシーケンス Control+x Control+s を Control+s に置き換える(ファイルを保存)。
- キーシーケンス Control+x k を Control+w に置き換える(ファイル/タブを閉じる)。
- キーシーケンス Control+x Control+c を Alt+F4 に置き換える(アプリケーション終了)。

## 任意のキーをアプリケーションに送る

```
C-q C-q :: C-q
```

設定ファイルに未定義のキーは、そのままアプリケーションに送信されます。
なので、上記の設定を行うと、Control+q の次にタイプしたキーは、すべてそのままアプリケーションに送信されます(最初の Control+q は、アプリケーションには送信されません)。

# 実行方法

```
# x-set-keys [オプション...] <設定ファイル>
```

x-set-keys の実行には、ルート権限が必要です。

## オプション

### -h, --help

使用法を表示して終了します。

### -d, --device-file=`<デバイスファイル>`

キーボードのデバイスファイルを指定します。
このオプションが省略された場合、 x-set-keys は /dev/input/event\* からキーボードデバイスを探して、最初に見つかったものを使用します。

### -e, --exclude-focus-class=`<クラス名>`

入力フォーカスウィンドウのクラス名がこのオプションで指定されたクラス名と一致するときは、x-set-keys はキーリマップ処理を行いません。
ウィンドウのクラス名は、 `xprop WM_CLASS` コマンドを実行して調べることができます。
このオプションは、複数回指定できます。

### -f, --exclude-fcitx-im=`<インプットメソッド>`

「インプットメソッド」には「mozc」などのインプットメソッドの名前を指定します。
Fcitx のアクティブなインプットメソッドがこのオプションで指定されたインプットメソッドと一致する間は、x-set-keys はキーリマップ処理を行いません。
このオプションを使用して、日本語入力中にキーリマップ処理を停止させることができます。
このオプションを指定した場合、x-set-key は sudo を使って実行しなければならず、また、環境変数 `DBUS_SESSION_BUS_ADDRESS` を sudo 実行前から引き渡してやる必要があります(下の実行例を参照してください)。
このオプションは、複数回指定できます。

## 実行例

```sh
$ sudo -b /usr/local/bin/x-set-keys \
     --exclude-focus-class=emacs --exclude-focus-class=Gnome-terminal \
     /usr/local/etc/x-set-keys/emacslike.conf
```

上の例では、設定ファイルに /usr/local/etc/x-set-keys/emacslike.conf を指定して、 x-set-keys を実行しています。
キーボードデバイスは、自動で検出されます。
また、インプットフォーカスが Emacs または Gnome-terminal のときは、キーリマップ処理が行われません。

```sh
$ sudo -b G_MESSAGES_PREFIXED=all /usr/local/bin/x-set-keys \
     --device-file=/dev/input/by-id/usb-Topre_Corporation_Realforce-event-kbd \
     --exclude-focus-class=emacs24 /usr/local/etc/x-set-keys/emacslike.conf
```

上の例では、キーボードデバイスに東プレの REALFORCE を指定しています。
また、環境変数 `G_MESSAGES_PREFIXED=all` は、 x-set-keys の出力メッセージにプログラム名と PID を前置させることを指定しています。

```sh
$ sudo -b G_MESSAGES_PREFIXED=all \
     DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \
     /usr/local/bin/x-set-keys \
       --exclude-focus-class=Emacs \
       --exclude-fcitx-im=mozc \
       /usr/local/etc/x-set-keys/emacslike.conf
```

上の例では、Fcitx の mozc による日本語入力中は、キーリマップ処理が行われません。
この機能を使うためには、例のように環境変数 `DBUS_SESSION_BUS_ADDRESS` を sudo の前から引き渡してやる必要があります。

## x-set-keys をパスワード無しで起動する

ログイン時に x-set-keys を自動起動する場合など、 x-set-keys をパスワード無しで起動したい場合、`visudo` コマンドを使って、/etc/sudoers の末尾に以下の行を追加します。

```
yourname ALL=(ALL) SETENV:NOPASSWD: /usr/local/bin/x-set-keys
```

# 関連ソフト

- [autokey](https://code.google.com/archive/p/autokey/)
- [x11keymacs](http://yashiromann.sakura.ne.jp/x11keymacs/index.html)

x-set-keys の開発にあたって、 x11keymacs のソースを参考にさせていただきました。
作者様には大変感謝しております。ありがとうございます。

# 最後に

ではみなさま、快適な Linux ライフをお過ごしください。