12
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Espanso

Espanso とは、オープンソースかつ無料で使用できる、クロスプラットフォーム(Windows、macOS、Linux)のスニペットアプリです。Espanso を使用すると、短いキーワードを入力するだけで、長いテキストを瞬時に入力できます。これにより、繰り返し入力する必要のあるテキストを簡単に入力できるようになります。Mac 標準のテキスト辞書よりも高速で、多機能です。さらに、Shell script を呼び出すことができるので、ただのスニペットアプリとしてだけでなく、アプリやファイルを開いたり、APIを呼び出すことができるなど、非常に拡張性が高いです。例えば、クリップボードにコピーしたテキストを即時翻訳させることができ、作業中のアプリから離れる必要もなくなります。

image.png

ezgif-1-5219cff875.gif

ezgif-1-6d58091dfc.gif

インストール

インストールしたら、アプリを開きます。そして、ターミナルを開き、コマンドで espanso status を実行して動いているか確認しましょう。

設定

Espanso の設定は主に2つのファイルで行います。

esnpanso/
  config/
    default.yml
  match/
    base.yml

espanso のディレクトリの場所は OS によって異なり、コマンド espanso path によって確かめることができます。

  • Linux: $XDG_CONFIG_HOME/espanso (e.g. /home/user/.config/espanso)
  • MacOS: $HOME/Library/Application Support/espanso (e.g. /Users/user/Library/Application Support/espanso)
  • Windows: {FOLDERID_RoamingAppData}\espanso (e.g. C:\Users\user\AppData\Roaming\espanso)

config/default.yml ファイルは、初めは特に設定することはないです。
もし、メニューバーのアイコンを非表示にたい場合は、show_icon: false と書き込むと良いです。

使い方

スニペットの設定は match/base.yml ファイルに書き込みます。

基本的には次のような文法で書きます。

matches: 
  - trigger: ":hello"
    replace: "world"

# 複数行
  - trigger: ":hello"
    replace: "line1\nline2"

# 複数行
  - trigger: ":include newlines"
    replace: |
              exactly as you see
              will appear these three
              lines of poetry

# 改行なし
  - trigger: ":fold newlines"
    replace: >
              this is really a
              single line of text
              despite appearances

match/base.yml を変更したら、それを反映させるためにメニューバーで Reload をするか、コマンドで espanso restart を実行しましょう。

望まないスニペットの作動を防ぐために、:; などの普段は使わない記号を接頭辞に用いると良いです。

:a を登録すると :as:ad といったトリガーは使えなくなります。なぜなら、:a を入力した段階で別のテキストに置換されるからです。このようなことを防ぐために、短すぎるトリガーの設定は避けた方が良いです。

match ディレクトリにある全ての .yml ファイルは読み込まれるので、用途に応じてファイルを細かく分割することもできます。

動的マッチ

次の設定では、:now と入力すると It's 11:29 のように現在時刻に変換します。

  - trigger: ":now"
    replace: It's {{mytime}}
    vars:
      - name: mytime
        type: date
        params:
          format: "%H:%M"

単語マッチ

基本的な triggermatch の設定方法では、変換して欲しくない場面で変換が起こる可能性があります。例えば、トリガー ther によって there としたいとき、other と入力しても変換が実行され othere となってしまいます。これを防ぐためには、以下のように word: true のオプションをつけます。

  - trigger: "ther"
    replace: there
    word: true

カーソルヒント

テキストを変換した後に、カーソルが来る位置を $|$ で決めることができます。

  - trigger: ":div"
    replace: <div>$|$</div>

一つのトリガーに複数の変換

  - trigger: ":quote"
    replace: "Every moment is a fresh beginning."
  - trigger: ":quote"
    replace: "Everything you can imagine is real."
  - trigger: ":quote"
    replace: "Whatever you do, do it well."

複数のトリガーに一つの変換

  - triggers: [":hello", ":hi"]
    replace: "world"

複数のトリガーに複数の変換

  - triggers: [":ok",":emoji"]
    replace: "👍"
  - triggers: [":ok",":emoji"]
    replace: "✅"
  - triggers: [":up",":emoji"]
    replace: "⬆️"
  - triggers: [":down",":emoji"]
    replace: "⬇️"

