Compare commits

..

2 Commits

Author SHA1 Message Date
df8e73bc23 Replace fish with nushell 2026-02-08 08:27:43 +00:00
f389753946 flake
Signed-off-by: Christoph Schmatzler <christoph@schmatzler.com>
2026-02-08 07:47:27 +00:00
18 changed files with 294 additions and 115 deletions

48
flake.lock generated
View File

@@ -254,11 +254,11 @@
]
},
"locked": {
"lastModified": 1770318660,
"narHash": "sha256-yFVde8QZK7Dc0Xa8eQDsmxLX4NJNfL1NKfctSyiQgMY=",
"lastModified": 1770491427,
"narHash": "sha256-8b+0vixdqGnIIcgsPhjdX7EGPdzcVQqYxF+ujjex654=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "471e6a065f9efed51488d7c51a9abbd387df91b8",
"rev": "cbd8a72e5fe6af19d40e2741dc440d9227836860",
"type": "github"
},
"original": {
@@ -270,11 +270,11 @@
"homebrew-cask": {
"flake": false,
"locked": {
"lastModified": 1770393771,
"narHash": "sha256-yNaIsOtVX83L83O/2BHS9WVpAqZ7IzDs2yZhEb4umyg=",
"lastModified": 1770536562,
"narHash": "sha256-N28diMb0XI0g+ZAWZzjquFP5FieQVqE3uIqbofIf6hw=",
"owner": "homebrew",
"repo": "homebrew-cask",
"rev": "c16ebafbe5cb55c51e9b0ec46ed3f11b73d93604",
"rev": "4cc466d7ede54a8984c1d4284d73d7ad9a920a19",
"type": "github"
},
"original": {
@@ -286,11 +286,11 @@
"homebrew-core": {
"flake": false,
"locked": {
"lastModified": 1770391396,
"narHash": "sha256-WH8DSpgT0P93MdblM7z9qS2U9VhG0j99VZ/wberbmT8=",
"lastModified": 1770531570,
"narHash": "sha256-iBAZFuPc/+ZX1DdSc0XluOi1UfXXPuyFYWyhhCnu8p0=",
"owner": "homebrew",
"repo": "homebrew-core",
"rev": "de9367dc2858d3add0dd79be5ca79ad62f8186e0",
"rev": "200e020e5e6ac09aacc51fc6ee8d484f15e9e6e3",
"type": "github"
},
"original": {
@@ -306,11 +306,11 @@
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1770388146,
"narHash": "sha256-tjCUAiXibkgKMJxiTXak+VwYbWyxY2at7hRCPykrTbc=",
"lastModified": 1770521775,
"narHash": "sha256-ZYdadYL/s8dtY4KcvUMspwgKPpeR2QHYwt7sbSwn5Fw=",
"owner": "numtide",
"repo": "llm-agents.nix",
"rev": "2c5791cc2667f20fe75fa6a5ea9335c23bea538d",
"rev": "ab28ccc8ae39071ec4833def4ea90ad5aadb5644",
"type": "github"
},
"original": {
@@ -382,11 +382,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1770169770,
"narHash": "sha256-awR8qIwJxJJiOmcEGgP2KUqYmHG4v/z8XpL9z8FnT1A=",
"lastModified": 1770380644,
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "aa290c9891fa4ebe88f8889e59633d20cc06a5f2",
"rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
"type": "github"
},
"original": {
@@ -413,11 +413,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1770393649,
"narHash": "sha256-agO684FuNJrJSm0EOxlCotu2AnKO0JKU8nu2Z3QfplQ=",
"lastModified": 1770536127,
"narHash": "sha256-HVGHWqNoCLAe5wDqU6hE0lxpoLP7ElMO6wN/br7qs9s=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a123db84a6aff9e37716dc856ad09cfe885a0ce4",
"rev": "efd5db69f4598def49f886033346b2dcce709dfa",
"type": "github"
},
"original": {
@@ -482,11 +482,11 @@
"nono": {
"flake": false,
"locked": {
"lastModified": 1770230267,
"narHash": "sha256-EUSXFyhPBkffuukLvr4Q3LythNds2ca5wJotW0APSY8=",
"lastModified": 1770491265,
"narHash": "sha256-5assq7vn/88kP2p/tTFP3wcWiuxD/E/aG+AExRfW1t0=",
"owner": "lukehinds",
"repo": "nono",
"rev": "42df275918579adeb3243a9f9e085f052e19199c",
"rev": "0986e4d2e9b05da9e75dc2f5a43b8756aa10a991",
"type": "github"
},
"original": {
@@ -576,11 +576,11 @@
]
},
"locked": {
"lastModified": 1770145881,
"narHash": "sha256-ktjWTq+D5MTXQcL9N6cDZXUf9kX8JBLLBLT0ZyOTSYY=",
"lastModified": 1770526836,
"narHash": "sha256-xbvX5Ik+0inJcLJtJ/AajAt7xCk6FOCrm5ogpwwvVDg=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "17eea6f3816ba6568b8c81db8a4e6ca438b30b7c",
"rev": "d6e0e666048a5395d6ea4283143b7c9ac704720d",
"type": "github"
},
"original": {

View File

@@ -25,8 +25,7 @@
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/nushell.nix
../../profiles/fzf.nix
../../profiles/ghostty.nix
../../profiles/git.nix

View File

@@ -24,8 +24,7 @@
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/nushell.nix
../../profiles/fzf.nix
../../profiles/ghostty.nix
../../profiles/git.nix

View File

@@ -39,7 +39,7 @@
home-manager.users.${user} = {
imports = [
../../profiles/fish.nix
../../profiles/nushell.nix
../../profiles/home.nix
../../profiles/ssh.nix
inputs.nixvim.homeModules.nixvim

View File

@@ -26,8 +26,7 @@
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/nushell.nix
../../profiles/fzf.nix
../../profiles/git.nix
../../profiles/home.nix

View File

@@ -1,7 +1,7 @@
{
programs.atuin = {
enable = true;
enableFishIntegration = true;
enableNushellIntegration = true;
flags = [
"--disable-up-arrow"
];

View File

@@ -1,5 +1,6 @@
{pkgs, ...}: {
programs.fish.enable = true;
environment.shells = [pkgs.nushell];
nixpkgs = {
config = {

View File

@@ -118,7 +118,7 @@
name = user;
home = "/Users/${user}";
isHidden = false;
shell = pkgs.fish;
shell = pkgs.nushell;
};
home-manager.useGlobalPkgs = true;

View File

@@ -1,6 +0,0 @@
{
programs.eza = {
enable = true;
enableFishIntegration = true;
};
}

View File

@@ -1,54 +0,0 @@
{
programs.fish = {
enable = true;
functions = {
open_project = ''
set -l base "$HOME/Projects"
set -l choice (fd -t d -d 1 -a . "$base/Personal" "$base/Work" \
| string replace -r -- "^$base/" "" \
| fzf --prompt "project > ")
test -n "$choice"; and cd "$base/$choice"
'';
};
interactiveShellInit = ''
set fish_greeting
set fish_color_normal 4c4f69
set fish_color_command 1e66f5
set fish_color_param dd7878
set fish_color_keyword d20f39
set fish_color_quote 40a02b
set fish_color_redirection ea76cb
set fish_color_end fe640b
set fish_color_comment 8c8fa1
set fish_color_error d20f39
set fish_color_gray 9ca0b0
set fish_color_selection --background=ccd0da
set fish_color_search_match --background=ccd0da
set fish_color_option 40a02b
set fish_color_operator ea76cb
set fish_color_escape e64553
set fish_color_autosuggestion 9ca0b0
set fish_color_cancel d20f39
set fish_color_cwd df8e1d
set fish_color_user 179299
set fish_color_host 1e66f5
set fish_color_host_remote 40a02b
set fish_color_status d20f39
set fish_pager_color_progress 9ca0b0
set fish_pager_color_prefix ea76cb
set fish_pager_color_completion 4c4f69
set fish_pager_color_description 9ca0b0
set -gx LS_COLORS "$(vivid generate catppuccin-latte)"
set -gx COLORTERM truecolor
set -gx COLORFGBG "15;0"
set -gx TERM_BACKGROUND light
for mode in default insert
bind --mode $mode \cp open_project
end
'';
};
}

View File

@@ -1,7 +1,6 @@
{
programs.fzf = {
enable = true;
enableFishIntegration = true;
};
home.sessionVariables = {

View File

@@ -1,6 +1,6 @@
{pkgs, ...}: {
xdg.configFile."ghostty/config".text = ''
command = ${pkgs.fish}/bin/fish
command = ${pkgs.nushell}/bin/nu
theme = Catppuccin Latte
window-padding-x = 12
window-padding-y = 3
@@ -10,7 +10,7 @@
cursor-style = block
mouse-hide-while-typing = true
mouse-scroll-multiplier = 1.25
shell-integration = fish
shell-integration = none
shell-integration-features = no-cursor
clipboard-read = allow
clipboard-write = allow

View File

@@ -95,15 +95,10 @@ in {
gf = "git fetch";
gfa = "git fetch --all --tags --prune";
gfo = "git fetch origin";
gfg = "git ls-files | grep";
gg = "git gui citool";
gga = "git gui citool --amend";
ggpull = "git pull origin \"$(git branch --show-current)\"";
ggpush = "git push origin \"$(git branch --show-current)\"";
ggsup = "git branch --set-upstream-to=origin/$(git branch --show-current)";
ghh = "git help";
gignore = "git update-index --assume-unchanged";
gignored = "git ls-files -v | grep \"^[[:lower:]]\"";
gl = "git pull";
glg = "git log --stat";
glgp = "git log --stat --patch";
@@ -118,7 +113,6 @@ in {
glols = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset\" --stat";
glod = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset\"";
glods = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset\" --date=short";
gluc = "git pull upstream $(git branch --show-current)";
glum = "git pull upstream main";
gm = "git merge";
gma = "git merge --abort";
@@ -133,7 +127,6 @@ in {
gpd = "git push --dry-run";
gpf = "git push --force-with-lease";
gpod = "git push origin --delete";
gpoat = "git push origin --all && git push origin --tags";
gpr = "git pull --rebase";
gpra = "git pull --rebase --autostash";
gprav = "git pull --rebase --autostash -v";
@@ -142,8 +135,6 @@ in {
gprv = "git pull --rebase -v";
gprum = "git pull --rebase upstream main";
gprumi = "git pull --rebase=interactive upstream main";
gpsup = "git push --set-upstream origin $(git branch --show-current)";
gpsupf = "git push --set-upstream origin $(git branch --show-current) --force-with-lease";
gpv = "git push --verbose";
gpu = "git push upstream";
gr = "git remote";
@@ -169,13 +160,11 @@ in {
grm = "git rm";
grmc = "git rm --cached";
grmv = "git remote rename";
groh = "git reset origin/$(git branch --show-current) --hard";
grrm = "git remote remove";
grs = "git restore";
grset = "git remote set-url";
grss = "git restore --source";
grst = "git restore --staged";
grt = "cd \"$(git rev-parse --show-toplevel || echo .)\"";
gru = "git reset --";
grup = "git remote update";
grv = "git remote --verbose";
@@ -201,16 +190,43 @@ in {
gswm = "git switch main";
gta = "git tag --annotate";
gts = "git tag --sign";
gtv = "git tag | sort -V";
gunignore = "git update-index --no-assume-unchanged";
gunwip = "git rev-list --max-count=1 --format=\"%s\" HEAD | grep -q \"\\--wip--\" && git reset HEAD~1";
gwch = "git whatchanged -p --abbrev-commit --pretty=medium";
gwipe = "git reset --hard && git clean --force -df";
gwt = "git worktree";
gwta = "git worktree add";
gwtls = "git worktree list";
gwtmv = "git worktree move";
gwtrm = "git worktree remove";
gwip = "git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign --message \"--wip-- [skip ci]\"";
};
# Complex git aliases that require pipes/subshells — nushell `alias` can't
# handle these, so they're defined as custom commands instead.
programs.nushell.extraConfig = ''
def ggpull [] { git pull origin (git branch --show-current | str trim) }
def ggpush [] { git push origin (git branch --show-current | str trim) }
def ggsup [] { git branch $"--set-upstream-to=origin/(git branch --show-current | str trim)" }
def gluc [] { git pull upstream (git branch --show-current | str trim) }
def gpsup [] { git push --set-upstream origin (git branch --show-current | str trim) }
def gpsupf [] { git push --set-upstream origin (git branch --show-current | str trim) --force-with-lease }
def groh [] { git reset $"origin/(git branch --show-current | str trim)" --hard }
def --env grt [] {
let toplevel = (do { git rev-parse --show-toplevel } | complete | get stdout | str trim)
if ($toplevel | is-not-empty) { cd $toplevel } else { cd . }
}
def gfg [...pattern: string] { git ls-files | lines | where {|f| $f =~ ($pattern | str join ".*") } }
def gignored [] { git ls-files -v | lines | where {|l| ($l | str substring 0..1) =~ "[a-z]" } }
def gpoat [] { git push origin --all; git push origin --tags }
def gtv [] { git tag | lines | sort }
def gwipe [] { git reset --hard; git clean --force -df }
def gunwip [] {
let msg = (git rev-list --max-count=1 --format="%s" HEAD | lines | get 1)
if ($msg | str contains "--wip--") { git reset HEAD~1 }
}
def gwip [] {
git add -A
let deleted = (git ls-files --deleted | lines)
if ($deleted | is-not-empty) { git rm ...$deleted }
git commit --no-verify --no-gpg-sign --message "--wip-- [skip ci]"
}
'';
}

View File

@@ -1,7 +1,7 @@
{
programs.mise = {
enable = true;
enableFishIntegration = true;
enableNushellIntegration = true;
globalConfig.settings = {
auto_install = false;
};

View File

@@ -66,7 +66,7 @@
"network"
"systemd-journal"
];
shell = pkgs.fish;
shell = pkgs.nushell;
openssh.authorizedKeys.keys = constants.sshKeys;
};

226
profiles/nushell.nix Normal file
View File

@@ -0,0 +1,226 @@
{pkgs, ...}: {
programs.nushell = {
enable = true;
settings = {
show_banner = false;
completions = {
algorithm = "fuzzy";
case_sensitive = false;
};
history = {
file_format = "sqlite";
};
use_ls_colors = true;
};
environmentVariables = {
COLORTERM = "truecolor";
COLORFGBG = "15;0";
TERM_BACKGROUND = "light";
};
extraEnv = ''
$env.LS_COLORS = (${pkgs.vivid}/bin/vivid generate catppuccin-latte)
'';
extraConfig = ''
# --- Catppuccin Latte Theme ---
let theme = {
rosewater: "#dc8a78"
flamingo: "#dd7878"
pink: "#ea76cb"
mauve: "#8839ef"
red: "#d20f39"
maroon: "#e64553"
peach: "#fe640b"
yellow: "#df8e1d"
green: "#40a02b"
teal: "#179299"
sky: "#04a5e5"
sapphire: "#209fb5"
blue: "#1e66f5"
lavender: "#7287fd"
text: "#4c4f69"
subtext1: "#5c5f77"
subtext0: "#6c6f85"
overlay2: "#7c7f93"
overlay1: "#8c8fa1"
overlay0: "#9ca0b0"
surface2: "#acb0be"
surface1: "#bcc0cc"
surface0: "#ccd0da"
base: "#eff1f5"
mantle: "#e6e9ef"
crust: "#dce0e8"
}
let scheme = {
recognized_command: $theme.blue
unrecognized_command: $theme.text
constant: $theme.peach
punctuation: $theme.overlay2
operator: $theme.sky
string: $theme.green
virtual_text: $theme.surface2
variable: { fg: $theme.flamingo attr: i }
filepath: $theme.yellow
}
$env.config.color_config = {
separator: { fg: $theme.surface2 attr: b }
leading_trailing_space_bg: { fg: $theme.lavender attr: u }
header: { fg: $theme.text attr: b }
row_index: $scheme.virtual_text
record: $theme.text
list: $theme.text
hints: $scheme.virtual_text
search_result: { fg: $theme.base bg: $theme.yellow }
shape_closure: $theme.teal
closure: $theme.teal
shape_flag: { fg: $theme.maroon attr: i }
shape_matching_brackets: { attr: u }
shape_garbage: $theme.red
shape_keyword: $theme.mauve
shape_match_pattern: $theme.green
shape_signature: $theme.teal
shape_table: $scheme.punctuation
cell-path: $scheme.punctuation
shape_list: $scheme.punctuation
shape_record: $scheme.punctuation
shape_vardecl: $scheme.variable
shape_variable: $scheme.variable
empty: { attr: n }
filesize: {||
if $in < 1kb {
$theme.teal
} else if $in < 10kb {
$theme.green
} else if $in < 100kb {
$theme.yellow
} else if $in < 10mb {
$theme.peach
} else if $in < 100mb {
$theme.maroon
} else if $in < 1gb {
$theme.red
} else {
$theme.mauve
}
}
duration: {||
if $in < 1day {
$theme.teal
} else if $in < 1wk {
$theme.green
} else if $in < 4wk {
$theme.yellow
} else if $in < 12wk {
$theme.peach
} else if $in < 24wk {
$theme.maroon
} else if $in < 52wk {
$theme.red
} else {
$theme.mauve
}
}
datetime: {|| (date now) - $in |
if $in < 1day {
$theme.teal
} else if $in < 1wk {
$theme.green
} else if $in < 4wk {
$theme.yellow
} else if $in < 12wk {
$theme.peach
} else if $in < 24wk {
$theme.maroon
} else if $in < 52wk {
$theme.red
} else {
$theme.mauve
}
}
shape_external: $scheme.unrecognized_command
shape_internalcall: $scheme.recognized_command
shape_external_resolved: $scheme.recognized_command
shape_block: $scheme.recognized_command
block: $scheme.recognized_command
shape_custom: $theme.pink
custom: $theme.pink
background: $theme.base
foreground: $theme.text
cursor: { bg: $theme.rosewater fg: $theme.base }
shape_range: $scheme.operator
range: $scheme.operator
shape_pipe: $scheme.operator
shape_operator: $scheme.operator
shape_redirection: $scheme.operator
glob: $scheme.filepath
shape_directory: $scheme.filepath
shape_filepath: $scheme.filepath
shape_glob_interpolation: $scheme.filepath
shape_globpattern: $scheme.filepath
shape_int: $scheme.constant
int: $scheme.constant
bool: $scheme.constant
float: $scheme.constant
nothing: $scheme.constant
binary: $scheme.constant
shape_nothing: $scheme.constant
shape_bool: $scheme.constant
shape_float: $scheme.constant
shape_binary: $scheme.constant
shape_datetime: $scheme.constant
shape_literal: $scheme.constant
string: $scheme.string
shape_string: $scheme.string
shape_string_interpolation: $theme.flamingo
shape_raw_string: $scheme.string
shape_externalarg: $scheme.string
}
$env.config.highlight_resolved_externals = true
$env.config.explore = {
status_bar_background: { fg: $theme.text, bg: $theme.mantle },
command_bar_text: { fg: $theme.text },
highlight: { fg: $theme.base, bg: $theme.yellow },
status: {
error: $theme.red,
warn: $theme.yellow,
info: $theme.blue,
},
selected_cell: { bg: $theme.blue fg: $theme.base },
}
# --- Custom Commands ---
def --env open_project [] {
let base = ($env.HOME | path join "Projects")
let choice = (
${pkgs.fd}/bin/fd -t d -d 1 -a . ($base | path join "Personal") ($base | path join "Work")
| lines
| each {|p| $p | str replace $"($base)/" "" }
| str join "\n"
| ${pkgs.fzf}/bin/fzf --prompt "project > "
)
if ($choice | str trim | is-not-empty) {
cd ($base | path join ($choice | str trim))
}
}
# --- Keybinding: Ctrl+O for open_project ---
$env.config.keybindings = ($env.config.keybindings | append [
{
name: open_project
modifier: control
keycode: char_o
mode: [emacs vi_insert vi_normal]
event: {
send: executehostcommand
cmd: "open_project"
}
}
])
'';
};
}

View File

@@ -1,7 +1,7 @@
{
programs.starship = {
enable = true;
enableFishIntegration = true;
enableNushellIntegration = true;
settings = {
add_newline = true;
command_timeout = 2000;

View File

@@ -1,6 +1,6 @@
{
programs.zoxide = {
enable = true;
enableFishIntegration = true;
enableNushellIntegration = true;
};
}