Overview

シェルまわりの環境をリニューアルしてみて、その備忘録を残す。

ISUCONに出場予定なので、さくっともろもろ編集するにはシェル環境だけで完結できるとよいかな、という考えから再構築をはじめた。

リニューアル前の環境としては、こちらの記事で紹介したものをベースに更に少し変更を加えたものだった。

fish,tmux,neovim,ghq,pecoで開発スペース構築を快適にする - abekoh’s tech note

もろもろ設定したものがこちら。

abekoh/dotfiles: my dotfiles

リニューアル前のものはtagをつけてスナップショットとして追いやすくしている。

以下、分類ごとに採用したツールを紹介してみる。

ターミナル: Alacritty

長らくiTerm2を使っていたが、Alacrittyというのに乗り換えてみた。

Alacritty - A cross-platform, OpenGL terminal emulator

RustとOpenGLの力で高速というのが売りのもの。とはいえ個人的にはiTerm2との差は感じない。

また、複数パネル・タブなどの機能はない(複数ウィンドウはできそう)、設定はYAML(次期バージョンではTOML)でしか設定できないという硬派であるが、それが以前のiTerm2とtmuxの機能両方を混ぜながら使うスタイルより統一感を助長してくれてよいかなと思った。 シンプルで硬派なところに惹かれて採用。

最近だとWarp, WezTermも流行っているが、いずれも立地だったり機能盛りだくさんだったり。ターミナルエミュレータ自体はシンプル志向でいきたかったので採用せず。

シェル: zsh + Starship + zinit + Atuin

fishは前回の記事の後早いうちからやめていて、zshに戻っていた。 理由として、fishは独自構文多すぎで学習コストが辛いのと、世に多くあるPOSIX互換のコマンド・ワンライナー等のコピペが動かず厄介だったところ。

結局zshにして、Starship 入れたり補完周りのプラグイン入れたりすればfishでできてた補完・情報表示などは再現できる。

Starshipはゼロコンフィグで、見た目をいい感じにできてよい。gitのステータスはもちろん、各種言語の使用バージョン表示など。

Starship: Cross-Shell Prompt

zinitはプラグイン管理、ここはあまり比較検討できてない。

zdharma-continuum/zinit: 🌻 Flexible and fast ZSH plugin manager

また、コマンド履歴はAtuinで後からの検索をサクサクできるようにしている。登録すれば別のデバイスとの共有も可能らしいが、コマンド履歴をインターネット越しに共有は抵抗があるので利用していない。

Atuin - Magical Shell History

マルチプレクサ: Zellij

tmuxの代替としてZellijを導入。

Zellij

tmuxでできてたことは何でもできる。設定項目も豊富。

できるだけデフォルトの設定を尊重しつつ、Vim操作で被ったところは別のものを割り当てたりで調整。有効なレイアウトなら下にガイドが表示されているのがわかりやすくて嬉しい。

Alacritty導入により複数タブ・パネルが使えないのでこちらに全て頼ることとなる。Autostartの設定を入れてzsh起動したら自動でZellijが立ち上がるようにした。

エディタ: Neovim + AstroNvim

NeoVimであれこれプラグイン入れて環境整えて久しいが、以前より利用頻度が減った(主にGoLand, WebStormでコードを書くから)のでチューニングがだるくなっていた。 プラグイン大量使いだと、それぞれのキーバインドを被らないようにあれこれ割当なおすのは楽しい半面、しっかり設計しないとモグラ叩きのように次から次へ設定をし直すハメになってしまう。

そこでAstroNvimという、これさえ入れればいろいろいい感じにしてくれるってやつに頼ることにした。

Getting Started | AstroNvim

LSPのおかげで色々な言語の補完が簡単に実現できてうれしい。自動でどのLSPを使うかの設定は入れておいた

-- init.lua
return {
  plugins = {
    {
      "williamboman/mason-lspconfig.nvim",
      opts = function(_, opts)
        opts.ensure_installed = require("astronvim.utils").list_insert_unique(opts.ensure_installed, {
          "ansiblels",
          "astro",
          "bashls",
          "clangd",
          "cmake",
          "cssls",
          "dockerls",
          "gopls",
          "html",
          "jsonls",
          "jdtls",        -- java
          "tsserver",     -- javascript / typescript
          "marksman",     -- markdown
          "intelephense", -- php
          "prismals",
          "pyright",      -- python
          "solargraph",   -- ruby
          "taplo",        -- toml
          "tailwindcss",
          "terraformls",
          "lemminx", -- xml
          "yamlls",
          "sqlls",
          "hls", -- haskell
          "graphql",
        })
      end,
    },
  },
}