画像のマッチ

  - trigger: ":cat"
    image_path: "$CONFIG/images/cat.png"

グローバル変数

match に共通してよく使う変数がある場合はグローバル変数として設定すると、変更する際に便利です。

global_vars:
  - name: myname
    type: echo
    params:
      echo: "John"
# It can also be defined as follows:
#  - name: myname
#    type: shell
#    params:
#      cmd: "John"

matches:
  - trigger: ":greet"
    replace: "Hello {{myname}}"

  - trigger: ":sig"
    replace: "Best regards, {{myname}}"

espanso のディレクトリを GitHub などで管理したいが、一部プライベートなパラメーターを含むような場合は、params.yml に入れておき、params.yml.gitignore に追加する方法があります。match ディレクトリにある *.yml ファイルは全て読み込まれます。それ以外の場合は、直接パスを指定して import することもできます。

esnpanso/
  config/
    default.yml
  match/
    base.yml
    params.yml
# base.yml
imports:
  - "paths/to/your.yml"

matches:
  - trigger: ":hello"
    replace: "{{greet}} Jon"

Clipboard Extension

変換後の中身にクリップボードの内容を含めて出力することができます。これで、貼り付け作業が必要なくなります。

例えば、直前にコピーしたリンクを用いて、HTML の <a> タグを作成したい時、以下のようにトリガーを定義します。

  - trigger: ":aref"
    replace: "<a href='{{clip}}' />$|$</a>"
    vars:
      - name: "clip"
        type: "clipboard"

マークダウンのトリガー例:

  - trigger: ";mdlink"
    replace: "[$|$]({{clip}})"
    vars:
      - name: "clip"
        type: "clipboard"

  - trigger: ";mdcode"
    replace: |
          ```
          {{clip}}
          ```
    vars:
      - name: "clip"
        type: "clipboard"

各トリガーにクリップボード変数を定義するのが面倒な方は、global_vars に定義しておくと良いです。

Shell Exntension

シェルコマンドを実行して、その結果を出力することもできます。

  - trigger: ":shell"
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "echo 'Hello from your shell'"

以下の例は、ipify からパブリック IP を取得するトリガーです。

  - trigger: ":ip"
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "curl 'https://api.ipify.org'"

以下の例は、UUID(Universally Unique Identifier)を生成するトリガーです。

  - trigger: ";uuid"
    replace: "{{output}}"
    vars:
    - name: output
      type: shell
      params:
        # macOS,Linux:
        cmd: "uuidgen"
        # Windows (requires PowerShell):
        # cmd: "powershell -command \"[guid]::NewGuid().ToString()\""

以下の複数の例は、本来のアプリの趣旨とは異なりますが、アプリやWebサイト、ファイルを開くためのトリガーです。

まずは、ターミナルや特定のフォルダを開くトリガー。

  - trigger: ";term"
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "open -a Terminal.app"

  - trigger: ";dotfile"
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "open ~/github/dotfiles/"

ターミナルを経由し、VScode で espanso ディレクトリを開くトリガー。ターミナルが開き、code ~/github/dotfiles/espanso/ が実行されます。\n がエンターの役割を果たします。

  - trigger: ";espanso"
    replace: "{{output}}\n"
    vars:
      - name: output
        type: shell
        params:
          cmd: "open -a Terminal.app; echo 'code ~/github/dotfiles/espanso/'"

以下のように、直接呼び出す書き方もできますが、最初に開かれているファイルの一部が消される可能性があります。

  - trigger: ";espanso"
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "code ~/github/dotfiles/espanso/"

CotEditor.app で新しいファイルを作成し、それを開くトリガー。

  - trigger: ";newfile"
    replace: "{{output}}"
    vars:
      - name: uuid
        type: shell
        params:
          cmd: "uuidgen"
      - name: output
        type: shell
        params:
          cmd: "cd ~/Desktop; touch {{uuid}}.md; open /Applications/CotEditor.app {{uuid}}.md"

Youtube を開くトリガー。デフォルトのブラウザで開きます。

  - trigger: ";you"
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "open 'https://www.youtube.com/'"

