LoginSignup
1
3

More than 5 years have passed since last update.

AutoHotKeyで、TextExpander風にスニペットに他のスニペットを埋め込んだりしたい

Posted at

AutoHotKeyをTextExpanderのようなスニペット展開アプリとして利用しています。

TextExpanderには、スニペット内に別のスニペットを挿入することができますが、このようなことはAutoHotKeyではできないのでしょうか。

AutoHotKeyにおけるスニペット展開スクリプト

ユースケースによって様々な実装がありますが、私の場合、ホットストリングから、文字列をペースト(性格にはCtrl+Vキーを送る)する関数をコールしています。

::ahk:: ; Abbreviations相当部分
    PasteString("AutoHotKey") ; Snippet相当部分
    Return

このように、ホットストリングラベルのサブルーチン内で関数コールがされている状態です。

PasteString関数のコードは以下のとおりです。これは関数ライブラリとして利用しています。

PasteString(String){
    Backup := ClipboardAll
    Clipboard := String
    Send,^v
    Sleep,250 ; Ctrl+Vによる貼り付け処理が終わるまで適当に待つ
    Clipboard := Backup
    Return
}

変数の利用

例えば、メールアドレス等を、必要とするすべてのスニペットに直接記述するのではなく、メールアドレスのみが記述されたスニペットを呼び出す形で利用したい。

ホットストリングgmailhogehoge@gmail.comを、mymailメールアドレス:hogehoge@gmail.comをペーストするような場合です。

このような場合、変数に格納して参照するのが簡単です。

::gmail::
    Gmail = hogehoge@gmail.com
    PasteString(Gmail)
    ; ペーストされる文字列は`hogehoge@gmail.com`
    Return
::mymail::
    PasteString("メールアドレス:" . Gmail)
    ; ペーストされる文字列は`メールアドレス:hogehoge@gmail.com`
    Return

global宣言とかしなくていいのかというと、AutoHotKeyでいうローカル変数というのは関数内で格納された変数のみを指すのであって、サブルーチンを含むそれ以外の場所で格納された変数は全部グローバルです。

もちろん、ホットストリングのサブルーチン以外の場所で変数に格納しておいても問題ありません。

Gmail = hogehoge@gmail.com
::gmail::
    PasteString(Gmail)
    ; ペーストされる文字列は`hogehoge@gmail.com`
    Return
::mymail::
    PasteString("メールアドレス:" . Gmail)
    ; ペーストされる文字列は`メールアドレス:hogehoge@gmail.com`
    Return

ホットストリングラベルの呼び出し

ホットストリングはラベルなので、Gotoでジャンプできます。(無論Gosubでも。)

::gmail::
    Gmail = hogehoge@gmail.com
    PasteString(Gmail)
    ; ペーストされる文字列は`hogehoge@gmail.com`
    Return
::github::
    ghhome = https://github.com/hogehoge
    PasteString(Github)
    ; ペーストされる文字列は`https://github.com/hogehoge`
    Return
::myprof::
    PasteString("メールアドレス:")
    GoSub, ::gmail
    PasteString("`n/Github:")
    Goto, ::github
    ; ペーストされる文字列は、
    ; `メールアドレス:``hogehoge@gmail.com``/Github:``https://github.com/hogehoge`
    Return

しかしこれだと、PasteString関数のコールのたびにsleepがかかるため、実行段階ではスマートさに欠けます。

一応、各PasteStringIfを書いておいて、Gosubする側でフラグ立ててGosubだったらペーストしないで戻るとかできなくはないですが、別にそこまでしたくないなという感じ。

自動置換型ないしSendを使うタイプのホットストリングだと、まとめて1回でも2回に分けても大差ないのですが、それはそれで単純な実行速度の遅さだったり、日本語の扱いが神経質だったりの問題があります。(参考:ユニコード版で利用する

Abbreviations-Snippets対応表を別に用意する

まあこんな感じで、txtでもcsvでも。

Snippets.txt
; 左右の区切りはタブ文字
Gmail   hogehoge@gmail.com
Github  https://github.com/hogehoge
...

それで、PasteString関数でLoop,ReadStringSplitかなにかで参照すると。ただ、対応表が肥大化すると実行速度がえらいことになりそうだし、ホットストリングと対応表の両方に追加していくのも、まあそれも自動化すればいいのですがやっぱり面倒。

これが一番TextExpanderに近い動作といえばそうなのでしょうが。

というわけで

結論としては、変数に格納しております。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3