Nix学習備忘録Part 2-1-2: GitHubのzshプラグインを利用する
1 はじめに
本記事ではHome Managerを用いて導入したZ ShellでGitHub上にあるプラグインを利用する方法について書きます。 Home Mangerを用いたzshの導入がお済みでない方は、前回の記事を先にご覧ください。
また、GitHub上のオープンソースを利用させて頂き、 ls
コマンドの見た目も整えてみたいと思います。
2 外部パッケージの導入方法
基本的にはpkgs.fetchFromGitHub
関数を用いて、 GitHubからソースを引っ張ってきます。 let ~ in ...
式を用いて、パッケージをインストールします。 let
式の中にはパッケージの情報を持つ定数を記述します。 そのフォーマットが以下の通りです:
variableName = {
name = "プラグイン名";
src = pkgs.fetchFromGitHub {
owner = "作成者のGitHubユーザ名";
repo = "プラグインのリポジトリ名";
rev = "コミットID";
sha256 = "Nixが生成するハッシュ値";
};
};
sha256
以外はすぐにイメージが付くと思います。 一番戸惑うのがsha256
ですが、これはNixが自動で生成してくれるハッシュを記述します。 Nixの記事では多くの場合、"00000000000000000000000000000000000000000000"
などの適当な値で束縛している例をよく見ますが、 一応lib.fakeSha256
という関数が用意されており、この関数を使えば桁数を覚えておく必要も無いので、 私は最初にこのlib.fakeSha256
という関数を利用しています。
zshプラグインの場合、home.nix
のzsh
内に以下のように記述します:
plugins =
let
plugin1 = {
name = "plugin1";
src = pkgs.fetchFromGitHub {
owner = "someone";
repo = "repository1";
rev = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
sha256 = "mrPMgwVkqOlKjvy1106MUKFjfkslajfjfkdslasjdkfj";
};
};
plugin2 = {
name = "plugin2";
src = pkgs.fetchFromGitHub {
owner = "somebody";
repo = "repository2";
rev = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
sha256 = "KLUYpUu4DHRumQZ3w59m9aTW6TBKMCXl2UcKihfjdhsj";
};
};
in [
plugin1
plugin2];
ざっくり説明すると、plugins = [];
というリスト形式で宣言するものを、 let ~ in ...
式を用いて、 プラグインを定義してから、リストに入れるということをしています。
では、早速autojump
というzshのプラグインを入れてみましょう。
2.1 autojump: 曖昧な名前でディレクトリ移動を可能にする
autojump
は一度訪問したことのあるディレクトリであれば、 曖昧な名前で移動できるようになるという便利なプラグインです。 GitHubリポジトリはwting/autojumpです。
2022/01/31現在の最新バージョンを上のフォーマットを参考にして設定してみます。 記述するのはhome.nix
のzsh
の中です。
plugins =
let
autojump = {
name = "autojump";
src = pkgs.fetchFromGitHub {
owner = "wting";
repo = "autojump";
rev = "06e082c91805cb022900819b2e0881eeae780d58";
sha256 = lib.fakeSha256;
};
};
in [
autojump];
これでhome-manager switch
を実行すると、sha256
の値が適当であるため、エラーが出ます:
$ home-manager switch
these 3 derivations will be built:
/nix/store/dvhngvpnk39ib19i9mlh8m89j621nykx-source.drv
/nix/store/2a26hw00za9x5bpwfmxglq06v6dksdw4-home-manager-files.drv
/nix/store/2l3b8vl5bfkcjspd56cimzw7wxnwyfj6-home-manager-generation.drv
building '/nix/store/dvhngvpnk39ib19i9mlh8m89j621nykx-source.drv'...
trying https://github.com/wting/autojump/archive/06e082c91805cb022900819b2e0881eeae780d58.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 156 0 156 0 0 491 0 --:--:-- --:--:-- --:--:-- 490
100 55488 0 55488 0 0 79451 0 --:--:-- --:--:-- --:--:-- 79451
unpacking source archive /tmp/nix-build-source.drv-0/06e082c91805cb022900819b2e0881eeae780d58.tar.gz
error: hash mismatch in fixed-output derivation '/nix/store/dvhngvpnk39ib19i9mlh8m89j621nykx-source.drv':
specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
got: sha256-mrPMgwVkqOlKjvy1106MUKF7OlEtKdt8E9mqCg7U9+U=
error: 1 dependencies of derivation '/nix/store/2a26hw00za9x5bpwfmxglq06v6dksdw4-home-manager-files.drv' failed to build
error: 1 dependencies of derivation '/nix/store/2l3b8vl5bfkcjspd56cimzw7wxnwyfj6-home-manager-generation.drv' failed to build
エラーメッセージの以下の部分を見ます:
specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
got: sha256-mrPMgwVkqOlKjvy1106MUKF7OlEtKdt8E9mqCg7U9+U=
mrPMgwVkqOlKjvy1106MUKF7OlEtKdt8E9mqCg7U9+U=
というsha256
の値を期待したのに、 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
という値を受け取ったというエラーです。 つまり、期待されているハッシュ値をgot
のところで教えてくれています。 これを先ほどのlib.fakeSha256
のところに設定し直します:
plugins =
let
autojump = {
name = "autojump";
src = pkgs.fetchFromGitHub {
owner = "wting";
repo = "autojump";
rev = "06e082c91805cb022900819b2e0881eeae780d58";
sha256 = "mrPMgwVkqOlKjvy1106MUKF7OlEtKdt8E9mqCg7U9+U="; # <-ここを変更した
};
};
in [
autojump];
これでhome-manager switch
を実行すると、Home Managerを切り替えることに成功します。
実際、zsh
のプラグインは~/.config/zsh/plugins
に置かれ、 autojump
がちゃんと存在しています:
$ ls ~/.config/zsh/plugins
autojump
しかし、この段階ではautojump
は使えません。 autojump
はj
というコマンドで実行されるのですが、見つかりません:
$ which j
j not found
これは、プラグインをGitHubから持ってきただけで、 プラグインとして使う宣言をしていないためです。
そこで、zsh
内のoh-my-zsh
、plugins
の中にautojump
を使用することを宣言します:
oh-my-zsh = {
enable = true;
plugins = [
"autojump" # <- この行を追加した
"extract"
"fzf"
"git"
"web-search"
];
};
また、autojump
をインストールする必要があります。 autojumpのGitHubリポジトリで、 導入方法を確認してみると、 「autojump
リポジトリ内のinstall.py
を実行してインストールする」と書かれています。 つまり、autojump
を導入するには、Pythonが必要になります。
ここで、蛇足ではあるものの、ある程度重要な話をします。 インストール時のみにPythonが必要である場合、 nix-shell -p python
を実行すれば一時的にPythonがある環境に入れるので、 グローバル環境にPythonを入れることなく、インストールを済ませることができます。 筆者はこの方法でインストールし、使用することを試みましたが、 autojump
については、動作するのにもPythonが必要であるため、 グローバルにPythonを入れる必要があるみたいです。 今回は結局グローバル環境に必要になってしまいましたが、一時的に使う方法も覚えておくと便利です。
ということで、グローバルにPythonがある環境が必要となりました。 これは簡単です。home
のpackages
内にpython
を追加するだけです。
home = {
homeDirectory = builtins.getEnv "HOME";
language.base = "en_US.UTF-8";
packages = with pkgs; [
cachix
niv# <- この行を追加
python yarn
];
sessionPath = [
"$HOME/.local/bin"
];
sessionVariables = {
EDITOR = "nvim";
};
stateVersion = "21.11";
username = builtins.getEnv "USER";
};
これでhome-manager switch
を実行して、autojump
、 およびpython
を追加した新しい環境に切り替えます。
説明通り、Pythonを使ってautojump
をインストールします。
$ ~/.config/zsh/plugins/autojump/install.py
これでautojump
が使えるようになりました。
どのように使うのか、デモを載せておきます:
autojumpのデモ
$ cd ~
$ mkdir tmp # デモ用の一時的なディレクトリ
$ mkdir tmp/hoge # デモ用の一時的なディレクトリ
$ mkdir tmp/hoge/fuga # デモ用の一時的なディレクトリ
$ cd hoge # hogeに訪問して足跡をつけておく
$ cd fuga # fugaに訪問して足跡をつけておく
$ cd ~ # 一度ホームディレクトリに戻る
$ j h # hogeって名前を忘れてしまったけど、hを含むことは覚えている
/home/username/tmp/hoge # hogeに移動している
$ pwd # 本当に移動できているか確認
/home/username/tmp/hoge # 移動している
$ j f # fugaって名前を忘れてしまったけど、fを含むことは覚えている
/home/username/tmp/hoge/fuga # fugaに移動した
$ pwd # 本当に移動できているか確認
/home/username/tmp/hoge/fuga # 移動している
$ cd ~ # お掃除するためにホームディレクトリへ
$ rm -r tmp # お掃除
3 lsコマンドをかっこよくする
本節では、ls
コマンドで表示されるディレクトリやファイルに、 色を割り当てる方法を記述します。
とはいっても、仕組みが若干複雑なので、動けばヨシ!ということで、 詳しい話は省略します。 GitHub上のtrapd/LS_COLORS を使用させていただきます。
何をしているのか詳しく知りたい方は、以下の2本の動画をご視聴ください:
home.nix
のhome.packages
の箇所を次のように書き換えます:
packages = with pkgs;
let
LS_COLORS = pkgs.fetchFromGitHub {
owner = "trapd00r";
repo = "LS_COLORS";
rev = "2402dfac278ec88909e8a4883b680fb1591fcd3f";
sha256 = lib.fakeSha256;
};
ls-colors = pkgs.runCommand "ls-colors" { } ''
mkdir -p $out/bin $out/share
ln -s ${pkgs.coreutils}/bin/ls $out/bin/ls
ln -s ${pkgs.coreutils}/bin/dircolors $out/bin/dircolors
cp ${LS_COLORS}/LS_COLORS $out/share/LS_COLORS
'';
in [
cachix<- ここも追加しています
ls-colors # niv
python
yarn
];
また、zsh
のenvExtra
内に
eval $(dircolors ~/.nix-profile/share/LS_COLORS)
を追記し、shellAliases
にls = "ls --color=auto -F"
というエイリアスを追加すれば、完了です。
home-manager switch
を実行すると、またsha256
のハッシュ値でエラーが出るので、 上の説明と同様、got
に書かれたsha256
を設定してください。
ls
コマンドで表示される内容がカラフルになりました!
4 まとめ
外部パッケージの導入方法を紹介し、それを利用して autojump
プラグインを有効にし、 ls
コマンドで表示される色をカラフルにしました。
最後に、最終的なhome.nix
を載せて終わります:
ここまでのhome.nix
※sha256
のハッシュ値は異なるかもしれません
{ config, lib, pkgs, ... }:
{
home = {
homeDirectory = builtins.getEnv "HOME";
language.base = "en_US.UTF-8";
packages = with pkgs;
let
LS_COLORS = pkgs.fetchFromGitHub {
owner = "trapd00r";
repo = "LS_COLORS";
rev = "2402dfac278ec88909e8a4883b680fb1591fcd3f";
sha256 = "Ny5jeh2lZMSADfG8KuoiD3X2P8Uwk/XjsCtXoOXuHWU=";
};
ls-colors = pkgs.runCommand "ls-colors" { } ''
mkdir -p $out/bin $out/share
ln -s ${pkgs.coreutils}/bin/ls $out/bin/ls
ln -s ${pkgs.coreutils}/bin/dircolors $out/bin/dircolors
cp ${LS_COLORS}/LS_COLORS $out/share/LS_COLORS
'';
in [
cachix
ls-colors
nivpython
yarn
];
sessionPath = [
"$HOME/.local/bin"
];
sessionVariables = {
EDITOR = "nvim";
};
stateVersion = "21.11";
username = builtins.getEnv "USER";
};
programs = {
direnv = {
enable = true;
nix-direnv.enable = true;
};
gh = {
enable = true;
};
git = {
enable = true;
userEmail = "potassium.iodide28@gmail.com";
userName = "PotassiumIodide";
};
home-manager = {
enable = true;
};
zsh = {
autocd = true;
defaultKeymap = "emacs";
dotDir = ".config/zsh";
enable = true;
enableAutosuggestions = true;
enableCompletion = true;
enableSyntaxHighlighting = true;
envExtra = ''
if [ -e ~/.nix-profile/etc/profile.d/nix.sh ]; then
. ~/.nix-profile/etc/profile.d/nix.sh
fi
eval $(dircolors ~/.nix-profile/share/LS_COLORS)
'';
initExtra =''
setopt no_beep
setopt auto_pushd
setopt pushd_ignore_dups
setopt inc_append_history
'';
history = {
extended = true;
ignoreDups = true;
save = 1000000;
share = true;
size = 1000000;
};
oh-my-zsh = {
enable = true;
plugins = [
"autojump"
"extract"
"fzf"
"git"
"web-search"
];
};
plugins =
let
autojump = {
name = "autojump";
src = pkgs.fetchFromGitHub {
owner = "wting";
repo = "autojump";
rev = "06e082c91805cb022900819b2e0881eeae780d58";
sha256 = "mrPMgwVkqOlKjvy1106MUKF7OlEtKdt8E9mqCg7U9+U=";
};
};
zsh-autosuggestions = {
name = "zsh-autosuggestions";
src = pkgs.fetchFromGitHub {
owner = "zsh-users";
repo = "zsh-autosuggestions";
rev = "a411ef3e0992d4839f0732ebeb9823024afaaaa8";
sha256 = "KLUYpUu4DHRumQZ3w59m9aTW6TBKMCXl2UcKi4uMd7w=";
};
};
in [
autojump
# zsh-autosuggestions];
shellAliases =
{
h = "history";
hs = "history | grep";
hsi = "history | grep -i";
l = "ls -CF";
la = "ls -A";
ll = "ls -alF";
ls = "ls --color=auto -F";
vi = "nvim";
view = "nvim -R";
vim = "nvim";
};
zplug = {
enable = true;
plugins = [
{ name = "romkatv/powerlevel10k"; tags = [ as:theme depth:1 ]; }
];
};
};
};
}