feat(shell): zsh tooling, tmux plugins, nix-index, nh
zsh: history tuning (100k, dedup, share, timestamps); oh-my-zsh sudo / colored-man-pages / extract; fzf, zoxide, direnv (+nix-direnv), eza, bat; ls-family aliases. command-not-found via the prebuilt nix-index DB (+comma). nh with $NH_FLAKE and a weekly user-GC timer. tmux: escape-time 10 (was the 500ms default -> laggy vim ESC), focus-events, base-index 1; plugins sensible / vim-tmux-navigator / yank / catppuccin (mocha statusline) / resurrect / continuum (restore on); renumber-windows and set-clipboard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+117
-5
@@ -1,6 +1,17 @@
|
||||
# Interactive shell: zsh + tmux. Wanted on every host.
|
||||
{ lib, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
# Prebuilt nix-index database -> working command-not-found
|
||||
# ("cmd not found -> which nix package provides it"), no manual indexing.
|
||||
inputs.nix-index-database.homeModules.default
|
||||
];
|
||||
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
enableCompletion = true;
|
||||
@@ -21,12 +32,24 @@
|
||||
"^[OB"
|
||||
];
|
||||
};
|
||||
history.append = true;
|
||||
history = {
|
||||
append = true; # append, don't overwrite, on shell exit
|
||||
size = 100000; # in-memory (HISTSIZE)
|
||||
save = 100000; # on-disk (SAVEHIST)
|
||||
ignoreDups = true; # drop consecutive duplicates
|
||||
ignoreSpace = true; # leading-space commands stay out of history
|
||||
expireDuplicatesFirst = true;
|
||||
share = true; # live-share history across sessions
|
||||
extended = true; # record timestamps
|
||||
};
|
||||
oh-my-zsh = {
|
||||
enable = true;
|
||||
plugins = [
|
||||
"git"
|
||||
"man"
|
||||
"sudo" # double-Esc prefixes the last command with sudo
|
||||
"colored-man-pages"
|
||||
"extract" # `extract <archive>` for any format
|
||||
];
|
||||
theme = "robbyrussell";
|
||||
};
|
||||
@@ -37,9 +60,59 @@
|
||||
export PS1="%M $PS1"
|
||||
fi
|
||||
'';
|
||||
envExtra = ''
|
||||
alias cls=clear
|
||||
'';
|
||||
shellAliases = {
|
||||
# eza's zsh integration also defines these; set explicitly so the
|
||||
# icons/git intent is obvious.
|
||||
ls = "eza --icons --git";
|
||||
ll = "eza --icons --git -l";
|
||||
la = "eza --icons --git -la";
|
||||
lt = "eza --icons --git --tree";
|
||||
cls = "clear";
|
||||
};
|
||||
};
|
||||
|
||||
# Fuzzy finder: Ctrl-R fuzzy history, Ctrl-T files, Alt-C cd.
|
||||
programs.fzf = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
|
||||
# Frecency directory jumping: `z <fragment>`.
|
||||
programs.zoxide = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
|
||||
# Per-project environments auto-loaded on cd, with the Nix dev-shell cache.
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
nix-direnv.enable = true;
|
||||
};
|
||||
|
||||
# Modern ls (drives the ls aliases above).
|
||||
programs.eza = {
|
||||
enable = true;
|
||||
git = true;
|
||||
icons = "auto"; # boolean form is deprecated
|
||||
};
|
||||
|
||||
# Syntax-highlighting pager, used as `bat` (acts like cat when piped).
|
||||
programs.bat.enable = true;
|
||||
|
||||
# command-not-found backed by the prebuilt nix-index DB (module imported
|
||||
# above). `comma` runs an uninstalled program once: `, cowsay hi`.
|
||||
programs.nix-index.enable = true;
|
||||
programs.nix-index-database.comma.enable = true;
|
||||
|
||||
# Nicer nixos-rebuild/home-manager (diffs) + a weekly user-GC timer.
|
||||
programs.nh = {
|
||||
enable = true;
|
||||
flake = "$HOME/code/nixfiles";
|
||||
clean = {
|
||||
enable = true;
|
||||
dates = "weekly";
|
||||
extraArgs = "--keep 5 --keep-since 3d";
|
||||
};
|
||||
};
|
||||
|
||||
programs.tmux = {
|
||||
@@ -50,6 +123,33 @@
|
||||
keyMode = "vi";
|
||||
historyLimit = 500000;
|
||||
mouse = true;
|
||||
escapeTime = 10; # was the 500ms default -> laggy ESC in vim
|
||||
focusEvents = true; # let vim see focus changes (autoread)
|
||||
baseIndex = 1; # sets both base-index and pane-base-index
|
||||
|
||||
plugins = with pkgs.tmuxPlugins; [
|
||||
sensible
|
||||
vim-tmux-navigator # Ctrl-h/j/k/l across vim splits and tmux panes
|
||||
yank
|
||||
{
|
||||
# Catppuccin Mocha statusline (v2 API: flavour + window options must be
|
||||
# set before the plugin loads, which home-manager does for plugin
|
||||
# extraConfig; the status modules below go in the main extraConfig,
|
||||
# which HM appends after all plugins).
|
||||
plugin = catppuccin;
|
||||
extraConfig = ''
|
||||
set -g @catppuccin_flavor 'mocha'
|
||||
set -g @catppuccin_window_status_style 'rounded'
|
||||
'';
|
||||
}
|
||||
resurrect # save/restore sessions
|
||||
{
|
||||
plugin = continuum; # auto-save + restore on tmux start (after resurrect)
|
||||
extraConfig = ''
|
||||
set -g @continuum-restore 'on'
|
||||
'';
|
||||
}
|
||||
];
|
||||
# `reverseSplit = true` already binds s -> vertical and v -> horizontal
|
||||
# split (the dotfiles' vim-style splits).
|
||||
extraConfig = ''
|
||||
@@ -75,6 +175,18 @@
|
||||
set -as terminal-features ",foot*:title"
|
||||
set -as terminal-features ",foot*:ccolour"
|
||||
set -as terminal-features ",foot*:cstyle"
|
||||
|
||||
# No home-manager options for these.
|
||||
set -g renumber-windows on
|
||||
set -g set-clipboard on
|
||||
|
||||
# Catppuccin v2 statusline. Must run after the plugin has loaded;
|
||||
# home-manager appends this extraConfig after the whole plugin list.
|
||||
set -g status-left-length 100
|
||||
set -g status-right-length 100
|
||||
set -g status-left ""
|
||||
set -g status-right "#{E:@catppuccin_status_application}"
|
||||
set -ag status-right "#{E:@catppuccin_status_session}"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user