Compare commits

..

24 Commits

Author SHA1 Message Date
rootiest 0e766b3326 Merge pull request 'feat(deps): add fish-deps unified dependency management command' (#17) from feat/fish-deps into main
Reviewed-on: #17
2026-05-19 03:53:51 +00:00
rootiest a7510cc8ea fix(fish-deps): filter fish-* tags only; fix starship sh -s flag
git tag --list 'fish-*' replaces for-each-ref so old pre-Rust tags like
pre_whitespace_fix (which have no Cargo.toml) are never selected.

starship update: sh -s -- --yes correctly passes --yes to the piped
install script instead of treating it as a filename for sh to open.
2026-05-18 23:46:34 -04:00
rootiest a351e62a17 feat(fish-deps): add uv as managed dep; install before cargo and fish
uv is now listed first in the catalog (before cargo and fish) so it is
installed automatically before the fish source build is attempted.
Install uses the official curl script; update uses `uv self update`.

Catalog order is now: uv → cargo → fish → … ensuring prerequisites are
in place before any dependent install method runs.

README updated: uv and cargo added to the Required table, warning callout
and dependency management note reflect the automatic install flow.
2026-05-18 23:34:49 -04:00
rootiest 7936a0966e feat(fish-deps): build fish from source via git + cargo when upgrading
Adds a git-cargo-fish install method that clones fish-shell, checks out
the latest tag, and runs `uv run --no-managed-python cargo install --path .`.
This is offered first in `fish-deps install` (requires cargo + uv) and
used automatically by `fish-deps update`, falling back to the system PM
when cargo or uv are absent.

Removes the stale `cargo install fish` README note (that crate is a
library, not the shell binary).
2026-05-18 23:29:55 -04:00
rootiest fee2d99bea feat(fish-deps): warn on fish < 4.0 in status; prompt upgrade in install
fish-deps status now shows ⚠ with the current version when fish < 4.0.
fish-deps install prompts to upgrade fish when the installed version is
below 4.0, using the same install methods (cargo/PM) and printing a
restart reminder on success.
2026-05-18 23:17:51 -04:00
rootiest 7d4e33bc7e feat(deps): add curl installer for lazydocker and binary download for wakatime
lazydocker: prefer the official install_update_linux.sh curl script over
system PM. The same script handles updates, so fish-deps update re-runs it.

wakatime: replace pipx with a direct binary download from github releases.
Detects architecture (amd64/arm64/arm) via uname -m, downloads the zip,
extracts the binary to ~/.config/wakatime/wakatime, chmods it, and
symlinks it to ~/.local/bin/wakatime. fish-deps update re-downloads and
replaces the binary in place.

Both new specials are added to the preferred-method block so they appear
before the system PM and are the default when prompted.
2026-05-18 23:04:35 -04:00
rootiest 782ef833c2 fix(deps): correct trash cargo crate name to trashy 2026-05-18 22:48:33 -04:00
rootiest 8917442089 fix(deps): update PATH immediately after rustup install
After the rustup installer runs, add the cargo bin dir to PATH in the
current session so subsequent installs in the same fish-deps run can
find cargo without a shell restart. Checks CARGO_HOME/bin first (set
in config.fish), then falls back to the rustup default ~/.cargo/bin.
Warns the user if cargo still isn't detectable after the path update.
2026-05-18 22:40:35 -04:00
rootiest 8d9e7ae43f fix(deps): validate method choice is numeric before comparing 2026-05-18 22:29:50 -04:00
rootiest 9e7539d863 feat(deps): support upgrading fish itself via cargo install fish
Fish 4.x is a Rust rewrite published to crates.io as 'fish'. Added the
crate to the catalog so fish-deps update will run cargo install --force
fish to upgrade it. A yellow restart reminder is printed after the
upgrade since the new binary won't take effect until the shell restarts.

README warning updated to mention cargo install fish as the upgrade
path for users stuck on Fish 3.x.
2026-05-18 22:23:10 -04:00
rootiest 6fd1e3221e docs(readme): require Fish >= 4.0 and add Rust/cargo to dependencies 2026-05-18 22:20:16 -04:00
rootiest df7c921bc6 feat(deps): add cargo as a managed dependency with rustup installer
cargo is now the second entry in the catalog (after fish) so it is
installed before any Rust tool that depends on it. Install preference:
rustup installer (curl | sh) first, system PM as fallback. Update
runs rustup update when rustup is available.

The rustup-installer special is evaluated before the system PM in the
method list so it is always option 1 / the default for cargo.
2026-05-18 22:18:57 -04:00
rootiest abbbf20b40 fix(deps): restore paru install gated on pacman presence
On Arch-based systems (pacman present), paru-build offers yay or
makepkg as install methods. On non-Arch systems neither pacman nor yay
exist, so no methods are built and the dep is silently skipped — no
prompt shown to the user.
2026-05-18 22:14:45 -04:00
rootiest a70e88c344 fix(deps): remove paru install, enforce cargo preference for Rust tools
Catalog: clear paru's pm and special install entries so it appears in
status but fish-deps install skips it (it's a package manager, not a
managed dep).

Install: cargo is now always attempted first for Rust tools. When cargo
is absent but a crate exists, a note is printed suggesting rustup.
When only one method is available the chosen method is shown so the user
can see whether cargo or the system PM is being used. Method prompt now
shows the default label inline for clarity.

Removed dead paru-build switch case from the install executor.
2026-05-18 22:13:13 -04:00
rootiest a7c6b9097d fix(deps): consolidate install prompt into read -P to prevent display race 2026-05-18 22:07:50 -04:00
rootiest 0e7e824085 fix(deps): fix autoloading and Fish 4.x test compatibility
Split _fish_deps_pm.fish into one file per function so Fish can
autoload each by name (_fish_deps_detect_pm, _fish_deps_pm_install,
_fish_deps_pm_upgrade). A single file with multiple functions only
autoloads under the filename, leaving the others unreachable.

Replace all `test -a`/`test -o` binary operators with `; and`/`; or`
chains throughout _fish_deps_install and _fish_deps_update. Fish 4.x
removed support for -a/-o in test, causing the "unexpected argument"
errors seen on Debian.

Also consolidate paru/yay cases in pm_install and pm_upgrade since
both helpers use identical flags.
2026-05-18 22:05:56 -04:00
rootiest a3d99eec3f fix(aur): fall back to yay when paru is unavailable
upgrade, pkg, search, and parur now detect paru first, then yay, and
print a clear error if neither is installed. Removes the hard dependency
on paru specifically across all AUR-wrapper functions.
2026-05-18 22:01:00 -04:00
rootiest a86f797627 fix(deps): demote paru from required to recommended
paru is an AUR helper only available on Arch-based distros and is not
required for the config to function. Moved to recommended tier alongside
yay. README updated accordingly.
2026-05-18 21:59:56 -04:00
rootiest 1a6f1f3f2c feat(deps): add status symbols to fish-deps status output
Installed deps show a green ✓. Missing required/integration deps show
a red ✗. Missing recommended deps show a yellow ⚠ since they are
optional, distinguishing severity at a glance.
2026-05-18 21:56:50 -04:00
rootiest b82766ad52 feat(deps): add yay as supported AUR helper alongside paru
yay uses the same -S --noconfirm interface as paru. Detection priority
is paru > yay > pacman so paru is preferred when both are present.
When installing paru itself via paru-build special, yay -S paru is
offered as a method when yay is available, in addition to the
makepkg-from-source fallback.
2026-05-18 21:52:56 -04:00
rootiest 9b342114aa feat(deps): add fish-deps unified dependency management command
Introduces `fish-deps` with four subcommands:
- status: colored installed/missing report per tier (required/integrations/recommended)
- install: interactively install each missing dep, prompts method when multiple exist
- update: update all installed deps using their preferred method
- sync: install missing then update installed

Install method priority: cargo (Rust tools get latest crate) > system PM
(paru/pacman/apt/brew/pkg/dnf/yum) > git clone (fzf via fzf-update) >
curl installer (starship, fisher) > pipx (wakatime).

Splits into focused helper files:
- _fish_deps_catalog.fish: parallel-array dep catalog with tiers, cargo crates, PM names, special install keys
- _fish_deps_pm.fish: PM detection and install/upgrade helpers
- _fish_deps_status.fish: tier-grouped colored status display
- _fish_deps_install.fish: per-dep interactive install with method selection
- _fish_deps_update.fish: per-dep update using known install method

check_fish_deps becomes a thin wrapper delegating to `fish-deps status`.
README updated with Dependency Management section.
2026-05-18 21:51:22 -04:00
rootiest f09006846b fix(fzf): drop focus/resize bind entirely on older fzf builds
Older fzf (pre-0.62) does not support the focus and resize events in
bind actions, causing a startup error when --fish or the bundled
integration is sourced. Split the FZF_DEFAULT_OPTS preview block into
an if/else: newer fzf gets the dynamic bg-transform bind with wrap-word;
older fzf gets a static preview window with plain wrap and no event bind.
2026-05-18 21:47:20 -04:00
rootiest 2df665a537 feat(fzf): use fzf --fish integration and add fzf-update function
- config.fish: add ~/.fzf/bin to PATH for git-installed fzf
- config.fish: prefer fzf --fish | source (fzf >= 0.48, always
  version-matched) with fallback to integrations/fzf.fish for
  older builds; erase plugin bindings reliably when fzf is absent
- functions/fzf-update.fish: install or upgrade fzf from git HEAD
  using --bin so shell config files are not modified
2026-05-18 21:17:13 -04:00
rootiest 46be262f92 fix(fzf): erase fzf bindings in config.fish when fzf is absent
conf.d/fzf.fish is owned by Fisher and gets restored to the plugin's
original on fisher update, so any guard placed there is unreliable.
config.fish is never touched by Fisher, making it the right place to
call _fzf_uninstall_bindings after conf.d has already run and set up
the fzf key bindings on machines where fzf is not installed.
2026-05-18 21:06:09 -04:00
17 changed files with 784 additions and 86 deletions
+34 -9
View File
@@ -241,6 +241,24 @@ rm -f file.txt # Falls through to standard rm -f
| `upgrade` | Full system upgrade: `paru -Syu --noconfirm` |
| `cleanup` | Log and remove orphaned packages |
### Dependency Management
`fish-deps` is a unified command for checking, installing, and updating all tools this config depends on.
| Command | Description |
|---|---|
| `fish-deps` / `fish-deps status` | Show installed/missing status for all deps, grouped by tier |
| `fish-deps install` | Interactively install each missing dep (prompts per-dep, prompts method when multiple exist) |
| `fish-deps update` | Update all installed deps using their preferred install method |
| `fish-deps sync` | Install missing deps then update installed ones |
| `fzf-update` | Install or upgrade fzf from git HEAD into `~/.fzf` (guarantees the latest build) |
| `check_fish_deps` | Legacy alias — delegates to `fish-deps status` |
Install method priority: **git+cargo source build** (fish) → **cargo** (other Rust tools, gets latest crate) → **system PM** (paru/apt/brew/etc.) → **git clone** (fzf) → **curl installer** (starship, fisher) → **pipx** (Python tools). When multiple methods are available for a tool, you are prompted to choose.
> [!NOTE]
> Upgrading Fish from source requires **cargo** and **[uv](https://docs.astral.sh/uv/)**. Both are managed dependencies — `fish-deps install` will offer to install them before attempting the Fish build. If both are unavailable, `fish-deps update` falls back to the system package manager.
### Docker
| Function | Description |
@@ -476,20 +494,27 @@ Named context shortcuts (e.g. `dcr`, `dck`) live in `~/.config/.user-dots/fish/l
### Required
| Tool | Purpose |
|---|---|
| [Fish](https://fishshell.com/) | Shell |
| [Fisher](https://github.com/jorgebucaran/fisher) | Plugin manager |
| [Starship](https://starship.rs/) | Prompt |
| [fzf](https://github.com/junegunn/fzf) | Fuzzy finder |
| [zoxide](https://github.com/ajeetdsouza/zoxide) | Smart directory jumper |
| [direnv](https://direnv.net/) | Per-directory env loading |
| [paru](https://github.com/Morganamilo/paru) | AUR helper |
| Tool | Version | Purpose |
|---|---|---|
| [uv](https://docs.astral.sh/uv/) | any | Python runner (needed to build Fish from source) |
| [Rust / cargo](https://www.rust-lang.org/tools/install) | any | Installs Rust-based tools; required to build Fish |
| [Fish](https://fishshell.com/) | **≥ 4.0** | Shell |
| [Fisher](https://github.com/jorgebucaran/fisher) | any | Plugin manager |
| [Starship](https://starship.rs/) | any | Prompt |
| [fzf](https://github.com/junegunn/fzf) | any | Fuzzy finder |
| [zoxide](https://github.com/ajeetdsouza/zoxide) | any | Smart directory jumper |
| [direnv](https://direnv.net/) | any | Per-directory env loading |
> [!WARNING]
> Fish **4.0 or newer is required.** This config uses `test` syntax and other constructs that are incompatible with Fish 3.x. Older versions will produce errors on startup.
> Run `fish-deps install` or `fish-deps update` to upgrade — it will install `uv` and `cargo` automatically if missing, then build the latest Fish from source.
### Recommended
| Tool | Replaces |
|---|---|
| [Rust / cargo](https://www.rust-lang.org/tools/install) | Build tool for Rust-based CLI replacements below |
| [paru](https://github.com/Morganamilo/paru) / [yay](https://github.com/Jguer/yay) | AUR helper (Arch only) |
| [eza](https://github.com/eza-community/eza) | `ls` (preferred) |
| [lsd](https://github.com/lsd-rs/lsd) | `ls` (fallback) |
| [bat](https://github.com/sharkdp/bat) | `cat` |
+20 -4
View File
@@ -75,6 +75,7 @@ fish_add_path $BUN_INSTALL/bin
fish_add_path $XDG_DATA_HOME/npm-global/bin
fish_add_path $HOME/.lmstudio/bin
fish_add_path $HOME/.resend/bin
fish_add_path $HOME/.fzf/bin
# ───────────────────────── CDPATH projects dir ──────────────────────────
# Allows cd-ing to directories within $HOME/projects or $HOME without needing to specify the full path.
@@ -111,10 +112,25 @@ if status is-interactive
set -g fish_key_bindings fish_vi_key_bindings
# ──────────────────────── Source FZF integration ────────────────────────
# Sources the FZF integration script, which provides enhanced command history
# searching and file finding capabilities.
if test -f "$__fish_config_dir/integrations/fzf.fish"
source "$__fish_config_dir/integrations/fzf.fish"
# Prefer fzf's own fish integration (fzf --fish, available since fzf 0.48)
# which is always version-matched to the installed binary. Fall back to our
# bundled integrations/fzf.fish for older builds.
# Run `fzf-update` to install/upgrade fzf from git HEAD.
if type -q fzf
set -l _fzf_minor (fzf --version | string match -r '^\d+\.(\d+)')[2]
if test -n "$_fzf_minor" -a "$_fzf_minor" -ge 48
fzf --fish | source
else
test -f "$__fish_config_dir/integrations/fzf.fish"
and source "$__fish_config_dir/integrations/fzf.fish"
end
else
# conf.d/fzf.fish is managed by Fisher and may be restored on fisher
# update, so this is the reliable place to strip its bindings when
# fzf is not installed.
if functions -q _fzf_uninstall_bindings
_fzf_uninstall_bindings
end
end
# ──────────────────────────────── DirENV ────────────────────────────────
+55
View File
@@ -0,0 +1,55 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Populates parallel arrays describing every managed dependency.
# Callers must invoke this function before accessing _fdc_* arrays.
#
# Array layout (same index across all sets):
# _fdc_bins — binary name (what `type -q` checks)
# _fdc_tiers — req | int | rec
# _fdc_cargo — cargo crate name, or "" if not on crates.io
# _fdc_pm — system PM package name, or "" if not in repos
# _fdc_special — special install key: rustup-installer | fisher-bootstrap |
# fzf-update | paru-build | pipx | curl-installer |
# git-cargo-fish | curl-uv | "" (none)
#
# uv and cargo are listed first so both are available before fish and other Rust tools.
function _fish_deps_catalog
set -g _fdc_bins \
uv cargo fish fisher starship fzf zoxide direnv paru \
wakatime tailscale \
eza lsd bat btop dust duf prettyping most rg lazygit lazydocker trash kitty wezterm
set -g _fdc_tiers \
req req req req req req req req rec \
int int \
rec rec rec rec rec rec rec rec rec rec rec rec rec rec
set -g _fdc_cargo \
"" "" "" "" starship "" zoxide "" "" \
"" "" \
eza lsd bat "" du-dust "" "" "" ripgrep "" "" trashy "" ""
set -g _fdc_pm \
uv cargo fish "" starship fzf zoxide direnv "" \
wakatime tailscale \
eza lsd bat btop dust duf prettyping most ripgrep lazygit lazydocker trash kitty wezterm
set -g _fdc_special \
curl-uv rustup-installer git-cargo-fish fisher-bootstrap curl-installer fzf-update "" "" paru-build \
wakatime-binary "" \
"" "" "" "" "" "" "" "" "" "" curl-lazydocker "" "" ""
end
# Returns the index (1-based) of $argv[1] in the catalog, or "" if not found.
function _fish_deps_catalog_idx --argument-names bin
_fish_deps_catalog
set -l i 1
for b in $_fdc_bins
if test "$b" = "$bin"
echo $i
return
end
set i (math $i + 1)
end
end
+13
View File
@@ -0,0 +1,13 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Detect the first available system package manager.
function _fish_deps_detect_pm
for pm in paru yay pacman apt brew pkg dnf yum
if type -q $pm
echo $pm
return
end
end
echo ""
end
+265
View File
@@ -0,0 +1,265 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Interactively install missing deps.
# For each missing dep: prompts yes/no, then prompts install method when multiple exist.
function _fish_deps_install
_fish_deps_catalog
set -l pm (_fish_deps_detect_pm)
set -l installed_any 0
set -l i 1
for bin in $_fdc_bins
# Determine if this dep needs attention: missing, or fish < 4.0
set -l needs_install 0
set -l upgrade_label Install
if not type -q $bin
set needs_install 1
else if test "$bin" = fish
set -l _major (fish --version 2>&1 | string match -r 'version (\d+)')[2]
if test -n "$_major"; and test "$_major" -lt 4
set needs_install 1
set upgrade_label "Upgrade"
end
end
if test $needs_install -eq 1
set -l cargo_crate $_fdc_cargo[$i]
set -l pm_pkg $_fdc_pm[$i]
set -l special $_fdc_special[$i]
# Build list of available install methods
set -l methods
set -l method_labels
# Cargo — preferred for Rust tools; gets the latest crate version
if test -n "$cargo_crate"
if type -q cargo
set -a methods cargo
set -a method_labels "cargo ($cargo_crate)"
else
set_color brblack
echo " note: cargo not found — install cargo first for the latest $bin"
set_color normal
end
end
# Preferred special methods — listed before system PM so they are the default
switch $special
case curl-uv
set -a methods special-uv
set -a method_labels "curl installer (official script)"
case git-cargo-fish
if type -q cargo; and type -q uv
set -a methods special-git-cargo-fish
set -a method_labels "build from source (git + cargo)"
else
set_color brblack
set -l _need
type -q cargo; or set -a _need cargo
type -q uv; or set -a _need uv
echo " note: "(string join " and " $_need)" not found — install them first to build fish from source"
set_color normal
end
case rustup-installer
set -a methods special-rustup
set -a method_labels "rustup installer (curl | sh)"
case curl-lazydocker
set -a methods special-lazydocker
set -a method_labels "curl installer (official script)"
case wakatime-binary
set -a methods special-wakatime
set -a method_labels "binary download (github releases)"
end
# System PM — after cargo and preferred specials
if test -n "$pm_pkg"; and test -n "$pm"
set -a methods pm
set -a method_labels "$pm ($pm_pkg)"
end
# Supplemental special methods (fallbacks, Arch-only, etc.)
switch $special
case fzf-update
set -a methods special-fzf
set -a method_labels "git clone (~/.fzf)"
case fisher-bootstrap
set -a methods special-fisher
set -a method_labels "curl bootstrap (fisher)"
case curl-installer
set -a methods special-curl
set -a method_labels "curl installer"
case paru-build
# Only offered on Arch-based systems where pacman is present
if type -q yay
set -a methods special-yay-paru
set -a method_labels "yay -S paru"
end
if type -q pacman
set -a methods special-paru
set -a method_labels "build from AUR (makepkg)"
end
case pipx
if type -q pipx
set -a methods special-pipx
set -a method_labels "pipx ($bin)"
else if type -q pip
set -a methods special-pip
set -a method_labels "pip install --user ($bin)"
end
end
if test (count $methods) -eq 0
set_color yellow
echo " $bin: no install method available on this system — skipping"
set_color normal
set i (math $i + 1)
continue
end
# Prompt: install/upgrade this dep?
read -l -P (set_color cyan)"$upgrade_label $bin?"(set_color normal)" [Y/n] " _reply
if test "$_reply" = n; or test "$_reply" = N
set i (math $i + 1)
continue
end
# Choose install method
set -l chosen_method $methods[1]
if test (count $methods) -gt 1
echo " Available methods:"
set -l m 1
for lbl in $method_labels
set_color brblack; echo -n " $m) "; set_color normal
echo $lbl
set m (math $m + 1)
end
read -l -P " Choose [1-"(count $methods)"] (default 1 = $method_labels[1]): " _choice
if string match -qr '^\d+$' "$_choice"; and test "$_choice" -ge 1; and test "$_choice" -le (count $methods)
set chosen_method $methods[$_choice]
end
else
set_color brblack; echo " "(string lower $upgrade_label)"ing via $method_labels[1]"; set_color normal
end
# Execute chosen method
switch $chosen_method
case cargo
cargo install $cargo_crate
case pm
_fish_deps_pm_install $pm_pkg
case special-rustup
curl https://sh.rustup.rs -sSf | sh
# Add cargo to PATH for the rest of this session without restarting.
# Try CARGO_HOME first (set in config.fish), then the rustup default.
for _d in "$CARGO_HOME/bin" "$HOME/.cargo/bin"
if test -d "$_d"
fish_add_path "$_d"
break
end
end
if not type -q cargo
set_color yellow
echo " cargo not yet in PATH — restart your shell if subsequent installs fail."
set_color normal
end
case special-lazydocker
curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash
case special-wakatime
set -l _arch (uname -m)
switch $_arch
case x86_64
set _arch amd64
case aarch64 arm64
set _arch arm64
case armv7l
set _arch arm
case '*'
set _arch amd64
end
set -l _zip "wakatime-cli-linux-$_arch.zip"
set -l _bin_src "wakatime-cli-linux-$_arch"
set -l _wt_dir "$HOME/.config/wakatime"
set -l _wt_bin "$_wt_dir/wakatime"
set -l _tmpdir (mktemp -d)
curl -L "https://github.com/wakatime/wakatime-cli/releases/latest/download/$_zip" \
-o "$_tmpdir/$_zip"
and unzip -o "$_tmpdir/$_zip" -d "$_tmpdir"
and mkdir -p "$_wt_dir" "$HOME/.local/bin"
and cp "$_tmpdir/$_bin_src" "$_wt_bin"
and chmod +x "$_wt_bin"
and ln -sf "$_wt_bin" "$HOME/.local/bin/wakatime"
rm -rf "$_tmpdir"
case special-fzf
fzf-update
case special-fisher
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source
fisher update
case special-curl
if test "$bin" = starship
curl -sS https://starship.rs/install.sh | sh
end
case special-yay-paru
yay -S --noconfirm paru
case special-paru
set -l _build_dir (mktemp -d)
git clone https://aur.archlinux.org/paru.git $_build_dir
and pushd $_build_dir
and makepkg -si --noconfirm
and popd
rm -rf $_build_dir
case special-uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Add uv to PATH for the rest of this session
for _d in "$HOME/.local/bin" "$HOME/.cargo/bin"
if test -d "$_d"
fish_add_path "$_d"
break
end
end
if not type -q uv
set_color yellow
echo " uv not yet in PATH — restart your shell if subsequent installs fail."
set_color normal
end
case special-git-cargo-fish
set -l _tmpdir (mktemp -d)
set -l _build_ok 0
git clone https://github.com/fish-shell/fish-shell "$_tmpdir"
and begin
set -l _tag (git -C "$_tmpdir" tag --list 'fish-*' --sort=version:refname | tail -1)
test -n "$_tag"; and git -C "$_tmpdir" checkout "$_tag"
true
end
and pushd "$_tmpdir"
and uv run --no-managed-python cargo install --path .
and set _build_ok 1
popd 2>/dev/null
rm -rf "$_tmpdir"
test $_build_ok -eq 1
case special-pipx
pipx install $bin
case special-pip
pip install --user $bin
end
if test $status -eq 0
set installed_any 1
set_color green; echo " $bin "(string lower $upgrade_label)"ed."; set_color normal
if test "$bin" = fish
set_color yellow
echo " Fish upgraded — restart your shell to use the new version."
set_color normal
end
else
set_color red; echo " $bin "(string lower $upgrade_label)" failed."; set_color normal
end
end
set i (math $i + 1)
end
if test $installed_any -eq 0
echo "Nothing to install."
end
end
+28
View File
@@ -0,0 +1,28 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Install a package via the system PM.
# Usage: _fish_deps_pm_install <pkg>
function _fish_deps_pm_install --argument-names pkg
set -l pm (_fish_deps_detect_pm)
if test -z "$pm"
echo "No supported package manager found." >&2
return 1
end
switch $pm
case paru yay
$pm -S --noconfirm $pkg
case pacman
sudo pacman -S --noconfirm $pkg
case apt
sudo apt install -y $pkg
case brew
brew install $pkg
case pkg
sudo pkg install -y $pkg
case dnf
sudo dnf install -y $pkg
case yum
sudo yum install -y $pkg
end
end
+28
View File
@@ -0,0 +1,28 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Upgrade an already-installed package via the system PM.
# Usage: _fish_deps_pm_upgrade <pkg>
function _fish_deps_pm_upgrade --argument-names pkg
set -l pm (_fish_deps_detect_pm)
if test -z "$pm"
echo "No supported package manager found." >&2
return 1
end
switch $pm
case paru yay
$pm -S --noconfirm $pkg
case pacman
sudo pacman -S --noconfirm $pkg
case apt
sudo apt install --only-upgrade -y $pkg
case brew
brew upgrade $pkg
case pkg
sudo pkg upgrade -y $pkg
case dnf
sudo dnf upgrade -y $pkg
case yum
sudo yum update -y $pkg
end
end
+50
View File
@@ -0,0 +1,50 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Print colored installed/missing status for all deps, grouped by tier.
function _fish_deps_status
_fish_deps_catalog
function __fds_print_dep --argument-names bin tier
if type -q $bin
# Special version check: fish < 4.0 is functionally incompatible
if test "$bin" = fish
set -l _major (fish --version 2>&1 | string match -r 'version (\d+)')[2]
if test -n "$_major"; and test "$_major" -lt 4
set -l _ver (fish --version 2>&1 | string replace 'fish, ' '')
set_color yellow; echo -n " ⚠ "; set_color normal
echo -n "$bin "
set_color brblack; echo "($_ver — upgrade to 4.0+ required)"; set_color normal
return
end
end
set_color green; echo -n " ✓ "; set_color normal
echo -n "$bin "
set_color brblack; echo "(Found at "(type -p $bin)")"; set_color normal
else if test "$tier" = rec
set_color yellow; echo -n " ⚠ "; set_color normal
echo -n "$bin "
set_color brblack; echo "(Not installed)"; set_color normal
else
set_color red; echo -n " ✗ "; set_color normal
echo -n "$bin "
set_color brblack; echo "(Not installed)"; set_color normal
end
end
for tier_label in "Required Dependencies:req" "Integrations:int" "Recommended Dependencies:rec"
set -l label (string split : $tier_label)[1]
set -l tier (string split : $tier_label)[2]
set_color cyan; echo $label; set_color normal
set -l i 1
for bin in $_fdc_bins
if test "$_fdc_tiers[$i]" = $tier
__fds_print_dep $bin $tier
end
set i (math $i + 1)
end
echo ""
end
functions -e __fds_print_dep
end
+177
View File
@@ -0,0 +1,177 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Update all installed deps using their known install method.
# Priority: cargo > system PM > special (fzf-update, fisher, pipx).
function _fish_deps_update
_fish_deps_catalog
set -l pm (_fish_deps_detect_pm)
set -l updated_any 0
# Fisher plugins — always update if fisher is present
if type -q fisher
echo "Updating fisher plugins..."
fisher update
set updated_any 1
end
set -l i 1
for bin in $_fdc_bins
# Skip fisher itself (handled above) and tools that aren't installed
if test "$bin" = fisher; or not type -q $bin
set i (math $i + 1)
continue
end
set -l cargo_crate $_fdc_cargo[$i]
set -l pm_pkg $_fdc_pm[$i]
set -l special $_fdc_special[$i]
# cargo: update via rustup
if test "$special" = rustup-installer
if type -q rustup
echo "Updating $bin..."
rustup update
set updated_any 1
end
set i (math $i + 1)
continue
end
# fzf: always use fzf-update (git-based)
if test "$special" = fzf-update
echo "Updating $bin..."
fzf-update
set updated_any 1
set i (math $i + 1)
continue
end
# lazydocker: re-run the official install/update script
if test "$special" = curl-lazydocker
echo "Updating $bin..."
curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash
set updated_any 1
set i (math $i + 1)
continue
end
# wakatime: re-download the binary from github releases
if test "$special" = wakatime-binary
echo "Updating $bin..."
set -l _arch (uname -m)
switch $_arch
case x86_64; set _arch amd64
case aarch64 arm64; set _arch arm64
case armv7l; set _arch arm
case '*'; set _arch amd64
end
set -l _zip "wakatime-cli-linux-$_arch.zip"
set -l _bin_src "wakatime-cli-linux-$_arch"
set -l _wt_bin "$HOME/.config/wakatime/wakatime"
set -l _tmpdir (mktemp -d)
curl -L "https://github.com/wakatime/wakatime-cli/releases/latest/download/$_zip" \
-o "$_tmpdir/$_zip"
and unzip -o "$_tmpdir/$_zip" -d "$_tmpdir"
and cp "$_tmpdir/$_bin_src" "$_wt_bin"
and chmod +x "$_wt_bin"
rm -rf "$_tmpdir"
and set updated_any 1
set i (math $i + 1)
continue
end
# pipx tools
if test "$special" = pipx
if type -q pipx
echo "Updating $bin..."
pipx upgrade $bin
set updated_any 1
end
set i (math $i + 1)
continue
end
# uv: use built-in self-updater
if test "$special" = curl-uv
echo "Updating $bin..."
uv self update
set updated_any 1
set i (math $i + 1)
continue
end
# fish: prefer build from source via git + cargo; fall back to PM
if test "$special" = git-cargo-fish
if type -q cargo; and type -q uv
echo "Updating $bin..."
set -l _tmpdir (mktemp -d)
set -l _build_ok 0
git clone https://github.com/fish-shell/fish-shell "$_tmpdir"
and begin
set -l _tag (git -C "$_tmpdir" tag --list 'fish-*' --sort=version:refname | tail -1)
test -n "$_tag"; and git -C "$_tmpdir" checkout "$_tag"
true
end
and pushd "$_tmpdir"
and uv run --no-managed-python cargo install --path .
and set _build_ok 1
popd 2>/dev/null
rm -rf "$_tmpdir"
if test $_build_ok -eq 1
set updated_any 1
set_color yellow
echo " Fish updated — restart your shell to use the new version."
set_color normal
end
else if test -n "$pm_pkg"; and test -n "$pm"
echo "Updating $bin (cargo/uv unavailable, using system PM)..."
_fish_deps_pm_upgrade $pm_pkg
set updated_any 1
set_color yellow
echo " Fish updated — restart your shell to use the new version."
set_color normal
else
set_color yellow
echo " fish: cannot update — install cargo and uv to build from source"
set_color normal
end
set i (math $i + 1)
continue
end
# curl-installer tools (starship etc.): re-run install script, which upgrades in place
if test "$special" = curl-installer
if test "$bin" = starship
echo "Updating $bin..."
curl -sS https://starship.rs/install.sh | sh -s -- --yes
set updated_any 1
end
set i (math $i + 1)
continue
end
# Cargo: prefer for Rust tools
if test -n "$cargo_crate"; and type -q cargo
echo "Updating $bin..."
cargo install --force $cargo_crate
set updated_any 1
set i (math $i + 1)
continue
end
# System PM fallback
if test -n "$pm_pkg"; and test -n "$pm"
echo "Updating $bin..."
_fish_deps_pm_upgrade $pm_pkg
set updated_any 1
end
set i (math $i + 1)
end
if test $updated_any -eq 0
echo "Nothing to update."
end
end
+2 -45
View File
@@ -1,50 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Check all fish-related dependencies
# Thin wrapper kept for backwards compatibility.
function check_fish_deps --description 'Check all fish-related dependencies'
set -l required fish fisher starship fzf zoxide direnv paru
set -l integrations wakatime tailscale
set -l recommended eza lsd bat btop dust duf prettyping most rg lazygit lazydocker trash kitty wezterm
function __print_dep
set -l dep $argv[1]
if type -q $dep
set_color green
echo -n "  "
set_color normal
echo -n "$dep "
set_color brblack
echo "(Found at "(type -p $dep)")"
set_color normal
else
set_color red
echo -n "  "
set_color normal
echo -n "$dep "
set_color brblack
echo "(Not installed)"
set_color normal
end
end
set_color cyan; echo "Required Dependencies:"; set_color normal
for dep in $required
__print_dep $dep
end
echo ""
set_color cyan; echo "Integrations:"; set_color normal
for dep in $integrations
__print_dep $dep
end
echo ""
set_color cyan; echo "Recommended Dependencies:"; set_color normal
for dep in $recommended
__print_dep $dep
end
echo ""
functions -e __print_dep
fish-deps status
end
+41
View File
@@ -0,0 +1,41 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function fish-deps --description 'Manage fish shell dependencies'
set -l subcmd $argv[1]
switch $subcmd
case status ''
_fish_deps_status
case install
_fish_deps_install
case update
_fish_deps_update
case sync
echo "=== Installing missing deps ==="
_fish_deps_install
echo ""
echo "=== Updating installed deps ==="
_fish_deps_update
case '*'
set_color red
echo "Unknown subcommand: $subcmd"
set_color normal
echo ""
__fish_deps_help
return 1
end
end
function __fish_deps_help
set_color cyan; echo "fish-deps — manage fish shell dependencies"; set_color normal
echo ""
echo "Usage:"
echo " fish-deps [status] Check installed/missing deps (default)"
echo " fish-deps install Install missing deps interactively"
echo " fish-deps update Update all installed deps"
echo " fish-deps sync Install missing, then update all"
echo ""
echo "Install method priority: cargo > system PM > git/curl/pipx"
echo "When multiple methods are available, you will be prompted to choose."
end
+15
View File
@@ -0,0 +1,15 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Installs or upgrades fzf from git HEAD into ~/.fzf
function fzf-update --description 'Install or upgrade fzf from git HEAD'
if test -d ~/.fzf
echo "Updating fzf..."
git -C ~/.fzf pull --ff-only
else
echo "Installing fzf..."
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
end
and ~/.fzf/install --bin
and echo "fzf $(fzf --version) ready. Restart your shell to activate."
end
+11 -4
View File
@@ -3,16 +3,23 @@
# Interactively search and remove an installed package using fzf
function parur --description 'Interactively search and remove an installed package using fzf'
# 1. Use command substitution to get the package list from fzf
set -l aur ""
if type -q paru
set aur paru
else if type -q yay
set aur yay
else
echo "No AUR helper found (install paru or yay)" >&2
return 1
end
set -l pkg_list (
pacman -Qqs \
| fzf --preview 'pacman -Qi {}' --multi
)
# 2. Check if a package was selected.
if test (count $pkg_list) -gt 0
# 3. Pass the selected packages directly to paru -R
paru -R $pkg_list
$aur -R $pkg_list
else
echo "No packages selected for removal."
end
+11 -6
View File
@@ -1,10 +1,15 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Function for installing packages with paru.
# This runs `paru` with the `-S` flag to install one or more packages.
# The `$argv` variable passes all arguments given to the `pkg` function
# directly to the `paru` command.
function pkg --wraps='paru' --description 'directly to the `paru` command.'
paru -S $argv
function pkg --description 'Install packages via paru or yay'
set -l aur ""
if type -q paru
set aur paru
else if type -q yay
set aur yay
else
echo "No AUR helper found (install paru or yay)" >&2
return 1
end
$aur -S $argv
end
+11 -6
View File
@@ -1,10 +1,15 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Function for searching for packages to install with paru.
# This runs `paru` with the search flags.
# The `$argv` variable passes all arguments given to the `search` function
# directly to the `paru` command.
function search --wraps='paru' --description 'directly to the `paru` command.'
paru $argv
function search --description 'Search/install packages interactively via paru or yay'
set -l aur ""
if type -q paru
set aur paru
else if type -q yay
set aur yay
else
echo "No AUR helper found (install paru or yay)" >&2
return 1
end
$aur $argv
end
+11 -5
View File
@@ -1,9 +1,15 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Function for upgrading the system with paru.
# This runs `paru` with the `-Syu` flags to sync, refresh, and upgrade all
# packages, and adds `--no-confirm` to bypass the confirmation prompt.
function upgrade --wraps='paru' --description 'packages, and adds `--no-confirm` to bypass the confirmation prompt.'
paru -Syu --noconfirm
function upgrade --description 'Full system upgrade via paru or yay'
set -l aur ""
if type -q paru
set aur paru
else if type -q yay
set aur yay
else
echo "No AUR helper found (install paru or yay)" >&2
return 1
end
$aur -Syu --noconfirm
end
+12 -7
View File
@@ -221,13 +221,18 @@ function fzf_key_bindings
end
# Prepend the options to allow user customizations
# wrap-word requires the same newer fzf as bg-transform; fall back to plain wrap
set -l _fzf_wrap_opt wrap
test "$_fzf_transform_action" = bg-transform; and set _fzf_wrap_opt wrap-word
set -p -- FZF_DEFAULT_OPTS \
'--bind="focus,resize:'$_fzf_transform_action':if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \
'--preview="string collect -- (test \\"$FZF_SELECT_COUNT\\" -gt 0; and string collect -- {+2..}) \\"\\n# \\"'$date_cmd' {2..} | fish_indent --ansi"' \
'--preview-window="right,50%,'$_fzf_wrap_opt',follow,info,hidden"'
if test "$_fzf_transform_action" = bg-transform
# Newer fzf: dynamic show/hide preview based on terminal width
set -p -- FZF_DEFAULT_OPTS \
'--bind="focus,resize:bg-transform:if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \
'--preview="string collect -- (test \\"$FZF_SELECT_COUNT\\" -gt 0; and string collect -- {+2..}) \\"\\n# \\"'$date_cmd' {2..} | fish_indent --ansi"' \
'--preview-window="right,50%,wrap-word,follow,info,hidden"'
else
# Older fzf: static preview; focus/resize events not reliably supported
set -p -- FZF_DEFAULT_OPTS \
'--preview="string collect -- (test \\"$FZF_SELECT_COUNT\\" -gt 0; and string collect -- {+2..}) \\"\\n# \\"'$date_cmd' {2..} | fish_indent --ansi"' \
'--preview-window="right,50%,wrap,follow,info"'
end
end
set -lx FZF_DEFAULT_OPTS_FILE