✍️

タイポ修正を支える技術

2023/07/05に公開

本記事はVim駅伝7月5日の記事として投稿しています。

はしがき

私は良く打ち間違えをします。タイポの達人です。

functionfuncitonと入力してしまったり returnretrnと入力してしまうことが良くあります。これは tiru のように左右の手を交互に動作するときに、押下のタイミングがズレることが原因です。

最近ならChatGPTにコードを渡せば良しなに修正してくれそうな問題ですが、一単語のタイポ修正のために毎回APIを叩いていたらキリがありません。今回は古典的な手法でタイポを自動修正するプラグインを作ったので共有します。

つくったもの

vim-typo_demo.gif

Vimのプラグインを作りました。設定は要りません。

インストールさえすれば動きます。対応言語は シンタックスハイライトされる言語全て です。

Jetpack 'tani/vim-typo'

https://github.com/tani/vim-typo

タイポとは

タイポとは、文字列の欠落 (functon)、入れ替え (funciton)、追加 (functioon) が行なわれた不正な入力を指します。タイポとされる文字列は上記の条件を満していればタイポと呼ばれていますが、私のタイポ歴を省みると、上記の操作以外に以下の制限がありそうです。

  • 先頭の文字と末尾の文字は間違え難い。(打ち始め・終りは正確なので)
  • 両手で6文字くらい入力するとミスをする。(左右3文字づつ)
  • 余分な文字を入力することは少ない。(タイミングがズレるだけで運指は問題ない)

タイポと編集距離

編集距離の概念を用いると、ある単語からタイポになりうる可能性のある文字列を列挙することができます。編集距離とは文字列に対して行った編集操作 (追加、削除、置換) の回数です。

たとえば、functonfunction の間の編集距離は1です。

今回は、この距離を応用してタイポ距離を定義します。タイポ距離は、タイポ(削除、入れ替え) の回数です。

たとえば、functionfunciton の間の編集距離は2ですが、タイポ距離は1です。

ある単語 wに対してタイポ距離がn以下のタイポの集合は、文字列操作で帰納的に構成することができます。

\mathrm{Typo}(w, n) = \begin{cases} \{w\} & (n = 0)\\ \{w\}\cup \mathrm{Typo}(\mathrm{del}(w), n - 1) \cup \mathrm{Typo}(\mathrm{swp}(w), n - 1) & (n > 0) \end{cases}

短縮入力 (abbreviation)

さて、vimや多くのテキストエディタには短縮入力 (abbreviation) という機能が搭載されています。これは、特定の単語が入力されたときに別の単語に自動で置き換えてくれる機能です。たとえば、 fn と入力したら function に展開するように登録することができます。

これは、原始的なスニペット機能として使うことができるので是非つかってみてください。Vimの場合、:abbreviate で登録することができます。

abbreviate fn function

今回はこの機能を用いて、タイポ — 正例 の間を短縮入力として登録することにします。

abbreviate functon function

正しい単語 w に対して \operatorname{Typo}(w, n) を一括で短縮入力に登録します。

これによってタイポとされる単語が入力されると、自動で正しい単語に修正されるようになります。

関連

この短縮機能を用いたタイポ修正は 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でシンタックスハイライトが有効なプログラミング言語なら全てタイポを修正してくれます。

懸念事項としては、例えば constcost のように、どちらも妥当な単語ですが、タイポ距離が1であるために勝手に修正されてしまうことがあります。そのため、このプラグインは冒頭にあるような「6文字以上で、先頭末尾を除く文字の削除と入れ替えのみ」という制限を加えています。タイポ修正の能力はやや弱いですが、安全に動作すると思います。

GitHubで編集を提案

Discussion