✏️

EmacsでFish Scriptをガチる

2021/09/26に公開

はじめに

ちょっとしたデータの整形や処理をサクっと終わらせたい時、みなさんは何を使いますか?

自分の好きな言語で書く人、テキストエディタのマクロ機能などを使う人、シェルスクリプトを書く人、気合で手作業でやる人など色々あると思います。
私は再現性も考慮してシェルスクリプトを書くことが多いです。

シェルスクリプトで一番書かれてるのはbash scriptな気がしますが、文法が現代プログラミング言語から乖離してるので中々理解しづらいです。

最近はzxというjavscript likeなシェルスクリプトもあるようなのですが、ログインシェルを使うほうが今後のことも考えると筋が良いように思えます。

fish scriptはruby likeな文法で覚えるのが非常に楽、ログインシェルとして利用してる人はシェルに貼りつけるだけで実行できます。

今回はfish scriptをemacsで快適に編集できるようにするためのTipsを纏めていきます。

emacsのpackage管理ツールはleafを使用しているので注意してください。

私のemacsの設定は以下です。

https://github.com/takeokunn/.emacs.d

packages

fish-mode

https://github.com/wwwjfy/emacs-fish

(leaf fish-mode
  :ensure t
  :setq
  (fish-enable-auto-indent . t)
  :mode ("\\.fish$"))

fish scriptのmajor modeです。
prog-modeを継承しています。
このpackageはsyntax highlightやインデントの計算などをしています。

fish-enable-auto-indentend else case を入力した時に良い感じにインデントをしてくれるものなので有効化しておくと便利です。

company-shell

https://github.com/Alexander-Miller/company-shell/

(leaf company-shell
  :ensure t
  :config
  (push 'company-fish-shell company-backends))

company-shell は補完ライブラリcompany-modeの拡張です。
内部的にはfish functionのfunctions -abuiltin -nから取得したものを補完候補に入れるような実装になっています。

2021/09/26現在、macでは非常に重いという現象が起きています。

https://github.com/Alexander-Miller/company-shell/issues/15

原因はコマンドを検索する whatis が遅いからみたいです。
meta情報は別になくても問題なく動くのでforkして company-shell-meta-enable という変数を作って有効無効を切り替えできるようにしました。

forkしたものを el-get などで入れてみてください。

https://github.com/takeokunn/company-shell/commit/c35f0b90596d971f9b0d2cc1de586969f02c6c32

(leaf company-shell
  :el-get (company-shell
           :url "https://github.com/takeokunn/company-shell.git"
           :features company-shell)
  :config
  (push 'company-shell company-backends)
  (push 'company-shell-env company-backends)
  (push 'company-fish-shell company-backends))

fish-repl

https://github.com/takeokunn/fish-repl.el

Image from Gyazo

(leaf fish-repl
  :el-get (fish-repl.el
           :url "https://github.com/takeokunn/fish-repl.el.git"))

拙作のREPLライブラリ。
Emacs内でREPL駆動開発をすることができるようにした。

fish scriptを編集しているbufferからreplにコードを送れるようにもしています。

現状出来はそこそこなので今後はabicky/nodejs-repl.elを参考に拡張していきたい。

org-babel

https://github.com/takeokunn/ob-fish

(leaf ob-fish
  :el-get (ob-fish
           :url "https://github.com/takeokunn/ob-fish.git"))

(leaf ob-babel
  :after (ob-fish)
  :config
  (org-babel-do-load-languages 'org-babel-load-languages
                               '((fish . t))))

拙作のorg-babelのfish拡張。
過去に書いた雑なfish scriptは雑にorgで管理しています。
orgのcode blockでfish scriptを実行できたら良いなぁと思って作りました。

#+begin_src fish
function say_hello
    echo Hello $argv
end

say_hello "world"
#+end_src

#+RESULTS:
  : Hello world

yasnippet

https://github.com/joaotavora/yasnippet

yasnippetは非常に強力なsnippet packageです。
yasnippet-snippetsfish-modeのsnippetがあるのでオススメです。
https://github.com/AndreaCrotti/yasnippet-snippets/tree/master/snippets/fish-mode

以前書いたsnippetのorgでの管理方法がオススメです。
https://takeokunn.xyz/blog/post/emacs-yasnippet-setup

最後に

fish scriptを書かない人もログインシェルとしてもオススメなので是非

GitHubで編集を提案

Discussion