2024年度 わたしのdotfilesを紹介します
はじめに
これまで適当に管理していたdotfilesを一念発起して整理したので備忘録がてら記事にしておきます。
リポジトリは👇から。
※dotfilesに関しては以下の記事がとても分かりやすかったので紹介しておきます。
dotfilesを使った環境構築の手順
めちゃくちゃ簡単です。
- ホームディレクトリ(
~/
,$HOME/
)にdotfilesのリポジトリをcloneする。 -
sh setup.sh
を実行する。 - 終わり!
ディレクトリ構成
dotfiles/〇〇
ディレクトリ配下に各設定ファイルを置いてます。
dotfiles
ディレクトリ直下には環境変数であったり環境構築や環境更新に必要なシェルスクリプトを置いてます。
.
├── git
│ ├── .gitconfig
│ └── user.conf
├── homebrew
│ └── .Brewfile
├── sheldon
│ └── .sheldon.toml
├── shellchecker
│ └── .shellcheckrc
├── starship
│ └── .starship.toml
├── wezterm
│ └── .wezterm.lua
├── zsh
│ ├── sync
│ │ ├── check-and-sync-brewfile.zsh
│ │ ├── config.zsh
│ │ └── starship.zsh
│ ├── .zshrc
│ ├── alias.zsh
│ └── amazon-q.zsh
├── .env
├── .env.example
├── .gitignore
├── brew-init.sh
├── link.sh
├── replace-git.sh
├── replace-zsh.sh
├── setup.sh
└── unlink.sh
重要なスクリプトの説明
link.sh
ホームディレクトリにシンボリックリンクを作成するためのスクリプトです。
dotfiles/XXX/.YYY
のような.
から始まるファイルが対象になっています。
#!/bin/bash
DOTFILES_DIR=~/dotfiles
echo "シンボリックリンクを作成します"
# dotfilesディレクトリ内の二つ下のディレクトリにあるファイルに対してループ
for file in "$DOTFILES_DIR"/*/.[^.]*; do
# '.' と '..' はスキップ
if [[ $file == "$DOTFILES_DIR/." || $file == "$DOTFILES_DIR/.." ]]; then
continue
fi
# ホームディレクトリ直下に作成するパスを計算
link_name=~/${file#"$DOTFILES_DIR"/*/}
# シンボリックリンクの作成
ln -sfn "$file" "$link_name"
# 作成したシンボリックリンクを出力
echo "リンクを作成: $file -> $link_name"
done
echo "シンボリックリンクがホームディレクトリ直下に作成されました"
setup.sh
環境構築時に実行するスクリプトです。
他のスクリプトもここで実行しこのファイルだけの実行で済むようにしています。
#!/bin/bash
echo "セットアップを開始します"
# dotfilesのシンボリックリンクを作成する
source ~/dotfiles/link.sh
# homebrewがインストールされていない場合はインストール
if ! type brew >/dev/null 2>&1; then
echo "Homebrewをインストールします"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
else
echo "Homebrewはすでにインストールされています"
fi
# Brewfileに記載されているパッケージをインストール
source ~/dotfiles/brew-init.sh
# zshをbrewのものに置き換え
source ~/dotfiles/replace-zsh.sh
# gitをbrewのものに置き換え
source ~/dotfiles/replace-git.sh
echo "セットアップが完了しました"
echo "Next..."
echo "1. .envを追加し、環境変数を設定してください。"
echo "2. git/user.confを追加し、ユーザー情報を設定してください。"
echo "3. ターミナルを再起動してください。"
Git
これなに?
皆さん使っていると思うので省略します。
ディレクトリ構成
git
├── .gitconfig
└── user.conf
設定ファイル
[include]
path = ~/dotfiles/git/user.conf
[init]
defaultBranch = main
[push]
default = current
autoSetupRemote = true
[merge]
ff = false
[pull]
ff = only
[alias]
s = switch
st = status
c = commit
p = pull
ps = push
a = add
r = reset
[user]
email = <メールアドレス>
name = <ユーザーネーム>
スクリプト
#!/bin/bash
# Brewでgitがインストールされているか確認
if ! brew list git &>/dev/null; then
echo "gitがインストールされていないため、インストールを開始します..."
brew install git
else
echo "gitはすでにインストールされています。"
fi
# Brewでインストールされたgitのパスを取得
GIT_PATH=$(brew --prefix)/bin/git
# 現在のgitのパスを確認
CURRENT_GIT_PATH=$(which git)
# デフォルトのgitがすでにbrewのものかどうか確認
if [ "$CURRENT_GIT_PATH" == "$GIT_PATH" ]; then
echo "すでにHomebrewでインストールされたgitがデフォルトになっています。"
else
echo "Homebrewでインストールされたgitをデフォルトに設定します..."
# パスを追加
SHELL_PATH_FILE="$HOME/dotfiles/zsh/sync/path.zsh"
echo "export PATH=\"$GIT_PATH:\$PATH\"" >>"$SHELL_PATH_FILE"
# シェル設定を再読み込み
source "$HOME"/.zshrc
echo "Homebrewでインストールされたgitがデフォルトに設定されました。"
echo "新しいターミナルセッションを開くと、設定が反映されます。"
fi
Point
-
.env
から取得して.gitconfig
に反映するのが難しそうだったので個人情報部分をuser.conf
に切り出してます。 - セットアップ時には
user.conf
を作成してあげる必要があります。- ここはシェルスクリプトでもうちょっと改善できるかも。
- GitもHomebrewで管理したいため、デフォルトで入っているGitをHomebrewのものに置き換えるスクリプトを環境構築時に実行します。
Homebrew
これなに?
macOS or Linux用のパッケージマネージャーです。
これを使うと自分で導入するほぼ全てのGUI, CLIツールを一元管理することができます。
👇の設定ファイルを見ていただければわかると思いますが筆者は全てのCLIツールやアプリケーションをHomebrewで管理しています。
ディレクトリ構成
homebrew
└── .Brewfile
設定ファイル
tap "homebrew/bundle"
brew "bat"
brew "eza"
brew "fd"
brew "fzf"
brew "git"
brew "just"
brew "mas"
brew "ripgrep"
brew "sheldon"
brew "shellcheck"
brew "shfmt"
brew "starship"
brew "tree"
brew "zsh"
cask "1password"
cask "amazon-q"
cask "arc"
cask "chatgpt"
cask "flameshot"
cask "font-monaspace-nerd-font"
cask "google-chrome@canary"
cask "hiddenbar"
cask "hot"
cask "insomnia"
cask "kap"
cask "notchnook"
cask "orbstack"
cask "raycast"
cask "spotify"
cask "steam"
cask "tableplus"
cask "visual-studio-code"
cask "wezterm"
mas "RunCat", id: 1429033973
...
# vscodeもbrewで管理していれば拡張機能もここに記載される
# 今回は数が多いので省略
スクリプト
#!/bin/bash
echo "Brewfileに記載されているパッケージをインストールします"
brew bundle --global
#!/bin/bash
function check_and_sync_brewfile() {
# 現在インストールされているパッケージ一覧を取得
installed_packages=$(brew leaves && brew list --cask)
# .Brewfileに記載されているパッケージ一覧を取得
brewfile_packages=$(grep '^(brew|cask)' ~/dotfiles/homebrew/.Brewfile | awk '{gsub(/"/, "", $2); print $2}')
# インストールされていないパッケージをインストールし、.Brewfileに追加
echo ".Brewfileに記載されているがインストールされていないパッケージをインストールします:"
installed_any=false
while read -r package; do
if ! echo "$installed_packages" | grep -q "^$package$"; then
echo "インストール中: $package"
brew install "$package"
installed_any=true
fi
done < <(echo "$brewfile_packages")
if [ "$installed_any" = false ]; then
echo "すべてのパッケージがすでにインストールされています。"
fi
echo
# .Brewfileに記載されていないがインストールされているパッケージを.Brewfileに追加
echo ".Brewfileに記載されていないがインストールされているパッケージを.Brewfileに追加します:"
installed_any=false
while read -r package; do
if ! echo "$brewfile_packages" | grep -q "^$package$"; then
installed_any=true
fi
done < <(echo "$installed_packages")
if [ "$installed_any" = false ]; then
echo "すべてのパッケージがすでに.Brewfileに記載されています。"
else
echo ".Brewfileの内容と実際のインストール状況が一致しません。"
echo ".Brewfileを再生成します。"
brew bundle dump --force --file=~/dotfiles/homebrew/.Brewfile
fi
}
# brewコマンドが実行された時に発火する
preexec() {
if [[ "$1" == brew* ]]; then
check_and_sync_brewfile
fi
}
Point
- masを使用して、AppStoreにしか存在しないものもbrewの管轄にしています。
-
brew bundle
を使用することでインストールしているものを設定ファイルとして残すことができます。- GitHubなどで管理することによって異なるマシンでも同一の環境を構築できます。
- .Brewfileの更新は手動でしか行えないので
brew
コマンドを使用したときに.Brewfileの再生成や足りていないパッケージのインストールを行なうスクリプトをzshのpreexec関数でフックしています。 - デフォルトは
Brewfile
という名前で生成されますが、dotfilesという名目で管理するため.Brewfile
という名前で保存しています。
Sheldon(Zsh)
これなに?
シェルのプラグインや、分割された設定ファイルなどを管理するマネージャーツールです。
これを使用することでペライチの混沌(カオス)な.zshrc
から解放されます...!!!
ディレクトリ構成
sheldon
└── .sheldon.toml
zsh
├── sync
│ ├── check-and-sync-brewfile.zsh
│ ├── config.zsh
│ ├── path.zsh
│ └── starship.zsh
├── .zshrc
├── alias.zsh
└── amazon-q.zsh
設定ファイル
Sheldonの設定に関しては👇の方の記事を参考にさせて頂きました🙇♂️
zinitが不安なのでsheldonへ移行したらzshの起動が50msと更に速くなった
shell = "zsh"
# デフォルトを遅延読み込みにする
apply = ["defer"]
[plugins.zsh-defer]
github = "romkatv/zsh-defer"
apply = ["source"]
# 遅延読み込みの設定
[templates]
defer = "{% for file in files %}zsh-defer source \"{{ file }}\"\n{% endfor %}"
# シンタックスハイライト(遅延読み込み非対応)
[plugins.syntax-highlighting]
github = "zdharma/fast-syntax-highlighting"
# zsh配下のファイルは遅延読み込みする
[plugins.local-defers]
local = "~/dotfiles/zsh"
use = ["{!sync,*}.zsh"]
# zsh/sync配下のファイルは遅延読み込みしない
[plugins.local-sync]
local = "~/dotfiles/zsh"
use = ["sync/*.zsh"]
apply = ["source"]
#!/bin/bash
# zshの読み込み時間を表示するときはコメントアウトを外す
# zmodload zsh/zprof
export SHELDON_CONFIG_FILE=$HOME/.sheldon.toml
eval "$(sheldon source)"
# zprof
#!/bin/bash
alias c='clear'
alias reload='exec $SHELL -l'
alias ls='eza -alh --icons=auto --no-user'
alias cat='bat --theme="Dracula"'
alias find='fd'
alias cdf='cd "$(dirname "$(fzf --preview="bat --color=always {}")")"'
alias grep='rg'
alias g='git'
#!/bin/bash
# 環境変数
export LANG=ja_JP.UTF-8
# ヒストリの設定
HISTFILE=~/.zsh_history
HISTSIZE=30000
# shellcheck disable=SC2034
SAVEHIST=30000
# 他のzshと履歴を共有
setopt inc_append_history
setopt share_history
# 直前のコマンドの重複を削除
setopt hist_ignore_dups
# 同じコマンドをヒストリに残さない
setopt hist_ignore_all_dups
# パスを直接入力してもcdする
setopt auto_cd
# cd-<tab>で以前移動したディレクトリを表示
setopt auto_pushd
# 環境変数を補完
setopt auto_param_keys
# historyに保存するときに余分なスペースを削除する
setopt hist_reduce_blanks
その他
#!/bin/bash
function check_and_sync_brewfile() {
# 現在インストールされているパッケージ一覧を取得
installed_packages=$(brew leaves && brew list --cask)
# .Brewfileに記載されているパッケージ一覧を取得
brewfile_packages=$(grep '^(brew|cask)' ~/dotfiles/homebrew/.Brewfile | awk '{gsub(/"/, "", $2); print $2}')
# インストールされていないパッケージをインストールし、.Brewfileに追加
echo ".Brewfileに記載されているがインストールされていないパッケージをインストールします:"
installed_any=false
while read -r package; do
if ! echo "$installed_packages" | grep -q "^$package$"; then
echo "インストール中: $package"
brew install "$package"
installed_any=true
fi
done < <(echo "$brewfile_packages")
if [ "$installed_any" = false ]; then
echo "すべてのパッケージがすでにインストールされています。"
fi
echo
# .Brewfileに記載されていないがインストールされているパッケージを.Brewfileに追加
echo ".Brewfileに記載されていないがインストールされているパッケージを.Brewfileに追加します:"
installed_any=false
while read -r package; do
if ! echo "$brewfile_packages" | grep -q "^$package$"; then
installed_any=true
fi
done < <(echo "$installed_packages")
if [ "$installed_any" = false ]; then
echo "すべてのパッケージがすでに.Brewfileに記載されています。"
else
echo ".Brewfileの内容と実際のインストール状況が一致しません。"
echo ".Brewfileを再生成します。"
brew bundle dump --force --file=~/dotfiles/homebrew/.Brewfile
fi
}
# brewコマンドが実行された時に発火する
preexec() {
if [[ "$1" == brew* ]]; then
check_and_sync_brewfile
fi
}
#!/bin/bash
export PATH="/opt/homebrew/bin/git:$PATH"
#!/bin/bash
export STARSHIP_CONFIG=$HOME/.starship.toml
eval "$(starship init zsh)"
#!/bin/bash
# Amazon Q pre block. Keep at the top of this file.
[[ -f "${HOME}/Library/Application Support/amazon-q/shell/zshrc.pre.zsh" ]] && builtin source "${HOME}/Library/Application Support/amazon-q/shell/zshrc.pre.zsh"
# Amazon Q post block. Keep at the bottom of this file.
[[ -f "${HOME}/Library/Application Support/amazon-q/shell/zshrc.post.zsh" ]] && builtin source "${HOME}/Library/Application Support/amazon-q/shell/zshrc.post.zsh"
スクリプト
#!/bin/bash
# Brewでzshがインストールされているか確認
if ! brew list zsh &>/dev/null; then
echo "zshがインストールされていないため、インストールを開始します..."
brew install zsh
else
echo "zshはすでにインストールされています。"
fi
# インストールしたzshのパスを取得
ZSH_PATH=$(brew --prefix)/bin/zsh
# インストールされたzshがシェルとして許可されているか確認し、追加
if ! grep -Fxq "$ZSH_PATH" /etc/shells; then
echo "$ZSH_PATH" | sudo tee -a /etc/shells
fi
# デフォルトシェルをインストールしたzshに変更
chsh -s "$ZSH_PATH"
# 設定の反映を促すメッセージ
echo "brewでインストールしたzshをデフォルトシェルに設定しました。ターミナルを再起動してください。"
Point
- ezaやbat、ripgrepなど、既存コマンドの代替ツールを使用することで効率や視認性を向上させています。
- aliasやconfigなど設定もファイルとして分割し、
.zshrc
をシンプルにすることで管理しやすくしています。 - 設定やプラグインを遅延読み込みさせることでzshの立ち上げを高速化しています。
- 補完系はAmazon Q(旧Fig)に一任することで面倒な設定を省いています。
- Amazon Qはめちゃ便利なのでぜひ試したことのない方には一度導入してもらいたいです。
- Gitと同様にZshもHomebrewで管理したいためデフォルトで入っているZshをHomebrewのものに置き換えるスクリプトを環境構築時に実行します。
WezTerm
これなに?
Rust製の軽量で高速なターミナルです。
設定は全てLua Languageで記述し、設定できる項目が非常に沢山あります!
ちなみに自分はこんな感じにしてます。(モチベが上がりますね \ΦwΦ/ )
ディレクトリ構成
wezterm
└── .wezterm.lua
設定ファイル
local wezterm = require 'wezterm'
-- .envから環境変数を読み込む
local load_env = function(file)
local env = {}
for line in io.lines(file) do
-- 行が空行やコメント行(#で始まる)でない場合
if line:match("^%s*#") == nil and line:match("^%s*$") == nil then
-- KEY=VALUEの形式を解析
local key, value = line:match("^%s*([^=]+)%s*=%s*(.*)%s*$")
if key and value then
-- 環境変数として設定
env[key] = value
end
end
end
return env
end
local dirName = os.getenv("HOME")
local env = load_env(string.format("%s/dotfiles/.env", dirName))
local config = wezterm.config_builder()
-- Color scheme
config.color_scheme = 'Andromeda'
-- Background
config.background = {
{
source = {
File = env.BACKGROUND_IMAGE_PATH
},
attachment = { Parallax = 0.05 },
hsb = {
brightness = 0.05,
}
}
}
-- Cursor
config.default_cursor_style = "BlinkingBlock"
-- TabBar
config.hide_tab_bar_if_only_one_tab = true -- タブが1つだけの場合はタブバーを非表示にする
config.show_tab_index_in_tab_bar = false -- タブバーにインデックスを表示しない
-- Font
config.line_height = 1.1
config.treat_east_asian_ambiguous_width_as_wide = true -- 日本語を2文字分の幅で表示する
config.font = wezterm.font "MonaspiceAr Nerd Font Mono"
-- Window
config.window_decorations = "RESIZE" -- タイトルバーを非表示にする
config.window_close_confirmation = "NeverPrompt" -- ウィンドウを閉じる際の確認を行わない
config.initial_rows = 50 -- 初期の行数
config.initial_cols = 150 -- 初期の列数
return config
BACKGROUND_IMAGE_PATH= # weztermの背景画像のパス
Point
- 環境変数を読み込めるようにして、好きな背景画像を設定できるようにしました。
- モチベが上がります!!
- 背景透過+ぼかしもできます。
Starship
これなに?
先ほどちらっとお見せしましたがプロンプトの見た目を整えてくれるこれまたRust製のツールです。
カスタマイズ製が非常に高く自分だけのプロンプトを作成できちゃいます。(自分はデフォルトで用意されているテーマを使用していますが...)
ディレクトリ構成
starship
└── .starship.toml
設定ファイル
公式のpresetsを貼り付けているだけなので省略します。
一応残しておく
[aws]
symbol = " "
[buf]
symbol = " "
[c]
symbol = " "
[conda]
symbol = " "
[crystal]
symbol = " "
[dart]
symbol = " "
[directory]
read_only = " "
[docker_context]
symbol = " "
[elixir]
symbol = " "
[elm]
symbol = " "
[fennel]
symbol = " "
[fossil_branch]
symbol = " "
[git_branch]
symbol = " "
[golang]
symbol = " "
[guix_shell]
symbol = " "
[haskell]
symbol = " "
[haxe]
symbol = " "
[hg_branch]
symbol = " "
[hostname]
ssh_symbol = " "
[java]
symbol = " "
[julia]
symbol = " "
[kotlin]
symbol = " "
[lua]
symbol = " "
[memory_usage]
symbol = " "
[meson]
symbol = " "
[nim]
symbol = " "
[nix_shell]
symbol = " "
[nodejs]
symbol = " "
[ocaml]
symbol = " "
[os.symbols]
Alpaquita = " "
Alpine = " "
AlmaLinux = " "
Amazon = " "
Android = " "
Arch = " "
Artix = " "
CentOS = " "
Debian = " "
DragonFly = " "
Emscripten = " "
EndeavourOS = " "
Fedora = " "
FreeBSD = " "
Garuda = " "
Gentoo = " "
HardenedBSD = " "
Illumos = " "
Kali = " "
Linux = " "
Mabox = " "
Macos = " "
Manjaro = " "
Mariner = " "
MidnightBSD = " "
Mint = " "
NetBSD = " "
NixOS = " "
OpenBSD = " "
openSUSE = " "
OracleLinux = " "
Pop = " "
Raspbian = " "
Redhat = " "
RedHatEnterprise = " "
RockyLinux = " "
Redox = " "
Solus = " "
SUSE = " "
Ubuntu = " "
Unknown = " "
Void = " "
Windows = " "
[package]
symbol = " "
[perl]
symbol = " "
[php]
symbol = " "
[pijul_channel]
symbol = " "
[python]
symbol = " "
[rlang]
symbol = " "
[ruby]
symbol = " "
[rust]
symbol = " "
[scala]
symbol = " "
[swift]
symbol = " "
[zig]
symbol = " "
スクリプト
#!/bin/bash
export STARSHIP_CONFIG=$HOME/.starship.toml
eval "$(starship init zsh)"
Point
特にないです!
おわりに
本当はRaycast(Spotlightのようなランチャーアプリ)の設定やMac本体の設定(defaultコマンドによる設定)もdotfilesに追加しておきたかったのですが時間が足らず断念しました...
時間があれば追記しておこうと思いますmm
今回はツールの細かい説明まではしませんでしたが「こんなんがあるのね〜」程度に把握しておいてもらえたら嬉しいです。
Discussion