feature image

2022年9月24日 | ブログ記事

Rustでエンジニアは絶対に使えない「TypoIME」を作ろう

こんにちは、@toshi00です。
IME使ってますか? 文字入力をサポートする便利なソフトウェアIME。ですが、今回はプログラミングには絶対に使えない超不便なIMEを作る話です。RustでmacOS向けのIMEを制作しました。

traP LT2022で発表したものをまとめ直した内容となっています。
夏のブログリレー2022の46日目の記事です。

TypoIMEのコンセプト

TypoIME はあなたの英数字入力を"支援"します。アルファベットがこっそり変換される最悪のIMEです。

世の中には、フォントによってはほとんど見分けのつかない文字があります。例えば、lIや、0Oはうっかり入れ替わっていても気づきにくいでしょう。資料やブログ記事程度なら気にせず読み飛ばしてしまう程度の差です。

conceptv2

しかし、プログラミングにおいては1文字の違いがあまりにも重大で悲惨な結果を生み出します。

例えば、

conso1e.log("hoge")

たった1文字、l1に変わっただけですが、conso1e is not defined と怒られ、動いてくれません。悲しい。

プログラミングを繰り返す中で、1文字の違いにも注意を向けられるエンジニアだからこそ、使えない最悪のIME、それがTypoIMEです。

TypoIMEを使ってみた

コードはGithubで公開しています。
入力に対して、ランダムに文字が変換されていることを確認できます。

input : hello world!
output: heI1o worId!

demo

設定画面に自分の作ったIMEが表示されているとなんだかわくわくしますね。
config

TypoIMEはmacOS向けのIMEです。make appでビルド&パッケージ化してください。生成されたtypoIME.app/Library/Input Methodsに配置し、PCでログアウト→再ログインすることで読み込まれます。その後、環境設定 > キーボード > 入力ソース:英語からTypoIMEを追加し、選択することで(たぶん)動きます。

技術の話

ざっくり、TypoIMEの構成要素についてまとめます。ほとんど触ったことがなかったという理由で言語はRustを選択しました。

Cocoa

macOSには、Cocoaというアプリケーション構築用フレームワーク(API)があります。これを利用してIMEを実装していきます。今回使ったのは、InputMethodKitと呼ばれる、文字入力を取り扱う機能です。主に下の2つを利用しました。

CocoaAPIを使ったIMEの実装方針は3種類くらいありそうです。今回はその中でもシンプルそうな、キーバインディングを利用した方法で実装しました。IMKInputControllerを継承して、TypoInputControllerを実装しました。

今回は放置したのですが、候補選択を実装したい場合は IMKCandidates というクラスを触るようです。

参考: InputMethodKit | Apple

RustからCocoaを触る

InputMethodKitは、主にObjective-Cで記述されています。Rustから使えるクレートを探したのですが、見つけることができず……
結局、Rustからobjcクレートを使い、直接Objective-Cを記述することで実装しました。

こんな感じで、こつこつObjective-CのコードをRustに置き換えていきます。

// [IMKServer alloc]
let server_alloc: id = msg_send![class!(IMKServer), alloc];

この部分は、正直なところあまりRustの嬉しさを感じられませんでした。Rustは触り始めたばかりなので、なにか良い方法を見つけたら修正していきたいですね。

実行ファイルをApp形式にする

実行ファイルとアイコンや設定をApp形式というパッケージにする必要があります。実態は、.appの拡張子と以下のディレクトリ構造です。

typoIME.app
└── Contents
    ├── Info.plist
    ├── MacOS
    │   └── typo_ime
    └── Resources
        └── icon.icns

それぞれファイルは以下の内容になっています。

Info.plistの設定項目についていくつか紹介します。

項目 内容
CFBundleExecutable 実行ファイル名、typo_imeと指定
CFBundleIdentifier .inputmethod. を含んだ id を指定
LSBackgroundOnly 1 (=True)と設定。IMEはバックグラウンドのみで実行されるため。
InputMethodConnectionName 他のIMEと競合しないコネクション名を指定
InputMethodServerControllerClass InputControllerを継承したサブクラス名
tsInputMethodIconFileKey キーボード環境設定に表示されるアイコン画像
tsInputMethodCharacterRepertoireKey 今回は英数字用なので Latn

まとめ

RustでしょうもないIME、「TypoIME」を制作しました。macOS向けIMEは、SwiftやObjective-C、Rubyで作られている例が多そうです。が、あえてRustで作ってみるのもいかがでしょうか?

後日談

traP LTで発表したとき、様々な反応をいただき大変嬉しかったです。その中でも記憶に残っているのがこちら。

競プロの A 問題レベルを TypoIME 使って早解き対決するみたいなネタとか、面白そうなことができそう

……天才!? エディタの拡張機能とかあったらいいんじゃね……?

ということで、VSCode向けの拡張機能を制作しました。次回へ続きます!!!
明日の記事も @toshi00 がお送りします!


GitHub - toshi-pono/TypoIME: typoIME は、英数字入力を支援する macOS 向け IME です。
typoIME は、英数字入力を支援する macOS 向け IME です。. Contribute to toshi-pono/TypoIME development by creating an account on GitHub.
Rustで エンジニアは絶対に使えない「TypoIME」を作ろう
IME自作のすすめRustで エンジニアは絶対に使えない「TypoIME」を作ろう#traP_LT 2022 制作物『TypoIME』:https://github.com/toshi-pono/TypoIME
toshi00 icon
この記事を書いた人
toshi00

20B 作りたいものをなんでも作る

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2022年9月16日
5日でゲームを作った #tararira
Komichi icon Komichi
2023年12月25日
オレオレRustプロジェクトテンプレート
H1rono_K icon H1rono_K
2023年12月16日
MacからWindowsを弄る方法?~RDP環境を作ろう~
Alt--er icon Alt--er
2023年9月27日
夏のブログリレーは終わらない【駄文】
Komichi icon Komichi
記事一覧 タグ一覧 Google アナリティクスについて