dotfilesを全面的にリニューアルしました。
この記事でわかること:
- dotfiles → dots への移行理由と背景
- devboxによるNixベースのパッケージ管理の実践
- Ghosttyターミナルの設定と使用感
- fzf + ghqのキャッシュ機能で爆速リポジトリ検索
- zinit turbo modeでシェル起動時間50msを実現する具体的な設定
- alacritty/zellijからの移行ポイント
移行の背景
以前のdotfilesリポジトリでは、以下の構成で開発環境を管理していました。
| カテゴリ | 以前 | 現在 |
|---|---|---|
| リポジトリ | dotfiles | dots |
| パッケージ管理 | Homebrew + Cargo | devbox (Nix) |
| ターミナル | Alacritty | Ghostty |
| マルチプレクサ | Zellij | tmux |
| dotfiles管理 | chezmoi | chezmoi |
| プラグイン管理 | zinit | zinit (turbo mode強化) |
特に devbox と Ghostty の導入が今回の移行の核心です。
なぜdotsへ移行したのか
1. パッケージ管理の複雑化
以前はHomebrewとCargoの併用でツールを管理していました。macOSとLinuxで環境を統一しようとすると、Homebrewはlinuxbrewが必要になり、設定が煩雑になります。
また、Rustツールはcargo installで管理していましたが、バージョン固定やアップデート管理が手動になりがちでした。
2. 再現性への課題
チームメンバーや新しいマシンで同じ環境を再現しようとすると、Homebrewのバージョン差異やOSごとのパッケージ名の違いで問題が発生することがありました。
3. ターミナルの進化
Alacrittyは優秀なターミナルでしたが、2024年末にGhosttyが正式リリースされ、状況が変わりました。
devbox: Nixベースの開発環境管理
Devbox: Portable, Isolated Dev Environmentswww.jetify.com
devboxは Jetify が開発する、Nixをバックエンドに持つ開発環境管理ツールです。Nixの複雑さを隠蔽しつつ、その恩恵を受けられる点が特徴です。
devboxの利点
1. 完全な再現性
devboxはNixパッケージマネージャを内部で使用しています。Nixの特徴である「宣言的なパッケージ管理」により、どのマシンでも全く同じバージョンのツールがインストールされます。
{ "packages": [ "go@latest", "nodejs@20", "python@3.12", "neovim@latest", "fzf@latest", "ripgrep@latest", "fd@latest", "lazygit@latest", "delta@latest", "gitleaks@latest" ]}2. グローバル環境のサポート
devboxには「グローバルパッケージ」の概念があり、プロジェクト固有ではなくシステム全体で使いたいツールを管理できます。
# グローバルにパッケージを追加devbox global add fzf ripgrep fd
# シェル起動時に自動読み込みeval "$(devbox global shellenv)"3. Homebrewとの併用も可能
すべてを移行する必要はありません。GUIアプリケーション(Raycast、1Password等)はHomebrewのCaskで管理し、CLIツールはdevboxで管理する、という使い分けが可能です。
40+のツールを一元管理
現在、devboxで管理しているツールは40以上あります。主要なものを紹介します。
| カテゴリ | ツール | 用途 |
|---|---|---|
| エディタ | Neovim | LSP + GitHub Copilot対応 |
| Git | lazygit, delta, gitleaks | TUI、差分表示、シークレット検出 |
| 検索 | fzf, ripgrep, fd | ファジー検索、高速grep、高速find |
| シェル | starship, atuin | プロンプト、履歴同期 |
| 言語 | Go, Node.js, Python | 開発用ランタイム |
| リポジトリ | ghq | リポジトリ一元管理 |
| K8s | kubectl | Kubernetes操作 |
| タスク | just | Make代替 |
Ghostty: 次世代ターミナルエミュレータ
GhosttyはZig言語で書かれた新しいターミナルエミュレータです。開発者はHashiCorpの共同創設者であるMitchell Hashimoto氏で、2024年12月に正式リリースされました。
AlacrittyからGhosttyへ
Alacrittyも高速なGPU加速ターミナルとして優秀でしたが、Ghosttyには以下の利点があります。
1. ネイティブなタブ・分割サポート
Alacrittyはタブや画面分割の機能を持たず、tmuxやzellijとの併用が前提でした。Ghosttyはネイティブでこれらをサポートしています。
# ウィンドウ分割のキーバインドkeybind = super+d=new_split:rightkeybind = super+shift+d=new_split:down
# タブ操作keybind = super+t=new_tabkeybind = super+w=close_surfacekeybind = super+shift+left_bracket=previous_tabkeybind = super+shift+right_bracket=next_tab2. 日本語レンダリングの最適化
Ghosttyは日本語フォントのレンダリングに優れています。UDEV Gothic NFフォントとの相性も良好です。
font-family = "UDEV Gothic NF"font-size = 16adjust-underline-position = 23. 設定のシンプルさ
AlacrittyはTOML形式でしたが、Ghosttyはシンプルなkey=value形式です。
# 外観background-opacity = 0.95window-padding-x = 8window-padding-y = 8
# カラースキーム(Tokyo Night)background = #1a1b26foreground = #c0caf5selection-background = #33467cselection-foreground = #c0caf5Zellijからtmuxへの回帰
Zellijは素晴らしいターミナルマルチプレクサですが、以下の理由でtmuxに戻りました。
- Ghosttyのネイティブ分割機能により、マルチプレクサの必要性が減少
- SSH接続先での互換性を考えるとtmuxの方が有利
- 長年の蓄積があるtmuxの方がトラブルシューティングが容易
ただし、Ghosttyのネイティブ機能だけで完結する場合も多く、tmuxは補助的な立ち位置になっています。
fzf + ghqで爆速リポジトリ検索
開発効率を上げる上で、リポジトリ間の移動は非常に重要です。ghqでリポジトリを一元管理し、fzfで高速検索する組み合わせは定番ですが、キャッシュ機能を追加することでさらに高速化しています。
キャッシュ付きghq関数
# ghqのリスト出力をキャッシュするための変数typeset -g _GHQ_CACHE=""
# キャッシュを更新する関数_ghq_cache_update() { _GHQ_CACHE="$(ghq list)"}
# fzf + ghq でリポジトリを検索・移動_fzf_cd_ghq() { # キャッシュが空なら初期化 [[ -z "$_GHQ_CACHE" ]] && _ghq_cache_update
local repo repo=$(echo "$_GHQ_CACHE" | fzf \ --prompt="repo> " \ --preview="bat --color=always --style=plain $(ghq root)/{}/README.md 2>/dev/null || cat $(ghq root)/{}/README.rst 2>/dev/null || echo 'No README'" \ --preview-window=right:60%:wrap \ --bind="ctrl-r:reload(ghq list)" \ )
[[ -n "$repo" ]] && cd "$(ghq root)/$repo"}
# キーバインド: Ctrl+G でリポジトリ検索bindkey -s '^g' '_fzf_cd_ghq\n'
# エイリアスalias repos='_fzf_cd_ghq'ghqラッパーで自動キャッシュ更新
ghq getやghq createでリポジトリを追加した際、自動的にキャッシュを更新します。
# ghqのラッパー関数(キャッシュ自動更新)ghq() { command ghq "$@"
# get, create, rm の場合はキャッシュを更新 case "$1" in get|create|rm) _ghq_cache_update ;; esac}この仕組みにより、数百のリポジトリがあっても一瞬で検索できます。初回のみghq listが実行され、以降はキャッシュから取得するためです。
READMEプレビュー
fzfの--previewオプションで、選択中のリポジトリのREADME.mdをリアルタイムプレビューしています。これにより、リポジトリの内容を確認しながら選択できます。
シェル起動時間50msの実現
新しいdots環境では、zshの起動時間が約50msまで高速化されました。
zinit turbo modeの活用
プラグイン管理にはzinitを使用し、turbo modeによる遅延読み込みを徹底しています。
# zinitの初期化source "${ZINIT_HOME}/zinit.zsh"
# ===== 遅延読み込みプラグイン(turbo mode) =====
# 補完機能(wait"0"で最優先遅延読み込み)zinit ice wait"0" lucid blockfzinit light zsh-users/zsh-completions
# シンタックスハイライト(fast-syntax-highlighting推奨)zinit ice wait"0" lucid atinit"zpcompinit; zpcdreplay"zinit light zdharma-continuum/fast-syntax-highlighting
# 自動補完サジェストzinit ice wait"0" lucid atload"_zsh_autosuggest_start"zinit light zsh-users/zsh-autosuggestions
# 履歴サブストリング検索zinit ice wait"0" lucidzinit light zsh-users/zsh-history-substring-searchツール初期化もturbo modeで
各種ツールの初期化も遅延読み込みすることで、起動時間を短縮しています。
# ===== ツール初期化(turbo mode) =====
# Starship(プロンプト)zinit ice wait"!0" lucid atload'eval "$(starship init zsh)"'zinit light zdharma-continuum/null
# Zoxide(ディレクトリジャンプ)zinit ice wait"0" lucid atload'eval "$(zoxide init zsh)"'zinit light zdharma-continuum/null
# Atuin(シェル履歴)zinit ice wait"0" lucid atload'eval "$(atuin init zsh)"'zinit light zdharma-continuum/null
# fzf(Tokyo Nightテーマ)zinit ice wait"0" lucid atload'export FZF_DEFAULT_OPTS=" --color=fg:#c0caf5,bg:#1a1b26,hl:#bb9af7 --color=fg+:#c0caf5,bg+:#292e42,hl+:#7dcfff --color=info:#7aa2f7,prompt:#7dcfff,pointer:#7dcfff --color=marker:#9ece6a,spinner:#9ece6a,header:#9ece6a"eval "$(fzf --zsh)"'zinit light zdharma-continuum/null補完キャッシング
各種CLIツールの補完生成もキャッシュすることで高速化しています。
# ===== 補完キャッシング =====
# GitHub CLIzinit ice wait"1" lucid as"completion" id-as"gh-completion" \ atclone"gh completion -s zsh > _gh" atpull"%atclone"zinit light zdharma-continuum/null
# chezmoizinit ice wait"1" lucid as"completion" id-as"chezmoi-completion" \ atclone"chezmoi completion zsh > _chezmoi" atpull"%atclone"zinit light zdharma-continuum/null
# kubectlzinit ice wait"1" lucid as"completion" id-as"kubectl-completion" \ atclone"kubectl completion zsh > _kubectl" atpull"%atclone"zinit light zdharma-continuum/nullturbo modeの仕組み
zinit turbo modeは、プロンプトが表示された後にプラグインを読み込む仕組みです。
wait"0": プロンプト表示直後に読み込みwait"1": プロンプト表示から1秒後に読み込みlucid: 読み込み時のメッセージを非表示atload: 読み込み後に実行するコマンド
これにより、ユーザーがコマンドを入力し始める頃には全てのプラグインが読み込み完了しています。
セットアップ方法
新しいdots環境は、ワンライナーでセットアップできます。
# 個人環境curl -fsSL https://raw.githubusercontent.com/paveg/dots/main/install.sh | bash
# 仕事環境(メールアドレス等が変わる)BUSINESS_USE=1 curl -fsSL https://raw.githubusercontent.com/paveg/dots/main/install.sh | bash初回実行時に名前とメールアドレスを入力すると、Gitの設定等が自動で行われます。
gitleaksでセキュリティ強化
GitHub - gitleaks/gitleaks: Find secrets with Gitleaks 🔑github.com
新しくgitleaksを導入しました。これは800以上のパターンでAPIキーやトークンなどの機密情報を検出するツールです。
# コミット前のチェックgitleaks protect --staged
# リポジトリ全体のスキャンgitleaks detectpre-commitフックと組み合わせることで、うっかり機密情報をコミットしてしまう事故を防げます。
まとめ
dotfilesからdotsへの移行で、以下の改善を実現しました。
| 改善項目 | 詳細 |
|---|---|
| パッケージ管理 | devboxによるNixベースの再現可能な環境 |
| ターミナル | Ghosttyによる高速で美しい体験 |
| シェル起動 | zinit turbo modeで約50ms |
| リポジトリ検索 | fzf + ghqのキャッシュで瞬時に検索 |
| セキュリティ | gitleaksで機密情報漏洩防止 |
開発環境の構築は一度やると長く使い続けるものです。定期的に見直して、より良い環境を追求していくのが楽しいですね。
リポジトリはこちらです。参考になれば幸いです。
それでは、またね。