クリップボードにコピーした内容を検索するトリガー。

  - trigger: ";ggl"
    replace: "{{output}}"
    vars:
      - name: "clip"
        type: "clipboard"
      - name: output
        type: shell
        params:
          cmd: "open 'https://www.google.com/search?q={{clip}}'"

クリップボードにコピーした内容を Google Gemini で翻訳するトリガー。global_varsGEMINI_API_KEY を定義した上で使用してください。

  - trigger: ";transen"
    replace: "{{translation}}"
    vars:
      - name: "clip"
        type: "clipboard"
      - name: translation
        type: shell
        params:
          cmd: >
            curl -s \
              "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={{GEMINI_API_KEY}}" \
              -H 'Content-Type: application/json' \
              -X POST \
              -d '{
                    "contents": [{
                      "parts": [{"text": "Translate the following to English. Provide ONLY the translated text, no explanations or markdown: {{clip}}"}]
                    }]
                  }' \
            | jq -r '.candidates[0].content.parts[0].text | split("\n")[0]'

指示を変更すれば、いろいろな種類のトリガーを作成できます!

Script Exntension

外部ファイルを実行してその結果を受け取ることもできます。

script.py

print("Hello from python")

base.yml

  - trigger: ":pyscript"
    replace: "{{output}}"
    vars:
      - name: output
        type: script
        params:
          args:
            - python
            - /path/to/your/script.py

Form Extension

トリガーからフォームを生成し、定型文にそって文章を作成することもできます。

  - trigger: ":greet"
    form: |
      Hey [[name]],
      Happy Birthday!

screenshot.png

上のフォームは以下のように表現することもできます。

# The above is equivalent to the following
  - trigger: ";_greet"
    replace: |
        Hey {{form.name}},
        Happy Birthday!
    vars:
      - name: "form"
        type: form
        params:
          layout: |
            Hey [[name]],
            Happy Birthday!

variableform を同じトリガー内で使用するような複雑な場合には、こちらの記法出ないと作動しないようです。

次の設定は、メールの定型文フォームから文章を作成します。

matches:
  - trigger: ";reply"
    form: |
        Hi, [[name]]
        
        Thank you for your email and for bringing this to our attention.
        I am sorry that you're disappointed with our product.
        
        [[choices]]

        Looking forward to hearing from you
        
        All the best,
        ABC Support Team
    form_fields:
      choices:
        type: choice
        values:
          - Could you please let me know what specific issues you've encountered?
          - sentence 2
          - sentence 3
          - sentence 4

screenshot.png

より複雑なフォームの使い方として、次のように Todo アイテムを作成できます。

  - trigger: ";todo"
    replace: "Task: {{form1.task}}, Due Date: {{form1.day}} {{form1.time}}"
    vars:
      - name: "day0"
        type: date
        params:
          format: "%Y/%m/%d"
      - name: "day1"
        type: shell
        params:
          cmd: "date -v+1d '+%Y/%m/%d'"
      - name: "day2"
        type: shell
        params:
          cmd: "date -v+2d '+%Y/%m/%d'"
      - name: "day3"
        type: shell
        params:
          cmd: "date -v+3d '+%Y/%m/%d'"
      - name: "day4"
        type: shell
        params:
          cmd: "date -v+4d '+%Y/%m/%d'"
      - name: "day5"
        type: shell
        params:
          cmd: "date -v+5d '+%Y/%m/%d'"
      - name: "day6"
        type: shell
        params:
          cmd: "date -v+6d '+%Y/%m/%d'"
      - name: "form1"
        type: form
        params:
          layout: "Task: [[task]], Due Date: [[day]] [[time]]"
          fields:
            day:
              type: choice
              values: |
                      {{day0}}
                      {{day1}}
                      {{day2}}
                      {{day3}}
                      {{day4}}
                      {{day5}}
                      {{day6}}
            time:
              type: choice
              values:
                - "9:00"
                - "10:00"
                - "11:00"
                - "12:00"
                - "13:00"
                - "14:00"
                - "15:00"
                - "16:00"
                - "17:00"
                - "18:00"
                - "19:00"
                - "20:00"

SCR-20240618-qyki.png

ここでは書ききれなかったトリガーの例は以下のレポジトリにあります。

あるいは、次のサイトも参考になります。

12
16
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
12
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?