テキストを素早く挿入する手法の一つ Text Expansion についての雑多なまとめ


単語、文章、コード――テキストを素早く挿入したい場面は多々あります。実現方法もまた多様ですが、その中に Text Expansion という手法があります。国内ではこれといった呼び名が無いほどマイナー（？）みたいなので、今回取り上げてみることにしました。

# （はじめに）本記事の前提について

はじめに、本記事の前提というかスタンスを書いておきます。

- Windows 環境を前提にしています（UNIX系OSの方、ごめんなさい :bow: )
- Text Expansion のコア部分（テキストの挿入）についてのみ取り上げ、各ソフトウェアに付随する便利機能については取り上げません
- Text Expansion の考え方について述べており、具体的なソフトウェアの使用方法やノウハウについては取り上げていません

# Text Expansion とは

テキストを素早く挿入する手法の一つで、以下のようなものです。

![what_is_text_expansion.gif](https://qiita-image-store.s3.amazonaws.com/0/191170/e496cf9d-b2b3-fbd1-edee-232a6948b62c.gif)

指定の略語を打ち終えたと同時に、対応する文章が挿入されるという素早さが特徴です。

# 挿入手法の変遷

ここでは Text Expansion の存在意義をイメージするため、Text Expansion が生まれた背景を、他のメジャーな挿入手法からの変遷という形でまとめてみます。

## 辞書登録

おそらく最もメジャーな挿入手法だと思います。IME、ATOK、Google日本語入力――日本語入力システムもまた多数存在しますが、いずれにせよ **ユーザー辞書** という機能があります。

![userdict_googleja.jpg](https://qiita-image-store.s3.amazonaws.com/0/191170/b4cd959d-f619-5d56-f073-113cb9ad6a86.jpeg)

「読み」と「単語」の組を登録させておけば、読みを入力 → スペースキーで変換 → 変換候補に単語が出る、という流れで入力できるというものです。

ここで辞書登録の強み（ :o: ）と弱み（ :x: ）をまとめてみます。

- 辞書登録の特徴
  - :o: 特別なツール無しに使える（まあ IME 以外のシステムならインストールが必要ですけども）
  - :o: 変換という馴染み深い動作のため、直感的に扱える
  - :x: 必ず全角モードで打つ必要がある
  - :x: 複数行文字列やコードなど複雑な文章は登録できない
  - :x: 使用可能な読みに制限がある
      - たとえば記号が使えないとか、英文字だけはダメ、など
  - :x: 登録した読みと単語を暗記する必要がある
      - たとえば「めあど」で自身のメールアドレスに変換させる場合、「めあど」という読みを暗記してないと呼び出せない。
      - 組を100個登録すれば100個覚える必要がある。

弱みをまとめると「使える単語のバリエーションが弱い」「暗記が苦痛」となるでしょうか。

## 定型文挿入

詳しい歴史はわかりませんが、割と古くから存在する手法がもう一つあります。 **定型文挿入** です。

これは主にフリーソフトによって実現され、あらかじめ登録しておいた定型文をあの手この手で素早く呼び出して貼り付ける類のソフトになります。オンラインソフトウェアライブラリの Vector では [クリップボード](http://www.vector.co.jp/vpack/filearea/winnt/util/clipbrd/) というジャンルがあるように、様々なソフトウェアがあります。たとえば、

- メニューで一覧表示して、選択した定型文を貼り付けるタイプ
- キーワードを入力し、インクリメンタルサーチでヒットした候補の中から選んで貼り付けるタイプ
- （定型文ではないですが）クリップボードの履歴を記録して、後から選択・検索・貼り付けを行えるようにしたタイプ

などがありますね。国内で最も有名なのはおそらく [amuns:code](https://www.amunsnet.com/) さんの Clibor でしょう。

定型文挿入の強みと弱みは以下のとおりです。

- 定型文挿入の特徴
  - :o: 複数行文字列など **複雑な文章を登録** できる
  - :o: 一覧からの選択やインクリメンタルサーチなど **暗記しなくても定型文を入力しやすい機構** がある
  - :x: 文字入力の延長で自然に入力できない
      - たとえばファイル名編集中には使用できない(定型文ツールのウィンドウがアクティブになるためファイル名編集が終了してしまう)

辞書登録の欠点は解消できていますが、ソフト本体のウィンドウが間に入るため、どうしても自然な文字入力の延長で挿入することができません。人によってはそこがもどかしく感じることもあるでしょう。

## Text Expansion

そこで Text Expansion の登場です。概要は上述したので特徴に入ります。

- Text Expansion の特徴
  - :o: **文字入力の延長で自然に、素早く入力** できる
      - たとえばファイル名編集中でも挿入可能
  - :x: 仕様的なクセが強く学習コストが高い、カスタマイズに手間がかかる
  - :x: 業務でもフリーで利用できる決定版的なソフトが無い
  - :x: 略語を暗記しておく必要がある

自然さと素早さでは辞書登録、そして定型文挿入にも勝っています。ですが他の二つと比べると歴史が浅く、また何かとクセが強いため、習得や順応に時間がかかるデメリットもあります。

# Text Expansion の構成要素

次は Text Expansion の肝となる要素を見ていきましょう。

※正式に用いられる日本語は未だ無いという認識です。ここでは私の独断で選んだ言葉を用いています。

## 略語(Abbreviation)

冒頭の GIF でいうなら `itm[` にあたるものが **略語(Abbreviation)** です。英語では abbr などと略すこともあります。

## 本文(Snippet)

**スニペット** ともいいます。冒頭の GIF でいうなら `いつもお世話になっております` にあたるものです。

ここで Text Expansion について改めて書くと、

- (1) **略語と本文の組** を登録しておき
- (2) 略語を入力すると、
- (3) **即座に** 本文が挿入される

そんな仕組みだと言えるでしょう。

ちなみに略語と本文の組のことをスニペットと呼ぶこともあり、ちょっとややこしいです。本記事では **略語、本文 、スニペット（略語と本文の組）** で統一します。

## トリガー(Trigger)

Text Expansion では **誤発動** がよく起きます。本文を挿入するつもりがないのに、今打っている文章にたまたま「略語が部分文字列として含まれていた」時に、本文が挿入されてしまう……というものです。

これを防ぐ仕組みがあります。**略語 + 特別な文字** を打った時に初めて本文を挿入させる、というものです。この特別な文字（あるいはこのような機構そのもの）を **トリガー** と呼びます。

トリガーとしてよく使われるのは Tab、Space、Enter などです。これらはソフトウェア側の機能として特別に設定枠が用意されていたり（たとえばリストボックスから選択できるとか）します。また、これらトリガーには誤発動防止だけでなく、「単語の区切りを意識しやすい」という感覚的なやりやすさ、自然さの担保という効果もあります。

トリガーを使うかどうかは好みです。設定により使用するかどうかを切り替えることもできるので、お好きな方を使うと良いでしょう。

※補足: **手動トリガー** について。数字やアルファベットより使用頻度の少ない「記号類の文字」を略語の最後に入れることで、手動でトリガーを実現することもできます。この手動トリガーの場合、略語の先頭や中間に入れることもできるので、より柔軟な略語設定が可能です。

## マクロ(Macro)

**マクロ** とは、本文中に記載可能な、特別な効果を持つ文字列のことです。

たとえば現在時刻を挿入するマクロなどがあります。

マクロについて最も充実しているソフトはおそらく PhraseExpress でしょう。[PhraseExpress v12 Macro functions Manual](http://www.phraseexpress.com/docs12/09/macro.htm) を見ると（英語ですが）、色々なマクロがあります。

# 主な Text Expansion ソフトウェア

続いて、Text Expansion を実現する Windows ソフトウェアをいくつか紹介します。

## AutoHotkey

Windows 用キーカスタマイズとして名高い [AutoHotkey](https://autohotkey.com/) にも Text Expansion 機能があります。 **ホットストリング(HotString)** と呼びます。

以下は記述例です。上二行は私の好みの設定を書いています。ここは各自の好みで良いと思います。詳細は [ホットストリング - AutoHotkey Wiki](http://ahkwiki.net/Hotstrings) を参照してください。

```ahk
; 終了文字無しで発動させる
#Hotstring *
; 自動置換後、最後に終了文字を入力しない
#Hotstring O
::itm[::いつもお世話になっております
```

特徴をまとめます。

- AutoHotkey ホットストリングの特徴
  - :o: 設定を Text で書ける、管理できる
  - :o: その気になれば AutoHotkey の機能を応用してあれこれできそう
  - :x: スクリプトベースのため学習コストが高い
  - :x: 複数行の本文を設定する際に色々と面倒な制約がある
      - 私のやり方が悪いだけかもしれませんが :sweat:

## PhraseExpress

Text Expansion として最も名高いのは [PhraseExpress](http://www.phraseexpress.com/) でしょう。英語ではありますが、使用されているブロガーさん、エンジニアさん（特にHTML/CSS絡み）をたまに見かけます。

AutoHotkey とは対照的に GUI ベースとなっています。以下は設定画面例です。

![phraseexpress_phrases.jpg](https://qiita-image-store.s3.amazonaws.com/0/191170/34cbd17d-18fe-6f06-196f-02d2bdce79e6.jpeg)

PhraseExpress はライセンスが若干厳しいです。もっと言うとタダで商用利用できません。詳しくは公式サイトを確認してください。

- PhraseExpress の特徴
  - :o: 設定項目(挙動カスタムやマクロなど)が豊富
  - :question: GUI ベース
      - :o: わかりやすい、使いやすい
      - :x: 素早く設定ができない、設定の管理がしづらい
  - :x: 商用利用についてはフリーでない

## InstantTextInserter

数少ない（というより唯一？）純国産 Text Expansion ソフトウェアが [InstantTextInserter](http://shouh.github.io/software_details.html) です。既に更新停止されているようですが、ダウンロードは可能なようです。

AutoHotkey と同様、テキストで設定を書くタイプとなっています。以下は記述例です。

```
====itm[====
いつもお世話になっております
```

上記の二つとは違い、本文を貼り付ける際にクリップボードを使用する実装のようです。そのため既にコピーしていた文字列は上書きされてしまいます。

- InstantTextInserter の特徴
  - :o: 設定を Text で書ける、管理できる
  - :x: 本文を貼り付ける際にクリップボードが使用される
  - :x: 更新停止している

# 略語のコツ
少し趣向を変えて、ここでは実践的な話をします。

Text Expansion の使う上で避けて通れない問題が一つあります。**いかにして覚えやすく、打ちやすく、誤発動しない略語を考えるか** ということです。

ここでは「いつもお世話になっております」という本文を挿入するスニペットを例に、どんな略語を設定すればいいかを考えてみましょう。

## 戦略1. なるべく覚えやすく、かつ打ちやすい略語
覚えやすく打ちやすいに越したことはありません。

「いつもお世話になっております」→ ローマ字にすると「itsumo osewa ni natte orimasu」 → 先頭を取って「itsumo」 → まだちょっと長いので削って「itm」 → 3文字もまだ長いので削って「it」

完成しました。トリガーも無しにします。略語は「it」です。わずか二文字で挿入できます。素晴らしく速いですね！めでたしめでたし……とはなりません。

**これではすぐに誤発動しちゃいます**。

たとえば「私はITエンジニアです」と打とうとすると、おそらくこうなるでしょう。

「私は」→「私はI」→「私はIT」→「 **私はいつもお世話になっております**」

これが誤発動です。誤発動してしまったら、いちいち消して打ち直さないといけません。面倒くさいです。何とか避けたいですね。

## 戦略2. トリガーを使う
そこでトリガーの出番です。トリガーを設定してやれば、「it」 + トリガーを打って初めて「いつもお世話になっております」が挿入されるので、誤発動がなくなるはずです。

トリガーとして色んな文字がありますが、ここではスペースを使いましょう。つまり「it 」で挿入されます。

これで今度こそめでたしめでたし…………とはなりません。

たとえば（ちょっと例が強引ですが）「Sit down!」と打とうとすると、こうなるでしょう。

「Si」→「Sit」→「Sit 」→「 **Sいつもお世話になっております** 」

またまた登場しました。誤発動です。イラっとしますね。

さて、困りました。どうすれば誤発動を回避できるでしょう。トリガーを変える？Enterに？Tabに？Tabなら防げそうですね。でも Tab キーって押しづらくないですか？出来ることならホームポジションで済ませたくありませんか？（ご都合主義ですみません、もう少し続きます :bow: ）

## 戦略3. 記号を使う
略語を文字キーだけで構成するから誤発動が起きるのです。トリガーはトリガーでよく使うキーばかりだから結局誤発動が起きるのです。

じゃあどうすればいいのかというと、あまり使わないキー――つまり記号を入れちゃえばいいんです。上記でちらっと言及した **手動トリガー** というやつです。もちろん入れすぎると打ちづらいですから一つだけ。

今回は `[` にしましょう。この記号ならそうそう打つこともないです。略語は `it[` になりました。今度こそ、今度こそ誤発動は起きないはずです……。

- :neutral_face:「ぼく、ただいまプログラミング中……」
- :neutral_face:「インスタンスを管理するテーブルを保持する必要が出てきたなぁ……」
- :neutral_face:「自分用だし名前はテキトーでいいや。インスタンス、テーブル。Instance, Table……よし、イニシャルを取って it にしよう。データ構造はハッシュ（辞書）でいいや」
- :neutral_face:「さて、ガシガシ書くぞー」

`self._`→`self._i`→`self._it`→`self._it[`→`self._いつもお世話になっております`

**self._いつもお世話になっておりますって何やねん……** ……また起きてしまいましたたね……。

そうです。`[` はプログラミングにおいて配列やリストの添字表記として使われます。誤発動する可能性は十分にありえるのです（コード書かない方は大丈夫だと思いますが）。

## 略語を考えるのは難しい
かなりご都合主義な例で申し訳ないですが、言いたいことは伝わったでしょうか……。略語を考えるのは **誤発動との戦い** なのです。

※なお、ここでは挙げてませんが、覚えやすい略語をつくれないと「中々覚えられん！全然効率化できんぞ！」なんてことが起こります。打ちやすい略語をつくれないと「くそ、また入力ミスった！挿入が発動しない！！」なんてことが起こります。

要するに略語を考えるのは難しいです。自分に合った略語を探すには、おそらく何度も、何度も略語を設定し直すという試行錯誤が必要になるでしょう。Text Expansion をガチで導入される方は覚悟してください :smiley:

## 略語を考える際の指針
最後に、略語を考える際の指針というか心がけをまとめておきたいと思います。

- **自分にとって** 覚えやすいこと
- 短すぎないこと
- 長すぎないこと
- **自分にとって** 打ちやすいこと
- 誤発動を防ぐためにトリガーや記号を工夫すること

大事なのは **自分にとって** の部分だと思います。Text Expansion の活用例は、ググればいくらかヒットしますが、彼らの設定が必ずしも自分に合うとは限りません。自分に合った設定は、自分で手を動かして探すしかないのです。

# おわりに
Text Expansion について雑多にまとめてみました。何かの参考になれば幸いです。

（本記事冒頭で「マイナー」と書きましたが、Windows はともかく UNIX 界隈はどうなんでしょうね。マイナーじゃないのかも……）

# 付録1. トリガー検討用 記号一覧
手動トリガーに用いる記号を検討するための表を作ってみました。略語を検討する際の材料になればいいなと思います。

| 記号| 読み            | 衝突内容 |
| --- | --------------- | -------- |
|     | Enter           | 改行
|     | タブ            | インデント
| ` ` | スペース        | 文章全般
| `-` | ハイフン(189)   | 文章全般、式表記全般(イコール)
| `^` | ハット          | XOR、HOMEディレクトリエイリアス
| `\` | バクスラ(220)   | ファイルパス、エスケープ、パイプ、OR
| `@` | アットマーク    | メールアドレス、インスタンス変数(Ruby)、リテラル/ハイライト(Markdown)
| `[` | ブレース左      | 配列、リスト、辞書の添字
| `;` | セミコロン      | 文の区切り
| `:` | コロン          | 構文表記全般(namespace in C++, slice in Python, symbol in Ruby)
| `]` | ブレース右      | 配列、リスト、辞書の添字
| `,` | カンマ          | 英文全般, 構文表記全般(式や文の複数列挙等)
| `.` | ドット          | 英文全般, 構文表記全般(属性アクセス等)
| `/` | スラッシュ(191) | ファイルパス、URI
| `\` | バクスラ(226)   | ファイルパス、エスケープ、文章全般(アンダースコア)
|     |                 | 
| `/` | スラッシュ(111) | ファイルパス、URI
| `-` | ハイフン(109)   | 文章全般
| `*` | アスタリスク    | 乗算、ポインタ、Wiki表記全般
| `+` | プラス          | 加算、結合

こうして見るとどの記号も何かしらの文脈で意味を持つため、誤発動は避けられないように見えますね。特にプログラミングが絡むと絶望的です。

# 付録2. 参考
- [Type Less: How Text Expansion Apps Help You Write Long Phrases With Fewer Keystrokes](https://zapier.com/blog/text-expander-how-to/)
- [The Best Text Expansion App for Windows](http://lifehacker.com/5844126/the-best-text-expansion-app-for-windows)
- [How to Use Text Expansion to Save Yourself Hours of Typing Every Week](http://lifehacker.com/5611210/how-to-use-text-expansion-to-save-yourself-hours-of-typing-every-day)