天才クールスレンダー美少女になりたい

チラシの表(なぜなら私はチラシの表にも印刷の上からメモを書くため)

今日から始めるdotfiles、そして4年間ずっと使っている自作コマンドの話

この記事はTSG Advent Calendar 2020の10日目の記事です。どっからどう見ても既に11日ですが、まあ1時間半の遅れは誤差ということで。
昨日は博多市さんの「sig-english」でした。え、記事が見えない? 頑張って心の目で見てください。博多市先生早く書いてくれないかな〜〜

おはようございます。初めての方にははじめまして。ふぁぼんと申します。
2020年に東大に入学し、4月頃からTSGで活動している華の未成年です。いや、「活動」はかなりミスリーディングですね。Slackで雑談するのは確かに「活動」なのですが、それ以外に有意義な活動をしたかと問われると、うーん……



今回は、私が6年間のMac生活で継ぎ足し継ぎ足し作ってきた秘伝のタレ、dotfilesの話をします。もともとは最近構築したLinuxデスクトップの話をする予定だったのですが、いま絶賛「積みゲー1つ崩すまでWindowsからArchLinuxに戻せません」縛りの最中で、スクショとか撮ってくるのが面倒なので……
というか、WindowsからLinuxに戻すと毎回Wi-Fi関連でトラブルが発生するんですよね。めんどくさい。そもそもデスクトップパソコンなんだから有線LAN環境を作った方が面倒が少ないんですが、いかんせん自宅のネットワークを整備するのが面倒で先送りにしています。最悪Wi-Fiアダプタのドングルを抜き差しすればだいたい直るし

dotfilesって何?

dotfilesとは、ホームディレクトリなどに置いてある設定ファイルを集めたプロジェクトのことです。そういうファイルはUNIX系の環境だとだいたいドットから始まるのでdotfilesという名前なわけです。わかりやすいですね。

設定ファイルだけでなく、自作コマンドや作業環境構築に便利なスクリプトなどをまとめて入れておくことも多いです。実際、私はそうしています。

ちなみに、これが私のdotfilesです。

github.com

このように、最近はdotfilesをGitHubなどで管理するのが一般的です。もちろんGitLabでもBitbucketでもなんでもいいです。とにかく、バージョン管理をして、そのソースコードをインターネットからアクセスできるところに置いておくのが大事。

dotfilesの何が嬉しいの?

さまざまな設定を全ての環境で同期することができます。
複数のパソコンを使っていて設定を同期したいとき、そして新しいパソコンに作業環境を構築したいときにとても便利です。カスタマイズしまくった作業環境をどこでも再現でき、作業を効率化できます。

使ってるパソコンが1つだけならバックアップ程度の意味しかありませんが、そのうちサーバで作業したり、あるいは新しいパソコンを使う機会ができるかもしれません。設定ファイルをまとめておくだけなら大した手間でもないし、やっておくと未来の自分が大助かりです。実際、私は前述のLinuxデスクトップを構築したときに、dotfilesを整備していた過去の自分に大いに助けられました。


さらに、スクリプトを実行するだけで設定ファイルを配置できるようにしておくと、新しい環境でもコマンド一発で環境構築が終了します。これは本当に便利です。

何をdotfilesで管理すればいいの?

汎用性のあるもの(環境依存性がないもの)ならなんでも大丈夫です。

  • シェル、ターミナルまわりの設定(.bashrcとか.zshrcとかconfig.fishとか)
  • エディタの設定(VimとかEmacsとか)
  • CLIツールの設定(tmuxとか)
  • GUIアプリ・ツールの設定
  • 自作コマンド

基本的に、設定ファイルを手書きするやつはdotfilesに極めて適しています。たとえば、エディタだとVimEmacsなどですね。
そうでないアプリでも工夫次第では管理できるかもしれませんが、正直「場合による」としか言えません……


