文脈を指定可能な自動展開されるglobal aliasを実現するZSHプラグイン zabrze を作った

ZSHにはglobal aliasという機能があります。 これは、行頭以外に入力された場合にも展開されるaliasです。

$ alias -g B='"$(git symbolic-ref --short HEAD)"'
$ git push -u origin B
# → git push -u origin [現在のブランチ名]

使いこなせれば便利そうな一方で、global aliasはグローバル名前空間を汚染するため、導入には慎重さを要します*1

また、コマンドヒストリーには通常のaliasと同様にglobal aliasの展開前の入力が保存されます。

これら2つの問題点を解決することを目的に、zabrze というZSHプラグインを作成しました。

github.com

これはなに

zabrze *2 は aliasをYAMLで記述できるようにするZSHプラグインです。

1. aliasの自動展開

例えば下のような設定ファイルを ~/.config/zabrze/config.yaml に記述した場合、行頭で g<スペース> と入力したとき、即座に git と展開されます *3

また、null<スペース> と入力した場合は行頭以外でも >/dev/null に展開することができます。

# ~/.config/zabrze/config.yaml
abbrevs:
  # alias
  - name: git
    abbr: g
    snippet: git

  # global abbrev
  - name: '>/dev/null'
    abbr: null
    snippets: '>/dev/null'
    global: true

2. 文脈を指定した global alias

さて、ここまでであれば後述する既存のZSHプラグインによってすでに同様の機能が実現されています。

zabrze ではaliasの自動展開に加え、展開の有無をその文脈によって切り替えられるようになっています。

  # git コマンドを入力しているときのみ展開されるglobal alias
  - name: branch
    abbr: B
    snippet: $(git symbolic-ref --short HEAD)
    evaluate: true # snippetの文字列をスクリプトとして解釈する
    global: true
    context: '^git ' # 展開される文脈を正規表現で指定する

上のような global alias B は、git コマンドを入力しているときのみ展開されます。

$ git push -u origin B<エンター>
# ↓ に展開され、実行される
# git push -u origin [現在のブランチ名]

$ echo B<スペース>
# ↑ は展開されない 

これにより、global alias自体の有用性を保ったままグローバル名前空間の汚染を避けることができます。

類似のZSHプラグイン

zsh-abbrev-alias

github.com

qiita.com

zsh-abbrev-alias は自動展開される alias コマンド、abbrev-alias コマンドを追加するシンプルなプラグインです。

zeno.zsh

github.com

zenn.dev

zeno.zsh は Deno 製のZSHプラグインです。 abbrev-alias相当の機能に加え、pmyのような補完機能を有しています。

一方、実行にはDenoのインストールを要求し、またスペースを押したときの動作が重い印象があります (おま環かも)。

開発のモチベーション

以前は zsh-abbrev-alias を利用していましたが、Gitなどのサブコマンドにabbrev-aliasを適用できないことを不満に思っていました。

$ abbrev-alias g=git
$ g<SP>  # git に展開される

$ abbrev-alias -g c=commit
$ git c<SP>  # git commit に展開されるがグローバル名前空間の汚染がきびしい

$ git config alias.c commit
$ git c  # history には `git commit` で記録されてほしい

現在は以下のような zabrze の config.yaml によって Git aliases の自動展開を実現しています。

github.com

*1:global aliasの活用例で紹介されるものは1~4文字程度の短いものが多い印象があります (長いglobal aliasの利点は少ないため)

*2: z (ZSHの頭文字) + abbr でそれっぽい単語がないか探した結果の命名です。期せずして almel, zouch と同じく地名になりました

*3:スペースではなく、エンターキーを入力した場合も同様に展開されます