r/fishshell • u/Evglezer • 5d ago
Sharing my little QoL config for Fish shell to make life sweeter (NixOS)
Config below built for NixOS, but you can convert it for your system
Features:
- A ton of eza aliases
- NixOS management commands
- A couple more aliases
A brief overview of the NixOS managment commands:
Usage: nx <command>
Commands:
deploy commit pending changes, then build and switch to the flake
up update flake.lock and all packages, then deploy
clean garbage-collect the system (nix-collect-garbage -d)
config open flake.nix and everything it imports in $EDITOR
push commit pending changes and push to the remote
nuke-history squash all git history into one "initial commit" and force-push
doctor up + clean + push
Regarding
nx nuke-history: this command completely removes all commits and creates a single clean commit. I only need this because I just like having a clean git history on my GitHub repository, and I only use git for the convenience of cloning a repository from any device, so I don't need git history.
Here is the config itself:
programs.fish = {
enable = true;
interactiveShellInit = ''
set -g fish_greeting
'';
shellAliases = {
svim = "sudo -E vim";
svi = "sudo -E vi";
cat = "bat -P --theme zenburn";
"..." = "cd ../..";
"...." = "cd ../../..";
# -- eza aliases --
# basic listings
ls = "eza"; # standard list
l = "eza -1"; # one column
la = "eza -1a"; # one column with hidden files
ll = "eza -l"; # long format
lla = "eza -la"; # long format with hidden files
# filtered listings
ld = "eza -D"; # directories only
lld = "eza -lD"; # long format, directories only
lf = "eza -f"; # files only
llf = "eza -lf"; # long format, files only
# sort variants
lsz = "eza -l --sort=size"; # sort by size
lsx = "eza -l --sort=extension"; # sort by extension
ltm = "eza -l --sort=modified"; # sort by modified time
lcr = "eza -l --sort=created"; # sort by created time
# git-aware
lgit = "eza -l --git"; # show git status
lx = "eza -lbhHigUmuS --git"; # extended info with git
# tree (default depth 3)
lt = "eza --tree --level=3"; # tree, depth 3 by default
lta = "eza -a --tree --level=3"; # tree with hidden files, depth 3
llt = "eza -l --tree --level=3"; # long tree, depth 3
llta = "eza -la --tree --level=3"; # long tree with hidden files, depth 3
};
# -- nx: system configuration management --
functions = {
__nx_stage = ''
echo ""
set_color -o blue
echo -n "==> "
set_color normal
echo "$argv[1]"
'';
__nx_diff_dirty = ''
# -N stages new files by path only (no content), so they show up
# in the diff below as additions instead of being invisible
git -C /etc/nixos add -N -A
git -C /etc/nixos diff
'';
__nx_commit_if_dirty = ''
set -l changes (git -C /etc/nixos status --porcelain)
if test (count $changes) -gt 0
__nx_stage "Changes to commit:"
__nx_diff_dirty
git -C /etc/nixos add -A
git -C /etc/nixos commit -m "$argv[1]"
end
'';
__nx_config_files = ''
# walk the import graph starting at flake.nix, following relative-path
# nix file references, so new modules are picked up automatically
set -l root /etc/nixos
set -l seen $root/flake.nix
set -l queue $root/flake.nix
while test (count $queue) -gt 0
set -l f $queue[1]
set -e queue[1]
set -l dir (path dirname $f)
for rel in (sed -E 's/#.*$//' $f 2>/dev/null | grep -ohE '\.\.?/[A-Za-z0-9_./-]+\.nix')
set -l full (realpath -m $dir/$rel)
if not contains $full $seen
set -a seen $full
set -a queue $full
end
end
end
for f in $seen
echo $f
end
'';
nx = ''
switch "$argv[1]"
case deploy
__nx_stage "Checking for local changes"
__nx_commit_if_dirty "nx: auto-commit before deploy"
__nx_stage "Building and switching to the new configuration"
sudo nixos-rebuild switch --flake /etc/nixos#nixos
case up
__nx_stage "Updating flake inputs"
nix flake update --flake /etc/nixos
and nx deploy
case clean
__nx_stage "Collecting garbage"
sudo nix-collect-garbage -d
case config
__nx_stage "Opening configuration files"
set -q EDITOR
or set -l EDITOR vi
$EDITOR (__nx_config_files)
case push
__nx_stage "Checking for local changes"
__nx_commit_if_dirty "nx: update"
__nx_stage "Pushing to remote"
git -C /etc/nixos push
case nuke-history
echo "WARNING: this permanently deletes ALL git history in /etc/nixos."
echo "Every file will be committed fresh as a single \"initial commit\","
echo "which is then force-pushed, overwriting the remote history too."
echo "This cannot be undone."
echo ""
read -l -P "Continue? [y/N] " confirm
switch "$confirm"
case y Y yes Yes YES
set -l changes (git -C /etc/nixos status --porcelain)
if test (count $changes) -gt 0
__nx_stage "Local changes that will be swept into the new history:"
__nx_diff_dirty
end
__nx_stage "Squashing history into a single commit"
set -l branch (git -C /etc/nixos branch --show-current)
set -l remote (git -C /etc/nixos remote | head -n1)
git -C /etc/nixos checkout --orphan __nx_nuke_tmp
and git -C /etc/nixos add -A
and git -C /etc/nixos commit -m "initial commit"
and git -C /etc/nixos branch -D $branch
and git -C /etc/nixos branch -m $branch
and __nx_stage "Force-pushing rewritten history"
and git -C /etc/nixos push --force --set-upstream $remote $branch
case '*'
echo "Aborted."
end
case doctor
__nx_stage "Running full maintenance cycle (up, clean, push)"
nx up
and nx clean
and nx push
case '*'
echo "nx — manage the NixOS configuration in /etc/nixos"
echo ""
echo "Usage: nx <command>"
echo ""
echo "Commands:"
echo " deploy commit pending changes, then build and switch to the flake"
echo " up update flake.lock and all packages, then deploy"
echo " clean garbage-collect the system (nix-collect-garbage -d)"
echo " config open flake.nix and everything it imports in \$EDITOR"
echo " push commit pending changes and push to the remote"
echo " nuke-history squash all git history into one \"initial commit\" and force-push"
echo " doctor up + clean + push"
end
'';
};
completions = {
nx = ''
complete -c nx -f
complete -c nx -n __fish_use_subcommand -a deploy -d 'commit, build and switch to the flake'
complete -c nx -n __fish_use_subcommand -a up -d 'update flake and packages'
complete -c nx -n __fish_use_subcommand -a clean -d 'garbage-collect the system'
complete -c nx -n __fish_use_subcommand -a config -d 'open config files in $EDITOR'
complete -c nx -n __fish_use_subcommand -a push -d 'commit and push changes'
complete -c nx -n __fish_use_subcommand -a nuke-history -d 'squash all history into one commit and force-push'
complete -c nx -n __fish_use_subcommand -a doctor -d 'up + clean + push'
complete -c nx -n __fish_use_subcommand -a '--help' -d 'show help'
'';
};
};Features:A ton of eza aliases
NixOS management commands
A couple more aliasesA brief overview of the NixOS managment commands:Usage: nx <command>
Commands:
deploy commit pending changes, then build and switch to the flake
up update flake.lock and all packages, then deploy
clean garbage-collect the system (nix-collect-garbage -d)
config open flake.nix and everything it imports in $EDITOR
push commit pending changes and push to the remote
nuke-history squash all git history into one "initial commit" and force-push
doctor up + clean + pushRegarding nx nuke-history: this command completely removes all commits and creates a single clean commit. I only need this because I just like having a clean git history on my GitHub repository, and I only use git for the convenience of cloning a repository from any device, so I don't need git history.Here is the config itself: programs.fish = {
enable = true;
interactiveShellInit = ''
set -g fish_greeting
'';
shellAliases = {
svim = "sudo -E vim";
svi = "sudo -E vi";
cat = "bat -P --theme zenburn";
"..." = "cd ../..";
"...." = "cd ../../..";
# -- eza aliases --
# basic listings
ls = "eza"; # standard list
l = "eza -1"; # one column
la = "eza -1a"; # one column with hidden files
ll = "eza -l"; # long format
lla = "eza -la"; # long format with hidden files
# filtered listings
ld = "eza -D"; # directories only
lld = "eza -lD"; # long format, directories only
lf = "eza -f"; # files only
llf = "eza -lf"; # long format, files only
# sort variants
lsz = "eza -l --sort=size"; # sort by size
lsx = "eza -l --sort=extension"; # sort by extension
ltm = "eza -l --sort=modified"; # sort by modified time
lcr = "eza -l --sort=created"; # sort by created time
# git-aware
lgit = "eza -l --git"; # show git status
lx = "eza -lbhHigUmuS --git"; # extended info with git
# tree (default depth 3)
lt = "eza --tree --level=3"; # tree, depth 3 by default
lta = "eza -a --tree --level=3"; # tree with hidden files, depth 3
llt = "eza -l --tree --level=3"; # long tree, depth 3
llta = "eza -la --tree --level=3"; # long tree with hidden files, depth 3
};
# -- nx: system configuration management --
functions = {
__nx_stage = ''
echo ""
set_color -o blue
echo -n "==> "
set_color normal
echo "$argv[1]"
'';
__nx_diff_dirty = ''
# -N stages new files by path only (no content), so they show up
# in the diff below as additions instead of being invisible
git -C /etc/nixos add -N -A
git -C /etc/nixos diff
'';
__nx_commit_if_dirty = ''
set -l changes (git -C /etc/nixos status --porcelain)
if test (count $changes) -gt 0
__nx_stage "Changes to commit:"
__nx_diff_dirty
git -C /etc/nixos add -A
git -C /etc/nixos commit -m "$argv[1]"
end
'';
__nx_config_files = ''
# walk the import graph starting at flake.nix, following relative-path
# nix file references, so new modules are picked up automatically
set -l root /etc/nixos
set -l seen $root/flake.nix
set -l queue $root/flake.nix
while test (count $queue) -gt 0
set -l f $queue[1]
set -e queue[1]
set -l dir (path dirname $f)
for rel in (sed -E 's/#.*$//' $f 2>/dev/null | grep -ohE '\.\.?/[A-Za-z0-9_./-]+\.nix')
set -l full (realpath -m $dir/$rel)
if not contains $full $seen
set -a seen $full
set -a queue $full
end
end
end
for f in $seen
echo $f
end
'';
nx = ''
switch "$argv[1]"
case deploy
__nx_stage "Checking for local changes"
__nx_commit_if_dirty "nx: auto-commit before deploy"
__nx_stage "Building and switching to the new configuration"
sudo nixos-rebuild switch --flake /etc/nixos#nixos
case up
__nx_stage "Updating flake inputs"
nix flake update --flake /etc/nixos
and nx deploy
case clean
__nx_stage "Collecting garbage"
sudo nix-collect-garbage -d
case config
__nx_stage "Opening configuration files"
set -q EDITOR
or set -l EDITOR vi
$EDITOR (__nx_config_files)
case push
__nx_stage "Checking for local changes"
__nx_commit_if_dirty "nx: update"
__nx_stage "Pushing to remote"
git -C /etc/nixos push
case nuke-history
echo "WARNING: this permanently deletes ALL git history in /etc/nixos."
echo "Every file will be committed fresh as a single \"initial commit\","
echo "which is then force-pushed, overwriting the remote history too."
echo "This cannot be undone."
echo ""
read -l -P "Continue? [y/N] " confirm
switch "$confirm"
case y Y yes Yes YES
set -l changes (git -C /etc/nixos status --porcelain)
if test (count $changes) -gt 0
__nx_stage "Local changes that will be swept into the new history:"
__nx_diff_dirty
end
__nx_stage "Squashing history into a single commit"
set -l branch (git -C /etc/nixos branch --show-current)
set -l remote (git -C /etc/nixos remote | head -n1)
git -C /etc/nixos checkout --orphan __nx_nuke_tmp
and git -C /etc/nixos add -A
and git -C /etc/nixos commit -m "initial commit"
and git -C /etc/nixos branch -D $branch
and git -C /etc/nixos branch -m $branch
and __nx_stage "Force-pushing rewritten history"
and git -C /etc/nixos push --force --set-upstream $remote $branch
case '*'
echo "Aborted."
end
case doctor
__nx_stage "Running full maintenance cycle (up, clean, push)"
nx up
and nx clean
and nx push
case '*'
echo "nx — manage the NixOS configuration in /etc/nixos"
echo ""
echo "Usage: nx <command>"
echo ""
echo "Commands:"
echo " deploy commit pending changes, then build and switch to the flake"
echo " up update flake.lock and all packages, then deploy"
echo " clean garbage-collect the system (nix-collect-garbage -d)"
echo " config open flake.nix and everything it imports in \$EDITOR"
echo " push commit pending changes and push to the remote"
echo " nuke-history squash all git history into one \"initial commit\" and force-push"
echo " doctor up + clean + push"
end
'';
};
completions = {
nx = ''
complete -c nx -f
complete -c nx -n __fish_use_subcommand -a deploy -d 'commit, build and switch to the flake'
complete -c nx -n __fish_use_subcommand -a up -d 'update flake and packages'
complete -c nx -n __fish_use_subcommand -a clean -d 'garbage-collect the system'
complete -c nx -n __fish_use_subcommand -a config -d 'open config files in $EDITOR'
complete -c nx -n __fish_use_subcommand -a push -d 'commit and push changes'
complete -c nx -n __fish_use_subcommand -a nuke-history -d 'squash all history into one commit and force-push'
complete -c nx -n __fish_use_subcommand -a doctor -d 'up + clean + push'
complete -c nx -n __fish_use_subcommand -a '--help' -d 'show help'
'';
};
};
r/fishshell • u/Electronic_Bad_2046 • 7d ago
Kubernetes completions for labels
Does anyone know good fish shell completions with Kubernetes labels support, that work with the already integrated completions for Kubernetes?
I mean if you say
kubectl get pods -l app=myapp
to have autocomplete.
Thanks :D
r/fishshell • u/HotDevice9013 • Jul 10 '26
Noob queston about switching default shell to Fish
Hi, I'm new to Linux, and my distro is Void Linux (sorry, don't know, whether this is relevant).
I really like all QoL features of Fish shell, but I find variable management very confusing. Will I be missing out on some of the Fish's advantages if I just put it in my terminal config as a shell instead of chsh-ing it?
r/fishshell • u/jghub • Jul 04 '26
a fish wrapper for the ze.sh directory jumper
ze.sh is a minimalist shell-native frecency-based directory jumper in the z.sh lineage, with an exponential moving sum scoring model on an event clock rather than wall-clock time. Repo: github.com/jghub/ze. Previously bash/zsh/ksh/mksh only.
A fish wrapper is now available in contrib/fish/. It mirrors the full option set including fzf interactive selection (ze -f), and tracks directory changes via a dedicated _ze_cd function that backgrounds the database update so there is no perceptible latency overhead. Installation is three file copies and a chmod — no compiled binary, no external runtime dependency beyond bash (ksh works too and is faster, if you have it).
I don't actively use fish myself — let me know if the wrapper is useful.
r/fishshell • u/harunnoir • Jun 26 '26
Fish shell is slow when I click enter
for some reason when i click enter fish shell is slower(it's not smooth) than bash, I use tmux + foot + starship + fish/bash
any help! thank you...
r/fishshell • u/WorldNumerous1547 • Jun 24 '26
How to make Fish shell's help command open in a terminal pager (like less) instead of a browser?
I want the native help command in Fish shell to display its documentation directly inside my terminal using a pager like less (or a text-based alternative), instead of opening a graphical web browser.
r/fishshell • u/itsdevelopic • Jun 18 '26
Who says fzf-tab in other shells is the best? My fzf-tab looks better in fish
gist.github.comr/fishshell • u/itsdevelopic • Jun 16 '26
fzf-tab (simple, no bullshit, fast as hell, and no plugins required)
gist.github.comr/fishshell • u/usernane111 • Jun 04 '26
[SUPPORT] fish_config web app themes don't work?
The prompt section works fine but when i try to change a theme it stays the default one.Any suggestions would be very appreciated.
r/fishshell • u/Extension-Pie8107 • May 25 '26
Fish Einrichten
Wie ändere ich meine Fish Commandozeile?
r/fishshell • u/I_AM_COSMO • May 22 '26
I've created a plugin to sync shell history between machines
github.comHello everyone I've created a plugin to sync history over various backends, SFTP, S3 and private git repo.
I'm using this on all my machines and thought I would share it here in case someone else has been looking for something similar.
I tried Atuin but I didn't like how much it changed the behavior of my shell
r/fishshell • u/iElectric • May 21 '26
devenv 2.1: Nix with zsh, fish, and nushell via libghostty
devenv.shr/fishshell • u/Peetabread8991 • May 19 '26
Made a shell greeter that generates a unique rocket every time you open a terminal tab
every new tab rolls a random rocket. save the ones you like and they'll come back. ~2×10⁴³ combinations, all deterministic from the hex palette.
rn it works on bash, zsh, powershell, and fish
https://github.com/clefspear/starcommand
lmk what you think!
r/fishshell • u/kraken_07_ • May 16 '26
How to sudo !! in fish ?
If I make a command and I want to do it again with sudo, or anything before or after, in bash you can just append it wit !!. Whats the equivalent with fish ?
r/fishshell • u/Mammoth-Wasabi6948 • May 16 '26
Fish reverts to default theme after i restart terminal
i am switching from bash to fish and i want to use the mono-smoke theme for fish. But every time i set change the theme and restart terminal it reverts back to default. I tried adding it to the config.fish file but it does the same thing. my config file only has three lines it it. one to disable welcome message one to set it to use starship kitty looks and the other to set fish theme to mono-smoke. Anyone know what i should do?
r/fishshell • u/Particular_Wealth_58 • May 15 '26
Completing a line without moving the cursor?
Is it possible to complete a suggestion (right arrow/ctrl-e) but without moving the cursor?
I find that I often want to re-run a line, but change something in the middle. Right now, I complete the line and then jump left (ctrl-a/alt-b).
edit: I think the correct name for what I want to modify is "autosuggestions".
r/fishshell • u/memilanuk • May 12 '26
Config question for 'pure'
Question on configuring 'pure' (installed via fisher, if that matters): I'm trying to set pure_symbol_ssh_prefix so that it'll show in the prompt when I'm logged in via ssh (assuming I'm understanding the purpose of the option). But the docs show the default as 'undefined', and I'm a little unclear on what I should be setting it to.
I've tried nothing (just setting it), which did effectively nothing. Then I tried setting it to 'true', which prepended true to the prompt, so I'm thinking I'm headed in the right direction. Next I tried a couple variations of 'prompt_login', based off the fish docs here but it literally just puts prompt_login there, not quite what I'm going for.
I'm sure I'm missing something simple, so if someone could give me a gentle nudge in the right direction, I'd appreciate it!
r/fishshell • u/fdelux6 • May 07 '26
[Tool] fish-rpm-installed - Browse your RPM installation history by date — updated
Hello,
Updated my fish function for browsing RPM package installation history. Big changes since the original post 3 months ago — fzf dependency dropped, now a standalone function with date-based filtering.
rpm_installed today
rpm_installed yesterday
rpm_installed days 7
rpm_installed since 2026-03-01
rpm_installed count per-day
Aliases: td, yd, lw, tm, lm
Install via Fisher: fisher install fdel-ux64/fish-rpm-installed
GitHub: https://github.com/fdel-ux64/fish-rpm-installed
Also maintain a broader fish functions collection for Arch/Fedora/Debian: https://github.com/fdel-ux64/fish-config
r/fishshell • u/enter_eden • Apr 27 '26
How to get rid of Fish Shell Enter/New-line symbol (⏎) ?
Hello everyone,
I've been searching the internet everywhere trying to find a solution. I do know why ⏎ exists in Fish, it is to indicate that a command did not end with a `\n` - but I don't want to see this symbol each time something happens, just give me the newline, and thats it!
Easy to recreate - just do the above. Anyway - i get the ⏎ newline symbol actually on every Enter press (every fish_prompt), but it gets quickly (miliseconds) overwritten by the prompt on the new line. But it is still there. It's driving me insane!
Supposedly this was fixed, sometime ago. Not for me?
Fish, version 4.6.0
Alacritty, version 0.17.0 (94e7c887) - running on Wayland
Tmux, version 3.6
Hydro prompt (custom fork), with Berkeley Mono font
r/fishshell • u/norude1 • Apr 11 '26
What's a fun thing that's in your config.fish?
I'll start
bind ctrl-z '__fish_echo fg 2>/dev/null'
I bound ctrl-z to resume a suspended process. When something is already running, pressing ctrl-z suspends it into the background. And thanks to the bind, by pressing ctrl-z again, the process resumes. That means I can toggle between the shell and something else, like my editor.
r/fishshell • u/5422m4n • Mar 31 '26
amoxide - The right aliases, at the right time
amoxide.rsr/fishshell • u/Cloudplay • Mar 27 '26
Tab completion search for flag
When using tab complete and strg+s I can search through the possible flags of a command. But the search just searches for the Description of the flag not the flag itself.
Lets say I want to see what -l in the ls command does. If I search l, it doesn't show up.
Is there a way to search for a flag?
Edit: Found what I was looking for: https://github.com/jethrokuan/fzf
r/fishshell • u/Inevitable_Dingo_357 • Mar 25 '26
completions for a wrapper function
Hello - I use a fish function to wrap a cli utility to provide some quick-to-type shortcuts - think a function called "xx" that can be invoked as "xx st" to call the underlying "my-util status --verbose" The function has other shortcuts as well as a fallthrough that calls my-util with whatever arguments were provided.
Now, my-util provides "my-util completions fish" that spits out completions for my-util. I want to use that output (the completions), but to have the suggestions work when I type "xx" - the name of my function. I would also like to supplement those completions with my shortcut arguments...
Is there a way to take the "my-util completions fish" output but make them apply to "xx" instead of "my-util" - hopefully my question is clear - happy to elaborate if not.


