nix-config/modules/shell/default.nix
2026-03-05 22:31:18 +01:00

267 lines
10 KiB
Nix

{
inputs,
...
}:
{
flake.modules.nixos.shell =
{ pkgs, ... }:
{
programs.fish.enable = true;
users.defaultUserShell = pkgs.fish;
home-manager.sharedModules = [
inputs.self.modules.homeManager.shell
];
};
flake.modules.darwin.shell =
{ pkgs, ... }:
{
programs.fish.enable = true;
environment.shells = [ pkgs.fish ];
home-manager.sharedModules = [
inputs.self.modules.homeManager.shell
];
};
flake.modules.homeManager.shell =
{ pkgs, ... }:
{
programs.fish = {
enable = true;
functions = {
fish_greeting = "fortune -a";
localip = "ifconfig | grep \"inet \" | grep -v 127.0.0.1 | awk '{print $2}' | head -n 1";
publicip = "curl -4 ifconfig.me";
enter_vps = "ssh dnsc-vps-sm -t tmux new -As main";
rebuild_vps = "ssh -t dnsc-vps-sm 'cd ~/nix-config && git pull && sudo just deploy'";
enter_server = "ssh dnsc-server -t tmux new -As main";
rebuild_server = "ssh -t dnsc-server 'cd ~/nix-config && git pull && sudo just deploy'";
kill_tunnels = /* fish */ ''
ps -o pid,command | grep "^[0-9]\{4,5\} ssh -fNL" | awk '{print $1}' | xargs kill -9
'';
dbui = ''
uvx --with PyMySQL --with sqlit-tui[ssh] --from sqlit-tui@1.2.11 sqlit
'';
dev_projects = /* fish */ ''
if test "$hn" = "dnsc-work"
begin
fd . ~/dev/ride/apps/backend/edge-services -t d -d 1;
fd . ~/dev/ride/apps/backend/backend-services -t d -d 1;
fd . ~/dev/ride/apps/frontend/projects -t d -d 1;
fd . ~/dev/ride/apps/native -t d -d 1;
fd . ~/dev/ride/packages -t d -d 1;
fd . ~/dev -t d -d 1;
echo "$HOME/dev/ride/apps/frontend";
echo "$HOME/dev/ride/apps/lib";
echo "$HOME/dev/ride/apps/packages";
end
else
begin
echo "$HOME/notes"
fd . ~/dev -t d -d 1
end
end
'';
cdd = /* fish */ ''
set folder (dev_projects | fzf)
cd $folder
'';
cdr = /* fish */ ''
set folder (dev_projects | fzf)
cd $folder
if test -n "$folder"
set service (basename $folder)
cd $folder
if test -f "package.json"
set script_cmd (jq -r '.scripts | to_entries | .[] | "\(.key): \(.value)"' package.json | fzf)
if test -n "$script_cmd"
set script_name (string split ": " $script_cmd)[1]
if test -n "$script_name"
echo "Running: npm run $script_name"
npm run $script_name
end
end
end
end
'';
sessionizer = /* fish */ ''
set -l selected (tmuxinator ls -n | tail -n +2 | fzf --prompt " switch to >> ")
if test -z "$selected"
return 1
end
tmuxinator start "$selected"
'';
tmux_sessionizer = /* fish */ ''
tmux display-popup -h 50% -w 80% -E sessionizer
'';
nn = /* fish */ ''
# Require a title argument
if test (count $argv) -lt 1
echo "Usage: nn \"My Note\""
return 1
end
# Join all arguments into single title (preserves spaces inside quotes)
set -l title $argv[1]
# Timestamp up to minutes, format: YYYY-MM-DD_HH-MM
set -l ts (date "+%Y%m%d%H%M")
# Normalize title: lowercase, replace spaces with hyphens, remove/replace
# characters unsafe for filenames (keep a-z0-9- and replace others with -)
set -l slug (string lower -- $title)
# Replace any sequence of non-alphanumeric characters with single hyphen
set -l slug (echo $slug | sed -E 's/[^a-z0-9]+/-/g' | sed -E 's/^-|-$//g')
# Compose filename
set -l filename "$ts"_"$slug.md"
# Directory for notes (change if you prefer another path)
set -l notes_dir ~/dev/notes
# Ensure directory exists
test -d $notes_dir; or mkdir -p $notes_dir
# Full path
set -l fullpath "$notes_dir/$filename"
# If file doesn't exist, create with timestamp and title at top
if not test -f $fullpath
# Human-friendly timestamp line (no seconds)
set -l display_ts (date "+%Y-%m-%d %H:%M")
printf "---\nCREATED_AT: %s\n---\n\n# %s\n\n" "$display_ts" "$title" > $fullpath
end
# Open file in neovim
nvim $fullpath
'';
fish_mode_prompt = /* fish */ ''
switch $fish_bind_mode
case default
set_color --bold brcyan
echo '[N] '
case insert
set_color --bold brgreen
echo '[I] '
case replace_one
set_color --bold yellow
echo '[R] '
case replace
set_color --bold bryellow
echo '[R] '
case visual
set_color --bold brmagenta
echo '[V] '
case '*'
set_color --bold red
echo '[?] '
end
set_color normal
'';
setup_winterly_theme_colors = /* fish */ ''
set --universal fish_color_autosuggestion brblack # autosuggestions
set --universal fish_color_command brwhite # commands
set --universal fish_color_comment brblack # code comments
set --universal fish_color_cwd brblack # current working directory in the default prompt
set --universal fish_color_end brblack # process separators like ';' and '&'
set --universal fish_color_error brwhite # highlight potential errors
set --universal fish_color_escape brblack # highlight character escapes like '\n' and '\x70'
set --universal fish_color_match yellow # highlight matching parenthesis
set --universal fish_color_normal brwhite # default color
set --universal fish_color_operator brblack # parameter expansion operators like '*' and '~'
set --universal fish_color_param bryellow # regular command parameters
set --universal fish_color_quote brmagenta # quoted blocks of text
set --universal fish_color_redirection brwhite # IO redirections
set --universal fish_color_search --bold --background=black --foreground=bryellow
set --universal fish_color_search_match --background black # highlight history search matches and the selected pager item (must be a background)
set --universal fish_pager_color_selected_background --background black --foreground brmagenta
set --universal fish_pager_color_progress --foreground=brwhite --background=black
set --universal fish_color_selection --background magenta # when selecting text (in vi visual mode)
set --universal fish_color_cancel brblack # the '^C' indicator on a canceled command
set --universal fish_color_host brwhite # current host system in some of fish default prompts
set --universal fish_color_host_remote yellow #ayu:syntax.constant current host system in some of fish default prompts, if fish is running remotely (via ssh or similar)
set --universal fish_color_user brwhite # current username in some of fish default prompts
'';
setup_homebrew = /* fish */ ''
fish_add_path /opt/homebrew/bin
if test -d (brew --prefix)"/share/fish/completions"
set -p fish_complete_path (brew --prefix)/share/fish/completions
end
if test -d (brew --prefix)"/share/fish/vendor_completions.d"
set -p fish_complete_path (brew --prefix)/share/fish/vendor_completions.d
end
'';
setup_path = /* fish */ ''
fish_add_path /run/wrappers/bin
fish_add_path /run/current-system/sw/bin
fish_add_path $HOME/.nix-profile/bin
if test "$(uname)" = "Darwin"
fish_add_path /nix/var/nix/profiles/default/bin
setup_homebrew
end
'';
setup_env = /* fish */ ''
for line in (cat $HOME/.env | grep -v '^#')
set item (string split -m 1 '=' $line)
set -gx $item[1] $item[2]
end
'';
setup_work = /* fish */ ''
fish_add_path $ANDROID_HOME/emulator
fish_add_path $ANDROID_HOME/platform-tools
fish_add_path $HOME/.local/share/uv/tools
rbenv init - | source
fnm env --use-on-cd --shell fish | source
'';
};
interactiveShellInit = /* fish */ ''
# Set some global values
set -x GPG_TTY (tty)
set hn (prompt_hostname)
fish_vi_key_bindings insert
fish_vi_cursor xterm
setup_winterly_theme_colors
setup_env
setup_path
if test "$hn" = "dnsc-work"
setup_work
end
# Custom init
direnv hook fish | source
# Auto start tmux
if status is-interactive; and not set -q TMUX
if tmux list-sessions >/dev/null 2>&1
# Attach to the first available session
tmux a
else
# Create a new session
tmux new-session -t main
end
end
'';
shellAbbrs = {
lg = "lazygit";
gg = "lazygit";
g = "git";
frc = "source ~/.config/fish/**/*.fish";
};
};
};
}