タイポ修正を支える技術
本記事はVim駅伝7月5日の記事として投稿しています。
はしがき
私は良く打ち間違えをします。タイポの達人です。
function
を funciton
と入力してしまったり return
を retrn
と入力してしまうことが良くあります。これは t
と i
や r
と u
のように左右の手を交互に動作するときに、押下のタイミングがズレることが原因です。
最近ならChatGPTにコードを渡せば良しなに修正してくれそうな問題ですが、一単語のタイポ修正のために毎回APIを叩いていたらキリがありません。今回は古典的な手法でタイポを自動修正するプラグインを作ったので共有します。
つくったもの
Vimのプラグインを作りました。設定は要りません。
インストールさえすれば動きます。対応言語は シンタックスハイライトされる言語全て です。
Jetpack 'tani/vim-typo'
タイポとは
タイポとは、文字列の欠落 (functon
)、入れ替え (funciton
)、追加 (functioon
) が行なわれた不正な入力を指します。タイポとされる文字列は上記の条件を満していればタイポと呼ばれていますが、私のタイポ歴を省みると、上記の操作以外に以下の制限がありそうです。
- 先頭の文字と末尾の文字は間違え難い。(打ち始め・終りは正確なので)
- 両手で6文字くらい入力するとミスをする。(左右3文字づつ)
- 余分な文字を入力することは少ない。(タイミングがズレるだけで運指は問題ない)
タイポと編集距離
編集距離の概念を用いると、ある単語からタイポになりうる可能性のある文字列を列挙することができます。編集距離とは文字列に対して行った編集操作 (追加、削除、置換) の回数です。
たとえば、functon
と function
の間の編集距離は1です。
今回は、この距離を応用してタイポ距離を定義します。タイポ距離は、タイポ(削除、入れ替え) の回数です。
たとえば、function
と funciton
の間の編集距離は2ですが、タイポ距離は1です。
ある単語
短縮入力 (abbreviation)
さて、vimや多くのテキストエディタには短縮入力 (abbreviation) という機能が搭載されています。これは、特定の単語が入力されたときに別の単語に自動で置き換えてくれる機能です。たとえば、 fn
と入力したら function
に展開するように登録することができます。
これは、原始的なスニペット機能として使うことができるので是非つかってみてください。Vimの場合、:abbreviate
で登録することができます。
abbreviate fn function
今回はこの機能を用いて、タイポ — 正例 の間を短縮入力として登録することにします。
abbreviate functon function
正しい単語
これによってタイポとされる単語が入力されると、自動で正しい単語に修正されるようになります。
関連
この短縮機能を用いたタイポ修正は https://zenn.dev/monaqa/articles/2020-12-22-vim-abbrev を参考にさせていただきました。
構文ファイルからキーワード抽出
前節でタイポの自動修正の手法を紹介しました。最後にタイポになりうる単語の収集方法を紹介します。多くのテキストエディタにはシンタックスハイライトというソースコードの各要素に色付けを行うためのキーワードを列挙したファイルが同梱されています。Vimの場合は、各プラグインの syntax/
ディレクトリ の中にシンタックスハイライト用の設定ファイルがあります。
そして、Vimに同梱されているソースコード補完エンジン syntaxcomplete#Complete
は、このシンタックスハイライト用のファイルを解析してキーワードを抽出していることが知られています。この補完エンジンは set omnifunc=syntaxcomplete#Complete
で有効化することができます。これ自体はビルトインの機能なので、とくにプラグインをインストールする必要はありません。
今回は、このエンジンと同様の手法を取ることにします。まず、ファイルが読み込まれてシンタックスハイライトが適用された段階で、キーワードを構文設定ファイルから抽出して、そのキーワードをもとに On-the-flyでタイポ辞書を作成します。これは syntaxcomplete#OmniSyntaxList
によってキーワードにアクセスできます。
Vim プラグインについて
このプラグインはもともと自分の設定ファイルにあったタイポ修正スクリプトをプラグインとして切り出したものです。普通、タイポ修正プラグインは個別の辞書を持っており、プラグインの作者が興味あるプログラミング言語しかタイポを対応していないという問題があります。
このスクリプトは、このような固定辞書に不満をあったので、構文ハイライトから修正単語を自動生成させることを検討し、作ったものになります。Vimでシンタックスハイライトが有効なプログラミング言語なら全てタイポを修正してくれます。
懸念事項としては、例えば const
と cost
のように、どちらも妥当な単語ですが、タイポ距離が1であるために勝手に修正されてしまうことがあります。そのため、このプラグインは冒頭にあるような「6文字以上で、先頭末尾を除く文字の削除と入れ替えのみ」という制限を加えています。タイポ修正の能力はやや弱いですが、安全に動作すると思います。
Discussion