私は基本的にZshVim(たまに使う)の設定ファイルと自作コマンドだけ管理してますが、これだけでもバチバチに便利です。

dotfilesってどうやって始めればいいの?

  1. dotfilesのプロジェクトを作る(GitHubとかで作ってからcloneしてもいいし、ローカルでgit initしてもいいし、好きなようにどうぞ)
  2. 設定ファイルをdotfilesのプロジェクトにコピーしてくる
  3. 元の設定ファイルをdotfiles以下の設定ファイルから元のパスにシンボリックリンクを張る
  4. 変更をリモートにpushする

こうすれば、dotfilesのファイルを変更するとグローバルの設定ファイルも自動で変更されることになります。(シンボリックリンクなので当然ですね)

新しい環境でいちいちシンボリックリンク手動で張っていくの面倒じゃない?

はい、ちょっと面倒です。というわけで、シンボリックリンクを張るスクリプトを書きましょう。
私はこの作業のことを「デプロイ」と呼んでいます。一般的には「インストール」と称されることが多いようですね。

いろんな人のdotfilesリポジトリで様々なインストールスクリプトが公開されています。高機能のものもありますが、ぶっちゃけ設定ファイルを列挙してln -sするだけのシェルスクリプトでも十分な気がします。ln -sは既にファイルがあったりするとエラーになるので、エラーが出たファイルだけ見て手動で作業すればいいでしょう。

もちろん、シェルスクリプトじゃなくても大丈夫です。RubyでもPythonでもお好きにどうぞ。


一応、自分のスクリプトも紹介しておきます。一応forceオプションも実装しています。

dotfiles/deploy.sh at master · fabon-f/dotfiles · GitHub

dotfilesはだいたい整備できたけど、次は何やればいいの?

dotfiles自体を整備できても、環境整備に終わりはありません。

シェル、エディタなどの設定をどんどん改善していって、最高の環境を目指しましょう。

特に、デフォルトのプロンプトをそのまま使ってる人はいい感じのプロンプトを探してみましょう。私はZshでpureというやつを使っています。これはとにかく起動が高速なので好きです。
もちろん、他にもいいやつはたくさんあります。いろいろ試してみるのも手ですよ。

github.com

dotfilesのちょっとしたテク

そのパソコン固有の設定を書きたいとき、あると思います。
そういうときは、たとえばZshなら.zshrcから.zshrc_localみたいなファイルを存在すれば読み込むようにしておくと、固有の設定をdotfilesに書かないですみます。

自分のdotfilesを晒すコーナー

作業ディレクトリをサッと作ってサッと消せる神自作コマンドtmpspaceのご紹介

dotfilesをインストールするときに、binディレクトリのそれぞれのファイルから~/binの下にシンボリックリンクを張り、~/binにPATHを通して自作コマンドを使えるようにしています。

いくつかある自作コマンドの中でも、tmpspaceというコマンドが自分の中で最強で、作ってから4年経ってなお毎日使っているので、布教したいと思います。

dotfiles/tmpspace at master · fabon-f/dotfiles · GitHub

コメントに書いている通り、アイデアは以下の記事の借り物です。

qiita.com

tmpspaceを実行すると、一時ディレクトリを生成し、そこをワーキングディレクトリとして新しいシェルを実行します。
ワーキングディレクトリをどれだけ散らかしても、シェルでexit 0を実行すれば、ワーキングディレクトリはきれいさっぱり消え去ります。
ディレクトリを残したい場合はexit 1などをするといいでしょう。同様に、シェルが突然異常終了しても作業用ディレクトリは消えませんし、元のパスが表示されるようになっています。


ただし、元の記事とは違い、$SHELLではなく、現在使っている(tmpspaceコマンドを打ったときの)シェルを起動するようにしています。要は親プロセスのコマンドを実行するということです。

ちなみに、Macで実行するとコマンド名前が-zshとかになって意味不明です。どういうことなのか調べても全く情報が出てこなくて、結果あまり美しくない回避策を取っています。

