gofujita notes

on outline processing, writing, and human activities for nature


Dynamic text expansion

Let’s talk about dynamic text expansion, but not the kind you may already know about.

さぁ、dynamic text expansion (動的なテキスト展開) の話しをしよう。でもそれは、あなたのしっているやつとちがうかもしれない。

(Mickey Petersen. Text expansion with Hippie Expand)

 

前回お話しした Emacs のパッケージ yasnippet では、snippets 展開前の略号も展開後のテンプレートも、事前に決めたもので変化しない。

しかしぼくたちが文章をかくとき、略号が事前には決められず、展開してほしいテンプレートも変わる場合がある。

たとえば、きのうつくったフォルダやファイルを呼び出すとき。いろいろつくったのでファイルやフォルダの名前がうろ覚え。呼び出したいフォルダやファイルの名前もたまに変化する。あるいは長いパス構造を毎回タイプするのはくたびれる。

こういう場合、覚えている数文字をタイプしただけでファイル名を展開したり、そのファイルがあるパスのすべてを展開してほしい。

あるいはたとえば、仕事のメールで、この2時間のあいだに3回繰り返しかいたフレーズをさらにもう一度かくとき。できれば、最初の3文字くらいをタイプした段階で、フレーズのすべてを展開してほしい。

あるいは、たしか1年以上前につかったアプリケーションの名前を思い出したいとき。だれか宛のメールにその名前をかいた記憶はある。ドイツのアプリで長い名前だったし、スペルが覚えにくかった。でも最初の3文字は何となく覚えている。それをヒントにその候補になる名前を教えてほしい。

こういう場合に頼りになるのが、dynamic text expansion (動的なテキスト展開) という機能。

ぼくの理解ではウェブブラウザや IM などの自動補完機能に似ているけれど、たぶんちょっとちがう。

そうした機能として、Emacs ではデフォルトで Dynamic Abbrev Expansion がある。

たとえば何となく覚えているファイル名が "my" からはじまることを覚えていたら、my とタイプしたあとで M-/ とタイプする。 M- はメタキーのことで macOS なら escopiton キーのこと。その "my" からはじまる、しかもこの Emacs で過去にタイプしたことのある言葉を展開してくれる。

勘ちがいしている可能性もあるけれど、この Emacs の dynamic expansion のいいところは、推定のタイミングを自分で決められること。たとえばこの2文字で推定してほしいときは、2文字タイプして M-/ 。それでだめなら自信ないけど3文字目の候補も入れて自分のタイミングで推定できる。

もっと大切ないいところとして、ぼくが過去に入力したり、コピーペイスト (Emacs ジャーゴンでは kill & yanks) したことだけから候補を展開してくれること。

なのでたとえば "my" といったありふれた2文字からでも、ぼくが展開してほしい「正解」に出会える可能性が高い。

Mickey Petersen さんによると、Emacs はこの Dynamic Abbrev よりもずっと賢いパッケージ "hippie-expand.el" を30年にわたり、隠しもってきた (笑)。

つかいはじめたばかりなので勘ちがいしている可能性もあるけど、Hippie はとくに長いセンテンスも覚えてくれている場面が多い。短い単語もほしいものに出会える可能性が高い気がする。Mickey さんがいうように「Dynamic Abbrev が学校でもっとがんばってればこうなれたはず」というくらいの完成度。

Hippie expand には、微妙にちがう条件で繰り返すことになるコードの引数などを補完する方法もある (Mickey さんの記事の3番目の例 Completing "lists")。

あともうひとつ、意外な役割をもっていることにも気づいた。たとえばあるキーワードで1年くらい前にぼくが一生懸命かいていたことが、センテンスの候補として出てきたりする。すっかり本人は忘れているアイディアが出てきたりする。

これは、そのことばをめぐる自分なりの考えを俯瞰する上で、役に立つのではないかと、テキトーに予想している (笑)。

これはキーワードの検索でもできそうな気がするけれど、point (cursol のこと) が今いる場所にキーワードを含む文字列が展開できる点が便利 (検索だと point は検索された文字列へジャンプする)。

たとえばぼくの場合、研究しているサシバという鳥について、自分がどんなアイディアをどんな文脈の中でかいたのかを "サシバ" M-/ とタイプし、あとは M-/ を押しつづけるだけで、サシバということばに関係する過去のノートを辿ることができる。

Hippie expand のつかい方。

あなたの Emacs にも「隠されて」いるのでインストールの必要はない。デフォルトの設定を変え M-/ で hippie expand をつかうには、以下のコードを設定ファイル (init.el や .spacemacs など) にかく。

(global-set-key [remap dabbrev-expand] 'hippie-expand)

もちろん他の形に key bind するのも OK。ぼくがよんだいくつかの記事には M-" " という key bind がいいよ、と紹介されていた。"meta key + space" という設定。

くわしい hippie-expand.el の解説は hippie-exp.el にある。

これによると、hippie expand は関数。補完の内容や順番は hippie-expand-try-functions-list というリストによって決められている。このリストの中身をかき変えてカスタマイズする。また、この関数のふるまいを変える変数もある。

make-hippie-expand-function という関数があり、これをつかって別の hippie expand みたいな関数をつくることができるというのも Emacs らしい。

Dynamic text expansion に興味をもち、自分なりの機能を育てたくなった人のための道具も用意されているのだ。