追加で以下のようなプラグインを入れた

AstroNvimのデフォルトで好みじゃないところはいろいろ変更している。以下の設定ファイル参照。

dotfiles/config/astronvim at main · abekoh/dotfiles

カスタマイズ

その他、オリジナルな設定についていくつか紹介。

prjコマンド

以前の記事 で実行していたprjコマンドをやや変更して移植。

実行する様子はこちら。NeoVim開いたりパネル上下入れ替えもやってみてる。

Run prj command

実行内容は、

  1. prjで、ghqにより管理されたgitリポジトリをskimをつかって選択
  2. リポジトリを選択するとそのプロジェクト用のZellijタブが開かれ、カレントディレクトリがそのリポジトリのルートになる

といった感じ。もう一度同じリポジトリを開こうとした場合はすでに開かれたタブがアクティブになるだけ。

次のような関数を定義している。

# ~/.zshrc
prj () {
  local prj_path=$(ghq list -p | sk --layout reverse --query "$LBUFFER")
  if [ -z "$prj_path" ]; then
    return
  fi
  local prj_name=$(echo "$(basename $(dirname $prj_path))/$(basename $prj_path)" | sed -e 's/\./_/g')
  if zellij action query-tab-names | grep -Fxq $prj_name; then
    zellij action go-to-tab-name $prj_name
  else
    zellij action new-tab --layout project --name $prj_name --cwd $prj_path
  fi
}

また、リポジトリに紐づくタブのZellijレイアウトは別途指定、上下に2つパネル、上が80%・下が20%のものにした。

// ~/.config/zellij/layouts/project.kdl
layout {
    pane size=1 borderless=true {
        plugin location="zellij:tab-bar"
    }
    pane {
      pane size="80%" {
        focus true
      }
      pane size="20%"
    }
    pane size=1 borderless=true {
        plugin location="zellij:status-bar"
    }
}

上下のパネルはCtrl+y(ZellijのMoveモード) → y、で入れ替えるようにした。大きいパネルでNeoVimで編集しつつ、コマンド実行したくなったら入れ替えて大きい画面で実行できる。視点移動が少なく自分好み。

// ~/.config/zellij/config.kdl
keybinds {
  normal {
    unbind "Ctrl h"
    bind "Ctrl y" { SwitchToMode "Move"; }
  }
  move {
    bind "y" { MovePane "Down"; MoveFocus "Up"; SwitchToMode "Normal"; }
  }
}

cdコマンドでgitルートジャンプ

こちらも以前のものの移植。あるリポジトリのコンテキスト内で閉じてさくっとルートに戻れるといろいろ嬉しい。

# ~/.zshrc
cd() {
    if [ "$#" -eq 0 ]; then
        if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
            builtin cd "$(git rev-parse --show-toplevel)" || return 1
        else
            builtin cd ~ || return 1
        fi
    else
        builtin cd "$@" || return 1
    fi
}

セットアップ

設定ファイルは~/dotfilesからシンボリックリンクを張るようにしているが、そのセットアップスクリプトを以前はPythonで書いていた。

dotfiles/make_links.py at 2023-08-19 · abekoh/dotfiles

最近なってRubyだとバッククォート囲むだけでシェル実行ができる、と知ってもっと見た目スマートになりそうだと思いRubyに書き換えた。書き換えはChatGPTにお願いしたらいい感じになった、超便利。

dotfiles/setup.rb at main · abekoh/dotfiles

まとめ

この環境で1ヶ月弱運用しているが、慣れると快適である。長年触ってたtmuxと別れを告げるのは寂しいものの、Zellijにもtmux互換で操作できるところもあるのでたまには使ってキーバインドは忘れずにいたい。

NeoVimもあまり触らなくなってたがAstroNvim,LSP,Copilotのおかげでまたこちらでコード書くのも慣らしていきたいかも。やはりCLIだけで完結できるコンパクトさ・スピード感はIDEにない醍醐味でよき。