あと、4年前の方が今よりもまともに英語書けてて泣けますね……冠詞の抜けもあんまないし……高校の間ずっと英語放置してロシア語をしていたら英文法が破滅していました。
「一時的で揮発性のワークスペースを作る」(Make a temporary and volatile workspace)というのも、今はもう絶対に書けないイカした英語でマジで強い。


どうでもいいですが、私の個人的な趣味で、かなり厳密にPOSIX準拠にしています。別にPOSIX原理主義者ではないんですが。

Zsh環境のおはなし

細かい設定は「zsh カスタマイズ」みたいな記事のコピペです。

手動で諸々をインストールするのは面倒で嫌だったのですが、とはいえ毎回起動に1秒かかるというのも嫌なので、高速なZshプラグインマネージャのzinitを使っています。
プロンプトは前述の通り、軽量なpureです。

zinit

github.com

ちょっと前までzpluginって名前だったやつ。事前コンパイルや非同期ローディングをサポートしていて、とにかく速く起動させたい人におすすめ。

enhancd

github.com

どこにいてもcd dotfilesと打てばdotfilesの場所に移動できます。候補が複数ある場合はpecoやfzfなどのフィルターコマンドで選択できます。

pecoやfzfってなんぞ? という人のために説明すると、複数行の入力をインタラクティブ・インクリメントに検索できるコマンドです。

zsh-completions

github.com

Zshの補完ファイルです。いろんなコマンドのものが用意されています。

zsh-autosuggestions

github.com

Zshの履歴から、今入力しているコマンドに合うものを薄くサジェストしてくれます。

fast-syntax-highlighting

github.com

Zshのコマンドをハイライトしてくれます。

pure

github.com

軽量・高速なプロンプト。

Gitのステータスチェックなどの重い作業を非同期で行うなど、とにかく軽く高速に表示されるということを念頭に開発されています。

peco/fzfなどによるヒストリ検索

[追記] 結局、どうせfzfしか使わないので、今はfzfが公式に提供しているzshプラグインを使っています。
fzfのREADMEの通りinstallコマンドを実行すればインストールできますが、zshの場合やってることは「shell/completion.zshとshell/key-bindings.zshをsourceする」だけなので、別に手動でやっても変わりません。私は前述のzinitでインストール・ロードしています。


dotfiles/history.zsh at 17fcebe843e95bfdf6e750bd44fe3e8fdec5100d · fabon-f/dotfiles · GitHub

ctrl+Rを押すとpecoやfzfが起動して、検索・選択したコマンド履歴が入力された状態になります。

なんかいろいろ書いていますが、これはいろんな環境に対応すべく汎用的にしているからで、エッセンスはこれだけです。

select-history() {
    local original_buffer=$BUFFER
    local original_cursor=$CURSOR
    local result
    result=$(history -n 1 | fzf --query "$LBUFFER" --tac)
    if [[ $? = 0 ]]; then
        BUFFER=$result
        CURSOR=${#BUFFER}
    else
        BUFFER=$original_buffer
        CURSOR=$original_cursor
    fi

    zle reset-prompt
}

zle -N select-history
bindkey '^R' select-history

fzfのとこをお好みのツールに変えて.zshrcにコピペすれば動きます。
このあたりを詳しくいじりたい人はZLE(Zsh Line Editor)について調べるといいと思います。

direnvという神ツールの話

github.com

一部のディレクトリの下でだけ環境変数をセットしたい。そう考えたことがある人はたくさんいると思います。

そんな人にdirenv。これはガチ便利ツールで、ちょっと設定するだけで環境変数をいじることができます。使えば人生が2倍得しちゃう最高ツールです。

おわりに

さあ、今日からdotfilesを始めて、どこでも快適作業できるようにしてしまいましょう!


明日今日、12月11日はGueryさんの「何か書く」です。お楽しみに!