やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

espansoのマッチを書いてみる

 シェルの実行ができたので、あとは何でもできそう。

成果物

パス

 私の環境では以下のパスにマッチファイルを配置する。

~/.config/espanso/

default.yml

日付

日付拡張だとコロンが消えてしまう。

 YYYY-mm-dd HH:MM:SS形式で現在日時を出力したい。だが以下のように日付拡張を使うとコロン:が消えてしまう。原因不明。

  - trigger: ":date"
    replace: "{{mydate}}"
    vars:
      - name: mydate
        type: date
        params:
          format: "%Y-%m-%d %H:%M:%S"

日付はシェルで出力する

 シェル拡張dateコマンドを使い、日付を出力させる。

  - trigger: ":nowl"
    replace: "{{now}}"
    vars:
      - name: now
        type: shell
        params:
          cmd: "date \"+%Y-%m-%d %H:%M:%S\""
  - trigger: ":nowu"
    replace: "{{now}}"
    vars:
      - name: now
        type: shell
        params:
          cmd: "date -u \"+%Y-%m-%dT%H:%M:%SZ\""
Key Output Format Example
nowl ローカル日時 %Y-%m-%d %H:%M:%S 2000-01-02 12:34:56
nowu UTC日時 %Y-%m-%dT%H:%M:%SZ 2000-01-02T12:34:56Z

user/

 外部ファイル化したものをこのディレクトリに配置する。

 各ファイル名は任意。ファイル内容の先頭には以下を書く。nameの値は任意。

name: bash
parent: default

url.yml

 ブログを書いているときによく使うURL。

name: url
parent: default

# URL
matches:
  - triggers: [":?-d",":hatena-draft"]
    replace: "https://blog.hatena.ne.jp/ytyaru/ytyaru.hatenablog.com/drafts"

  - triggers: [":?-e", ":hatena-entry"]
    replace: "{{hatena_entry}}"
    vars:
      - name: hatena_entry
        type: shell
        params:
          cmd: "echo 'http://ytyaru.hatenablog.com/entry/'$(date +%Y)/$(date +%m)/$(date +%d)/000000"

  - triggers: [":gh-user",":github-user"]
    replace: "https://github.com/ytyaru"

  - triggers: [":gh-raw", ":github-raw"]
    replace: "https://github.com/ytyaru/$REPO/blob/master/doc/0.png?raw=true"

  - triggers: [":gh-img", ":github-img"]
    replace: "{{github_img}}"
    vars:
      - name: github_img
        type: shell
        params:
          cmd: "URL='https://github.com/ytyaru/'\"$REPO_NAME\"'/blob/master/doc/@.png?raw=true'; cat <(seq 0 9 | xargs -I@ echo '![@]('\"$URL\"')') <(echo {A..Z} | tr ' ' '\n' | xargs -I@ echo '![@]('\"$URL\"')') | xsel -bi"
  • - triggers: ["",""]
    • 複数トリガーを指定できる(注意: - trigger: ""とは違う)

blog.yml

 Markdownでブログを書いているときによく使うHTML。

name: blog
parent: default
matches:
  - trigger: ":details"
    replace: "<details><summary>$|$<summary>\n</details>"

  - trigger: ":small"
    replace: "<small>$|$</small>"
  • $|$はカーソル位置を示す

bash.yml

# Bash
# https://espanso.org/docs/
name: bash
parent: default
matches:
  - trigger: ":shebang"
    replace: "#!/usr/bin/env bash"

  - trigger: ":run()"
    replace: |
        #!/usr/bin/env bash
        set -Ceu
        #---------------------------------------------------------------------------
        # $|$
        # CreatedAt: {{now}}
        #---------------------------------------------------------------------------
        Run() {
                THIS="$(realpath "${BASH_SOURCE:-0}")"; HERE="$(dirname "$THIS")"; PARENT="$(dirname "$HERE")"; THIS_NAME="$(basename "$THIS")"; APP_ROOT="$PARENT";
                cd "$HERE"
        }
        Run "$@"
    vars:
      - name: now
        type: shell
        params:
          cmd: "date \"+%Y%m%d %H%M%S\""

  - trigger: ":path"
    replace: |
        THIS="$(realpath "${BASH_SOURCE:-0}")"; HERE="$(dirname "$THIS")"; PARENT="$(dirname "$HERE")"; THIS_NAME="$(basename "$THIS")"; APP_ROOT="$PARENT";

  - triggers: [":loop", ":loop-line", ":while", ":while-line"]
    replace: |
        echo -e "A\nB" | while read line; do { echo "$line"; } done;
        echo -e "A\nB" | (RES=; while read line; do { RES+='A'"$line"$'\n'; } done; echo -n "$RES";)
        while read line; do {
            echo "$line"
        } done <<-EOS
            A
            B
        EOS

  - trigger: ":join"
    replace: |
        Join() {
            local ARG_DELIMITTER=;
            while getopts :d: OPT; do
                case $OPT in
                    d) ARG_DELIMITTER="$OPTARG"; continue; ;;
                esac
            done
            [ $OPTIND -lt $# ] && shift $(($OPTIND - 1))
            ARG_DELIMITTER="${ARG_DELIMITTER:-$'\n'}"
            local ARRAY=("$@")
            echo "$(IFS="$ARG_DELIMITTER"; echo "${ARRAY[*]}")"
        }
  - trigger: ":isint"
    replace: |
        IsInt() { test 0 -eq $1 > /dev/null 2>&1 || expr $1 + 0 > /dev/null 2>&1; }

  - trigger: ":isexistcmd"
    replace: |
        IsExistCmd() { type "$1" > /dev/null 2>&1; }

  - trigger: ":getopts"
    replace: |
        Help() { eval "echo \"$(cat "$APP_ROOT/doc/help.txt")\""; }
        while getopts :n: OPT; do
                case $OPT in
                        n) ARG_NUM="$OPTARG"; continue; ;;
                        \?) Help; exit 1; ;;
                esac
        done
        ARG_NUM="${ARG_NUM:-30}"
  • replace: |
    • 複数行やインデント付きテキストを入力できる

所感

 自動化スクリプトを書いて、それをespansoで起動するのが最適解かも。

 フォームはもっと強力なものが欲しい。日付、数値スピン、グリッド、ツリー等。

対象環境

$ uname -a
Linux raspberrypi 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l GNU/Linux