feat: initial fish shell configuration

- Core config layered on CachyOS base with Catppuccin Mocha theming
- Fisher plugins: fzf.fish, catppuccin, autopair, replay, puffer-fish, magic-enter, spark
- Smart CLI wrappers with fallbacks (bat, lsd, btop, dust, prettyping)
- Custom functions: git, docker, network, kitty, AI session management
- Extensive abbreviation system for keyboard-driven workflows
- Secrets/local sourcing pattern for private and machine-specific config
- README with full documentation and personalization guide
- AGPLv3+ license with copyright headers on all source files
This commit is contained in:
2026-04-26 00:59:48 -04:00
commit 4c1e7a7eb9
131 changed files with 5625 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
function _autopair_backspace
set --local index (commandline --cursor)
set --local buffer (commandline)
test $index -ge 1 &&
contains -- (string sub --start=$index --length=2 -- "$buffer") $autopair_pairs &&
commandline --function delete-char
commandline --function backward-delete-char
end
+13
View File
@@ -0,0 +1,13 @@
function _autopair_insert_left --argument-names left right
set --local buffer (commandline)
set --local before (commandline --cut-at-cursor)
commandline --insert -- $left
switch "$buffer"
case "$before"{," "\*,$autopair_right\*}
set --local index (commandline --cursor)
commandline --insert -- $right
commandline --cursor $index
end
end
+11
View File
@@ -0,0 +1,11 @@
function _autopair_insert_right --argument-names key
set --local buffer (commandline)
set --local before (commandline --cut-at-cursor)
switch "$buffer"
case "$before$key"\*
commandline --cursor (math (commandline --cursor) + 1)
case \*
commandline --insert -- $key
end
end
+20
View File
@@ -0,0 +1,20 @@
function _autopair_insert_same --argument-names key
set --local buffer (commandline)
set --local index (commandline --cursor)
set --local next (string sub --start=(math $index + 1) --length=1 -- "$buffer")
if test (math (count (string match --all --regex -- "$key" "$buffer")) % 2) = 0
test $key = $next && commandline --cursor (math $index + 1) && return
commandline --insert -- $key
if test $index -lt 1 ||
contains -- (string sub --start=$index --length=1 -- "$buffer") "" " " $autopair_left &&
contains -- $next "" " " $autopair_right
commandline --insert -- $key
commandline --cursor (math $index + 1)
end
else
commandline --insert -- $key
end
end
+7
View File
@@ -0,0 +1,7 @@
function _autopair_tab
commandline --paging-mode && down-or-search && return
string match --quiet --regex -- '\$[^\s]*"$' (commandline --current-token) &&
commandline --function end-of-line --function backward-delete-char
commandline --function complete
end
@@ -0,0 +1,44 @@
function _fzf_configure_bindings_help --description "Prints the help message for fzf_configure_bindings."
echo "\
USAGE:
fzf_configure_bindings [--COMMAND=[KEY_SEQUENCE]...]
DESCRIPTION
fzf_configure_bindings installs key bindings for fzf.fish's commands and erases any bindings it
previously installed. It installs bindings for both default and insert modes. fzf.fish executes
it without options on fish startup to install the out-of-the-box key bindings.
By default, commands are bound to a mnemonic key sequence, shown below. Each command's binding
can be configured using a namesake corresponding option:
COMMAND | DEFAULT KEY SEQUENCE | CORRESPONDING OPTION
Search Directory | Ctrl+Alt+F (F for file) | --directory
Search Git Log | Ctrl+Alt+L (L for log) | --git_log
Search Git Status | Ctrl+Alt+S (S for status) | --git_status
Search History | Ctrl+R (R for reverse) | --history
Search Processes | Ctrl+Alt+P (P for process) | --processes
Search Variables | Ctrl+V (V for variable) | --variables
Override a command's binding by specifying its corresponding option with the desired key
sequence using fish's key name syntax (e.g. ctrl-f, ctrl-alt-v). Disable a command's binding
by specifying its corresponding option with no value.
Because fzf_configure_bindings erases bindings it previously installed, it can be cleanly
executed multiple times. Once the desired fzf_configure_bindings command has been found, add it
to your config.fish in order to persist the customized bindings.
In terms of validation, fzf_configure_bindings fails if passed unknown options. It expects an
equals sign between an option's name and value. However, it does not validate key sequences.
Pass -h or --help to print this help message and exit.
EXAMPLES
Default bindings but bind Search Directory to Ctrl+F and Search Variables to Ctrl+Alt+V
\$ fzf_configure_bindings --directory=ctrl-f --variables=ctrl-alt-v
Default bindings but disable Search History
\$ fzf_configure_bindings --history=
An agglomeration of different options
\$ fzf_configure_bindings --git_status=ctrl-g --history=ctrl-h --variables= --processes=
SEE Also
To learn more about fish key bindings, see bind(1) and fish_key_reader(1).
"
end
+13
View File
@@ -0,0 +1,13 @@
# helper function for _fzf_search_variables
function _fzf_extract_var_info --argument-names variable_name set_show_output --description "Extract and reformat lines pertaining to \$variable_name from \$set_show_output."
# Extract only the lines about the variable, all of which begin with either
# $variable_name: ...or... $variable_name[
string match --regex "^\\\$$variable_name(?::|\[).*" <$set_show_output |
# Strip the variable name prefix, including ": " for scope info lines
string replace --regex "^\\\$$variable_name(?:: )?" '' |
# Distill the lines of values, replacing...
# [1]: |value|
# ...with...
# [1] value
string replace --regex ": \|(.*)\|" ' $1'
end
+49
View File
@@ -0,0 +1,49 @@
# helper for _fzf_search_git_status
# arg should be a line from git status --short, e.g.
# MM functions/_fzf_preview_changed_file.fish
# D README.md
# R LICENSE -> "New License"
function _fzf_preview_changed_file --argument-names path_status --description "Show the git diff of the given file."
# remove quotes because they'll be interpreted literally by git diff
# no need to requote when referencing $path because fish does not perform word splitting
# https://fishshell.com/docs/current/fish_for_bash_users.html
set -f path (string unescape (string sub --start 4 $path_status))
# first letter of short format shows index, second letter shows working tree
# https://git-scm.com/docs/git-status/2.35.0#_short_format
set -f index_status (string sub --length 1 $path_status)
set -f working_tree_status (string sub --start 2 --length 1 $path_status)
set -f diff_opts --color=always
if test $index_status = '?'
_fzf_report_diff_type Untracked
_fzf_preview_file $path
else if contains {$index_status}$working_tree_status DD AU UD UA DU AA UU
# Unmerged statuses taken directly from git status help's short format table
# Unmerged statuses are mutually exclusive with other statuses, so if we see
# these, then safe to assume the path is unmerged
_fzf_report_diff_type Unmerged
git diff $diff_opts -- $path
else
if test $index_status != ' '
_fzf_report_diff_type Staged
# renames are only detected in the index, never working tree, so only need to test for it here
# https://stackoverflow.com/questions/73954214
if test $index_status = R
# diff the post-rename path with the original path, otherwise the diff will show the entire file as being added
set -f orig_and_new_path (string split --max 1 -- ' -> ' $path)
git diff --staged $diff_opts -- $orig_and_new_path[1] $orig_and_new_path[2]
# path currently has the form of "original -> current", so we need to correct it before it's used below
set path $orig_and_new_path[2]
else
git diff --staged $diff_opts -- $path
end
end
if test $working_tree_status != ' '
_fzf_report_diff_type Unstaged
git diff $diff_opts -- $path
end
end
end
+43
View File
@@ -0,0 +1,43 @@
# helper function for _fzf_search_directory and _fzf_search_git_status
function _fzf_preview_file --description "Print a preview for the given file based on its file type."
# because there's no way to guarantee that _fzf_search_directory passes the path to _fzf_preview_file
# as one argument, we collect all the arguments into one single variable and treat that as the path
set -f file_path $argv
if test -L "$file_path" # symlink
# notify user and recurse on the target of the symlink, which can be any of these file types
set -l target_path (realpath "$file_path")
set_color yellow
echo "'$file_path' is a symlink to '$target_path'."
set_color normal
_fzf_preview_file "$target_path"
else if test -f "$file_path" # regular file
if set --query fzf_preview_file_cmd
# need to escape quotes to make sure eval receives file_path as a single arg
eval "$fzf_preview_file_cmd '$file_path'"
else
bat --style=numbers --color=always "$file_path"
end
else if test -d "$file_path" # directory
if set --query fzf_preview_dir_cmd
# see above
eval "$fzf_preview_dir_cmd '$file_path'"
else
# -A list hidden files as well, except for . and ..
# -F helps classify files by appending symbols after the file name
command ls -A -F "$file_path"
end
else if test -c "$file_path"
_fzf_report_file_type "$file_path" "character device file"
else if test -b "$file_path"
_fzf_report_file_type "$file_path" "block device file"
else if test -S "$file_path"
_fzf_report_file_type "$file_path" socket
else if test -p "$file_path"
_fzf_report_file_type "$file_path" "named pipe"
else
echo "$file_path doesn't exist." >&2
end
end
+18
View File
@@ -0,0 +1,18 @@
# helper for _fzf_preview_changed_file
# prints out something like
# ╭────────╮
# │ Staged │
# ╰────────╯
function _fzf_report_diff_type --argument-names diff_type --description "Print a distinct colored header meant to preface a git patch."
# number of "-" to draw is the length of the string to box + 2 for padding
set -f repeat_count (math 2 + (string length $diff_type))
set -f line (string repeat --count $repeat_count)
set -f top_border$line
set -f btm_border$line
set_color yellow
echo $top_border
echo "$diff_type"
echo $btm_border
set_color normal
end
+6
View File
@@ -0,0 +1,6 @@
# helper function for _fzf_preview_file
function _fzf_report_file_type --argument-names file_path file_type --description "Explain the file type for a file."
set_color red
echo "Cannot preview '$file_path': it is a $file_type."
set_color normal
end
+32
View File
@@ -0,0 +1,32 @@
function _fzf_search_directory --description "Search the current directory. Replace the current token with the selected file paths."
# Directly use fd binary to avoid output buffering delay caused by a fd alias, if any.
# Debian-based distros install fd as fdfind and the fd package is something else, so
# check for fdfind first. Fall back to "fd" for a clear error message.
set -f fd_cmd (command -v fdfind || command -v fd || echo "fd")
set -f --append fd_cmd --color=always $fzf_fd_opts
set -f fzf_arguments --multi --ansi $fzf_directory_opts
set -f token (commandline --current-token)
# expand any variables or leading tilde (~) in the token
set -f expanded_token (eval echo -- $token)
# unescape token because it's already quoted so backslashes will mess up the path
set -f unescaped_exp_token (string unescape -- $expanded_token)
# If the current token is a directory and has a trailing slash,
# then use it as fd's base directory.
if string match --quiet -- "*/" $unescaped_exp_token && test -d "$unescaped_exp_token"
set --append fd_cmd --base-directory=$unescaped_exp_token
# use the directory name as fzf's prompt to indicate the search is limited to that directory
set --prepend fzf_arguments --prompt="Directory $unescaped_exp_token> " --preview="_fzf_preview_file $expanded_token{}"
set -f file_paths_selected $unescaped_exp_token($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
else
set --prepend fzf_arguments --prompt="Directory> " --query="$unescaped_exp_token" --preview='_fzf_preview_file {}'
set -f file_paths_selected ($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
end
if test $status -eq 0
commandline --current-token --replace -- (string escape -- $file_paths_selected | string join ' ')
end
commandline --function repaint
end
+36
View File
@@ -0,0 +1,36 @@
function _fzf_search_git_log --description "Search the output of git log and preview commits. Replace the current token with the selected commit hash."
if not git rev-parse --git-dir >/dev/null 2>&1
echo '_fzf_search_git_log: Not in a git repository.' >&2
else
if not set --query fzf_git_log_format
# %h gives you the abbreviated commit hash, which is useful for saving screen space, but we will have to expand it later below
set -f fzf_git_log_format '%C(bold blue)%h%C(reset) - %C(cyan)%ad%C(reset) %C(yellow)%d%C(reset) %C(normal)%s%C(reset) %C(dim normal)[%an]%C(reset)'
end
set -f preview_cmd 'git show --color=always --stat --patch {1}'
if set --query fzf_diff_highlighter
set preview_cmd "$preview_cmd | $fzf_diff_highlighter"
end
set -f selected_log_lines (
git log --no-show-signature --color=always --format=format:$fzf_git_log_format --date=short | \
_fzf_wrapper --ansi \
--multi \
--scheme=history \
--prompt="Git Log> " \
--preview=$preview_cmd \
--query=(commandline --current-token) \
$fzf_git_log_opts
)
if test $status -eq 0
for line in $selected_log_lines
set -f abbreviated_commit_hash (string split --field 1 " " $line)
set -f full_commit_hash (git rev-parse $abbreviated_commit_hash)
set -f --append commit_hashes $full_commit_hash
end
commandline --current-token --replace (string join ' ' $commit_hashes)
end
end
commandline --function repaint
end
+41
View File
@@ -0,0 +1,41 @@
function _fzf_search_git_status --description "Search the output of git status. Replace the current token with the selected file paths."
if not git rev-parse --git-dir >/dev/null 2>&1
echo '_fzf_search_git_status: Not in a git repository.' >&2
else
set -f preview_cmd '_fzf_preview_changed_file {}'
if set --query fzf_diff_highlighter
set preview_cmd "$preview_cmd | $fzf_diff_highlighter"
end
set -f selected_paths (
# Pass configuration color.status=always to force status to use colors even though output is sent to a pipe
git -c color.status=always status --short |
_fzf_wrapper --ansi \
--multi \
--prompt="Git Status> " \
--query=(commandline --current-token) \
--preview=$preview_cmd \
--nth="2.." \
$fzf_git_status_opts
)
if test $status -eq 0
# git status --short automatically escapes the paths of most files for us so not going to bother trying to handle
# the few edges cases of weird file names that should be extremely rare (e.g. "this;needs;escaping")
set -f cleaned_paths
for path in $selected_paths
if test (string sub --length 1 $path) = R
# path has been renamed and looks like "R LICENSE -> LICENSE.md"
# extract the path to use from after the arrow
set --append cleaned_paths (string split -- "-> " $path)[-1]
else
set --append cleaned_paths (string sub --start=4 $path)
end
end
commandline --current-token --replace -- (string join ' ' $cleaned_paths)
end
end
commandline --function repaint
end
+39
View File
@@ -0,0 +1,39 @@
function _fzf_search_history --description "Search command history. Replace the command line with the selected command."
# history merge incorporates history changes from other fish sessions
# it errors out if called in private mode
if test -z "$fish_private_mode"
builtin history merge
end
if not set --query fzf_history_time_format
# Reference https://devhints.io/strftime to understand strftime format symbols
set -f fzf_history_time_format "%m-%d %H:%M:%S"
end
# Delinate time from command in history entries using the vertical box drawing char (U+2502).
# Then, to get raw command from history entries, delete everything up to it. The ? on regex is
# necessary to make regex non-greedy so it won't match into commands containing the char.
set -f time_prefix_regex '^.*? │ '
# Delinate commands throughout pipeline using null rather than newlines because commands can be multi-line
set -f commands_selected (
builtin history --null --show-time="$fzf_history_time_format" |
_fzf_wrapper --read0 \
--print0 \
--multi \
--scheme=history \
--prompt="History> " \
--query=(commandline) \
--preview="string replace --regex '$time_prefix_regex' '' -- {} | fish_indent --ansi" \
--preview-window="bottom:3:wrap" \
$fzf_history_opts |
string split0 |
# remove timestamps from commands selected
string replace --regex $time_prefix_regex ''
)
if test $status -eq 0
commandline --replace -- $commands_selected
end
commandline --function repaint
end
+32
View File
@@ -0,0 +1,32 @@
function _fzf_search_processes --description "Search all running processes. Replace the current token with the pid of the selected process."
# Directly use ps command because it is often aliased to a different command entirely
# or with options that dirty the search results and preview output
set -f ps_cmd (command -v ps || echo "ps")
# use all caps to be consistent with ps default format
# snake_case because ps doesn't seem to allow spaces in the field names
set -f ps_preview_fmt (string join ',' 'pid' 'ppid=PARENT' 'user' '%cpu' 'rss=RSS_IN_KB' 'start=START_TIME' 'command')
set -f processes_selected (
$ps_cmd -A -opid,command | \
_fzf_wrapper --multi \
--prompt="Processes> " \
--query (commandline --current-token) \
--ansi \
# first line outputted by ps is a header, so we need to mark it as so
--header-lines=1 \
# ps uses exit code 1 if the process was not found, in which case show an message explaining so
--preview="$ps_cmd -o '$ps_preview_fmt' -p {1} || echo 'Cannot preview {1} because it exited.'" \
--preview-window="bottom:4:wrap" \
$fzf_processes_opts
)
if test $status -eq 0
for process in $processes_selected
set -f --append pids_selected (string split --no-empty --field=1 -- " " $process)
end
# string join to replace the newlines outputted by string split with spaces
commandline --current-token --replace -- (string join ' ' $pids_selected)
end
commandline --function repaint
end
+47
View File
@@ -0,0 +1,47 @@
# This function expects the following two arguments:
# argument 1 = output of (set --show | psub), i.e. a file with the scope info and values of all variables
# argument 2 = output of (set --names | psub), i.e. a file with all variable names
function _fzf_search_variables --argument-names set_show_output set_names_output --description "Search and preview shell variables. Replace the current token with the selected variable."
if test -z "$set_names_output"
printf '%s\n' '_fzf_search_variables requires 2 arguments.' >&2
commandline --function repaint
return 22 # 22 means invalid argument in POSIX
end
# Exclude the history variable from being piped into fzf because
# 1. it's not included in $set_names_output
# 2. it tends to be a very large value => increases computation time
# 3._fzf_search_history is a much better way to examine history anyway
set -f all_variable_names (string match --invert history <$set_names_output)
set -f current_token (commandline --current-token)
# Use the current token to pre-populate fzf's query. If the current token begins
# with a $, remove it from the query so that it will better match the variable names
set -f cleaned_curr_token (string replace -- '$' '' $current_token)
set -f variable_names_selected (
printf '%s\n' $all_variable_names |
_fzf_wrapper --preview "_fzf_extract_var_info {} $set_show_output" \
--prompt="Variables> " \
--preview-window="wrap" \
--multi \
--query=$cleaned_curr_token \
$fzf_variables_opts
)
if test $status -eq 0
# If the current token begins with a $, do not overwrite the $ when
# replacing the current token with the selected variable.
# Uses brace expansion to prepend $ to each variable name.
commandline --current-token --replace (
if string match --quiet -- '$*' $current_token
string join " " \${$variable_names_selected}
else
string join " " $variable_names_selected
end
)
end
commandline --function repaint
end
+21
View File
@@ -0,0 +1,21 @@
function _fzf_wrapper --description "Prepares some environment variables before executing fzf."
# Make sure fzf uses fish to execute preview commands, some of which
# are autoloaded fish functions so don't exist in other shells.
# Use --function so that it doesn't clobber SHELL outside this function.
set -f --export SHELL (command --search fish)
# If neither FZF_DEFAULT_OPTS nor FZF_DEFAULT_OPTS_FILE are set, then set some sane defaults.
# See https://github.com/junegunn/fzf#environment-variables
set --query FZF_DEFAULT_OPTS FZF_DEFAULT_OPTS_FILE
if test $status -eq 2
# cycle allows jumping between the first and last results, making scrolling faster
# layout=reverse lists results top to bottom, mimicking the familiar layouts of git log, history, and env
# border shows where the fzf window begins and ends
# height=90% leaves space to see the current command and some scrollback, maintaining context of work
# preview-window=wrap wraps long lines in the preview window, making reading easier
# marker=* makes the multi-select marker more distinguishable from the pointer (since both default to >)
set --export FZF_DEFAULT_OPTS '--cycle --layout=reverse --border --height=90% --preview-window=wrap --marker="*"'
end
fzf $argv
end
+10
View File
@@ -0,0 +1,10 @@
function _puffer_fish_expand_bang
if commandline --search-field >/dev/null
commandline --search-field --insert '!'
else if string match --quiet -- '!' "$(commandline --current-token)"
commandline --current-token $history[1]
else
commandline --insert '!'
end
end
+10
View File
@@ -0,0 +1,10 @@
function _puffer_fish_expand_buck
if commandline --search-field >/dev/null
commandline --search-field --insert '$'
else if string match --quiet '!' -- "$(commandline --current-token)"
commandline --current-token ''
commandline -f history-token-search-backward
else
commandline --insert '$'
end
end
+9
View File
@@ -0,0 +1,9 @@
function _puffer_fish_expand_dot
if commandline --search-field >/dev/null
commandline --search-field --insert '.'
else if string match --quiet --regex -- '^(\.\./)*\.\.$' "$(commandline --current-token)"
commandline --insert '/..'
else
commandline --insert '.'
end
end
+15
View File
@@ -0,0 +1,15 @@
function _puffer_fish_expand_star
if commandline --search-field >/dev/null
commandline --search-field --insert '*'
else if string match --quiet -- '!' "$(commandline --current-token)"
set -l prev_cmd $history[1]
set -l prev_args (string split ' ' $prev_cmd)
set -e prev_args[1] # remove command name
set -l arg_str (string join ' ' $prev_args)
# replace !* with all arguments
commandline --current-token ''
commandline --insert $arg_str
else
commandline --insert '*'
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function antigravity
# In fish, we pipe stderr using '2>|' to another command
command antigravity $argv 2>| grep -v "'app' is not in the list of known options" >&2
end
+8
View File
@@ -0,0 +1,8 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function bash --wraps=bash --description 'bash switches to bash shell'
set SHELL $(which bash) # Set shell to bash
command bash $argv # run bash
set SHELL $(which fish) # Reset shell
end
+59
View File
@@ -0,0 +1,59 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function bd-pull -d "Pull new Gitea issues into local Beads and link them"
if not set -q argv[1]; echo "Need repo owner/name"; return 1; end
if not set -q GITEA_TOKEN; echo "\$GITEA_TOKEN not set"; return 1; end
set -l REPO $argv[1]
set -l GITEA_URL "https://git.rootiest.dev"
set -l IMPORT_COUNT 0
echo (set_color blue)"📡 Checking Gitea: $REPO..."(set_color normal)
# 1. Fetch issues (using jq to get BOTH title and number)
set -l gitea_json (curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_URL/api/v1/repos/$REPO/issues?state=all")
# 2. Iterate through issues using their index/number
for row in (echo $gitea_json | jq -r '.[] | @base64')
set -l _decode (echo $row | base64 --decode)
set -l title (echo $_decode | jq -r '.title')
set -l number (echo $_decode | jq -r '.number')
# If it doesn't have [ID] brackets, it's a "Web-Original" issue
if not string match -qr "^\[.*\]" "$title"
echo (set_color yellow)" Linking Web Issue #$number: $title"(set_color normal)
# A. Create local Bead and capture the new ID
# This captures the output of bd create to find the ID it generated
set -l bd_output (bd create --title "$title")
set -l bid (echo $bd_output | string match -r "bd-[a-z0-9]+" | head -n 1)
if test -z "$bid"
# Fallback: find the latest ID in the jsonl if regex fails
set bid (tail -n 1 .beads/issues.jsonl | jq -r '.id')
end
# B. Update the Gitea Issue Title IMMEDIATELY via API
# This prevents the Gitea Action from creating a duplicate
set -l new_title "[$bid] $title"
curl -s -X PATCH -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"title\":\"$new_title\"}" \
"$GITEA_URL/api/v1/repos/$REPO/issues/$number" > /dev/null
set IMPORT_COUNT (math $IMPORT_COUNT + 1)
end
end
if test "$IMPORT_COUNT" -gt 0
echo (set_color green)"✅ Linked $IMPORT_COUNT issues."(set_color normal)
bd sync
# We don't even necessarily need to push now, because the titles match!
git add .beads/issues.jsonl
git commit -m "chore: sync local IDs for web issues"
git push
else
echo "⠿ No unlinked issues found."
end
end
+26
View File
@@ -0,0 +1,26 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Function to run a command in the background, detached from the terminal.
# This prevents the command from being terminated when the terminal is closed.
# All output (stdout and stderr) is discarded.
#
# Usage:
# bkg <command> [arguments...]
#
# Example:
# bkg firefox
# bkg code .
#
function bkg
# Check if a command was provided as an argument.
if test -z "$argv[1]"
echo "Usage: bkg <command> [arguments...]"
return 1
end
# Run the command using nohup to make it immune to hangups (like closing the terminal).
# Redirect both stdout and stderr to /dev/null to discard all output.
# The final ampersand (&) sends the entire process to the background.
nohup $argv &>/dev/null &
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function cat --wraps=bat --description 'alias cat=bat'
bat --plain --no-pager $argv
end
+21
View File
@@ -0,0 +1,21 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function cb --description 'Copy to clipboard'
if type -q wl-copy
if set -q argv[1]
echo $argv | wl-copy
else
wl-copy
end
else if type -q xclip
if set -q argv[1]
echo $argv | xclip -selection clipboard
else
xclip -selection clipboard
end
else
echo "Error: No clipboard provider found." >&2
return 1
end
end
+19
View File
@@ -0,0 +1,19 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function cffetch --wraps='clear;fastfetch' --description 'alias cffetch=clear;fastfetch'
clear
if which fastfetch >/dev/null 2>&1
if ls ~/.fastfetch.jsonc >/dev/null 2>&1
fastfetch --config ~/.fastfetch.jsonc $argv
else
fastfetch $argv
end
else
if which neofetch >/dev/null 2>&1
command neofetch $argv
else
echo "fetch not found"
end
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function cheat --description 'alias cheat=cheat -c'
command cheat -c $argv
end
+12
View File
@@ -0,0 +1,12 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function claude-resume
if test -f .claude_session
set -l sid (cat .claude_session)
claude --resume $sid
else
echo "No saved session found in this directory."
claude --resume # Fallback to the interactive picker
end
end
+16
View File
@@ -0,0 +1,16 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function cleanup -d "Log orphans to ~/.removed_orphans and remove them"
set -l orphans (pacman -Qtdq)
if test -n "$orphans"
echo "📝 Logging orphans to ~/.removed_orphans..."
echo "--- Removed on $(date) ---" >> ~/.removed_orphans
pacman -Qi $orphans | grep -E '^(Name|Version)' >> ~/.removed_orphans
echo "🧹 Removing orphans..."
sudo pacman -Rns $orphans
else
echo "✨ No orphans to clean up!"
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function clone --wraps=clone-in-kitty --description 'alias clone=clone-in-kitty'
clone-in-kitty $argv
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function clonet --wraps='clone-in-kitty --type=tab' --description 'alias clonet=clone-in-kitty --type=tab'
clone-in-kitty --type=tab $argv
end
+17
View File
@@ -0,0 +1,17 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function code-resume
if test -f .claude_session
set -l sid (cat .claude_session)
echo "Resuming Claude session: $sid"
claude --resume $sid
else if test -f .gemini_session
set -l sid (cat .gemini_session)
echo "Resuming Gemini session: $sid"
gemini --resume $sid
else
echo "No local AI session found. Opening picker..."
claude --resume # Default to Claude picker
end
end
+45
View File
@@ -0,0 +1,45 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function detach
set -l show_help 0
set -l args
for arg in $argv
switch $arg
case -h --help
set show_help 1
case --version
echo "detach 1.0.0"
return
case '-*' '--*'
echo "❌ Unknown option: $arg"
echo "Run 'detach --help' for usage."
return 1
case '*'
set args $args $arg
end
end
if test $show_help -eq 1
echo "Usage: detach [command...]"
echo "Runs a command in the background, fully detached from the terminal."
echo
echo "Options:"
echo " -h, --help Show this help message"
echo " --version Show version information"
echo
echo "Example:"
echo " detach firefox"
echo " detach rsync -a ./data remote:/backup/"
return
end
if test (count $args) -eq 0
echo "❌ No command provided."
echo "Run 'detach --help' for usage."
return 1
end
nohup $args >/dev/null 2>&1 &
end
+100
View File
@@ -0,0 +1,100 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function dng2avif --description 'Convert DNG raw to 10-bit HDR AVIF'
set -l options (fish_opt -s h -l help)
set -a options (fish_opt -s i -l input -r)
set -a options (fish_opt -s o -l output -r)
set -a options (fish_opt -s q -l quality -r)
set -a options (fish_opt -s s -l speed -r)
argparse $options -- $argv
or return
# Help Screen
if set -q _flag_help; or test (count $argv) -eq 0 -a -z "$_flag_input"
echo "Usage: dng2avif [options] [input.dng]"
echo ""
echo "Options:"
echo " -i, --input FILE Input DNG file"
echo " -o, --output FILE Output AVIF file (defaults to input name)"
echo " -q, --quality N Encoding quality 0-100 (default: 92)"
echo " -s, --speed N Encoder speed 0-10 (default: 3, 0=slowest)"
echo " -h, --help Show this help message"
return 0
end
# Handle Input Source
set -l input ""
if set -q _flag_input
set input $_flag_input
else
set input $argv[1]
end
if not test -f "$input"
echo (set_color red)"Error: File '$input' not found."(set_color normal)
return 1
end
# Configuration
set -l quality 92
if set -q _flag_quality
set quality $_flag_quality
end
set -l speed 3
if set -q _flag_speed
set speed $_flag_speed
end
set -l basename (string replace -r '\.dng$' '' $input)
set -l output "$basename.avif"
if set -q _flag_output
set output $_flag_output
end
set -l temp_pnm "$basename"_temp.pnm
# Dependency check
for cmd in magick ffmpeg avifenc exiftool
if not type -q $cmd
echo (set_color red)"Error: $cmd is not installed."(set_color normal)
return 1
end
end
# Step 1: Develop
echo -n (set_color blue)"Step 1/3: Developing... "(set_color normal)
magick "$input" -depth 16 pnm:"$temp_pnm" &>/dev/null
if test $status -ne 0
echo (set_color red)"FAILED"
return 1
end
echo (set_color green)"DONE"(set_color normal)
# Step 2: Encode
echo -n (set_color blue)"Step 2/3: Encoding (Q:$quality, S:$speed)... "(set_color normal)
ffmpeg -i "$temp_pnm" -vf "format=yuv444p10le" -f yuv4mpegpipe -strict -1 - 2>/dev/null | avifenc -q $quality -s $speed --stdin -d 10 -y 444 --cicp 12/1/1 -r f -o "$output" &>/dev/null
if test $status -ne 0
echo (set_color red)"FAILED"
rm -f "$temp_pnm"
return 1
end
echo (set_color green)"DONE"(set_color normal)
# Step 3: Metadata
echo -n (set_color blue)"Step 3/3: Syncing Metadata... "(set_color normal)
exiftool -tagsFromFile "$input" -all:all "$output" -overwrite_original &>/dev/null
if test $status -ne 0
echo (set_color red)"FAILED"
else
echo (set_color green)"DONE"(set_color normal)
end
# Final Cleanup
test -f "$temp_pnm"; and rm "$temp_pnm"
set -l size (stat -c '%s' "$output" | numfmt --to=iec)
echo (set_color yellow)"Complete: $output ($size)"(set_color normal)
end
+57
View File
@@ -0,0 +1,57 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function dockup --description 'Pull and restart docker compose containers'
# Define colors
set -l clr_error (set_color red)
set -l clr_info (set_color -b blue white)
set -l clr_success (set_color green)
set -l clr_off (set_color normal)
# Handle help flags
if contains -- -h $argv; or contains -- --help $argv
echo (set_color -o yellow)"Usage:"$clr_off" dockup [DIRECTORY]"
echo ""
echo (set_color -u)"Options:"$clr_off
echo " -h, --help Show this help message"
echo ""
echo (set_color -u)"Arguments:"$clr_off
echo " DIRECTORY Optional path to the compose project (defaults to current dir)"
return 0
end
# Handle directory navigation
if count $argv >/dev/null
set -l target_dir $argv[1]
if test -d $target_dir
pushd $target_dir >/dev/null
else
echo $clr_error"Error: Directory '$target_dir' not found."$clr_off
return 1
end
end
# Check for compose file
if not test -f docker-compose.yml -o -f docker-compose.yaml
echo $clr_error"Error: No docker-compose.yml found in "(pwd)$clr_off
if count $argv >/dev/null
popd >/dev/null
end
return 1
end
# Execution
echo $clr_info" UPDATING "$clr_off" Containers in "(set_color -o)(pwd)$clr_off"..."
if docker compose pull && docker compose up -d --remove-orphans
echo $clr_success"✔ Upgrade complete!"$clr_off
docker image prune -f
else
echo $clr_error"✘ Upgrade failed."$clr_off
end
# Cleanup directory state
if count $argv >/dev/null
popd >/dev/null
end
end
+13
View File
@@ -0,0 +1,13 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function docker
if test -n "$argv[1]"
switch $argv[1]
case ps
dops $argv[2..-1]
case '*'
command docker $argv[1..-1]
end
end
end
+63
View File
@@ -0,0 +1,63 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function du
set cmd ""
set args
# Parse override flags and gather remaining args
for arg in $argv
switch $arg
case --disk
set cmd duf
case --dir
set cmd dust
case --dua
set cmd dua
case '*'
set args $args $arg
end
end
# Autodetect if no override flag given
if test -z "$cmd"
if count $args
set first_arg $args[1]
if test -d "$first_arg" -o -f "$first_arg"
set cmd dust
else
set cmd duf
end
else
set cmd duf
end
end
# Tool execution with graceful fallback
switch $cmd
case duf
if type -q duf
duf $args
else
echo "(duf not found — falling back to du)"
command du -sh $args
end
case dust
if type -q dust
dust $args
else
echo "(dust not found — falling back to du)"
command du -sh $args
end
case dua
if type -q dua
dua $args
else
echo "(dua not found — falling back to du)"
command du -sh $args
end
case '*'
# This shouldn't happen, but just in case
command du -sh $args
end
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function dusize
du -sh (test -n "$argv[1]"; and echo $argv[1]; or echo .)
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function edit --wraps=nvim --description 'alias edit=nvim'
nvim $argv
end
+18
View File
@@ -0,0 +1,18 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function ffetch --wraps='fastfetch' --description 'alias ffetch=fastfetch'
if which fastfetch >/dev/null 2>&1
if ls ~/.fastfetch.jsonc >/dev/null 2>&1
fastfetch --config ~/.fastfetch.jsonc $argv
else
fastfetch $argv
end
else
if which neofetch >/dev/null 2>&1
command neofetch $argv
else
echo "fetch not found"
end
end
end
+22
View File
@@ -0,0 +1,22 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function fish_right_prompt
# 1. Docker Context in Blue
set -l docker_ctx (docker context show 2>/dev/null)
if test -n "$docker_ctx"; and test "$docker_ctx" != default
set_color blue
echo -n "󰡨 $docker_ctx "
set_color normal
end
# 2. Timestamp Logic with Fallback
set_color brblack
if type -q __bobthefish_timestamp
__bobthefish_timestamp
else
# Manual fallback format: Wed Feb 11 15:04:28 2026
date "+%a %b %d %H:%M:%S %Y"
end
set_color normal
end
+254
View File
@@ -0,0 +1,254 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function fisher --argument-names cmd --description "A plugin manager for Fish"
set --query fisher_path || set --local fisher_path $__fish_config_dir
set --local fisher_version 4.4.8
set --local fish_plugins $__fish_config_dir/fish_plugins
switch "$cmd"
case -v --version
echo "fisher, version $fisher_version"
case "" -h --help
echo "Usage: fisher install <plugins...> Install plugins"
echo " fisher remove <plugins...> Remove installed plugins"
echo " fisher uninstall <plugins...> Remove installed plugins (alias)"
echo " fisher update <plugins...> Update installed plugins"
echo " fisher update Update all installed plugins"
echo " fisher list [<regex>] List installed plugins matching regex"
echo "Options:"
echo " -v, --version Print version"
echo " -h, --help Print this help message"
echo "Variables:"
echo " \$fisher_path Plugin installation path. Default: $__fish_config_dir" | string replace --regex -- $HOME \~
case ls list
string match --entire --regex -- "$argv[2]" $_fisher_plugins
case install update remove uninstall
isatty || read --local --null --array stdin && set --append argv $stdin
test "$cmd" = uninstall && set cmd remove
set --local install_plugins
set --local update_plugins
set --local remove_plugins
set --local arg_plugins $argv[2..-1]
set --local old_plugins $_fisher_plugins
set --local new_plugins
test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins | string replace -- \~ ~)
if ! set --query argv[2]
if test "$cmd" != update
echo "fisher: Not enough arguments for command: \"$cmd\"" >&2 && return 1
else if ! set --query file_plugins
echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1
end
set arg_plugins $file_plugins
else if test "$cmd" = install && ! set --query old_plugins[1]
set --append arg_plugins $file_plugins
end
for plugin in $arg_plugins
set plugin (test -e "$plugin" && realpath $plugin || string lower -- $plugin)
contains -- "$plugin" $new_plugins || set --append new_plugins $plugin
end
if set --query argv[2]
for plugin in $new_plugins
if contains -- "$plugin" $old_plugins
test "$cmd" = remove &&
set --append remove_plugins $plugin ||
set --append update_plugins $plugin
else if test "$cmd" = install
set --append install_plugins $plugin
else
echo "fisher: Plugin not installed: \"$plugin\"" >&2 && return 1
end
end
else
for plugin in $new_plugins
contains -- "$plugin" $old_plugins &&
set --append update_plugins $plugin ||
set --append install_plugins $plugin
end
for plugin in $old_plugins
contains -- "$plugin" $new_plugins || set --append remove_plugins $plugin
end
end
set --local pid_list
set --local source_plugins
set --local fetch_plugins $update_plugins $install_plugins
set --local fish_path (status fish-path)
echo (set_color --bold)fisher $cmd version $fisher_version(set_color normal)
for plugin in $fetch_plugins
set --local source (command mktemp -d)
set --append source_plugins $source
command mkdir -p $source/{completions,conf.d,themes,functions}
$fish_path --command "
if test -e $plugin
command cp -Rf $plugin/* $source
else
set resp (command mktemp)
set temp (command mktemp -d)
set repo (string split -- \@ $plugin) || set repo[2] HEAD
if set path (string replace --regex -- '^(https://)?gitlab.com/' '' \$repo[1])
set name (string split -- / \$path)[-1]
set url https://gitlab.com/\$path/-/archive/\$repo[2]/\$name-\$repo[2].tar.gz
else
set url https://api.github.com/repos/\$repo[1]/tarball/\$repo[2]
end
echo Fetching (set_color --underline)\$url(set_color normal)
set http (command curl -q --silent -L -o \$resp -w %{http_code} \$url)
if test \"\$http\" = 200 && command tar -xzC \$temp -f \$resp 2>/dev/null
command cp -Rf \$temp/*/* $source
else if test \"\$http\" = 403
echo fisher: GitHub API rate limit exceeded \(HTTP 403\) >&2
command rm -rf $source
else
echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2
command rm -rf $source
end
command rm -rf \$temp
end
set files $source/* && string match --quiet --regex -- .+\.fish\\\$ \$files
" &
set --append pid_list (jobs --last --pid)
end
wait $pid_list 2>/dev/null
for plugin in $fetch_plugins
if set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] && test ! -e $source
if set --local index (contains --index -- "$plugin" $install_plugins)
set --erase install_plugins[$index]
else
set --erase update_plugins[(contains --index -- "$plugin" $update_plugins)]
end
end
end
for plugin in $update_plugins $remove_plugins
if set --local index (contains --index -- "$plugin" $_fisher_plugins)
set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
if contains -- "$plugin" $remove_plugins
for name in (string replace --filter --regex -- '.+/conf\.d/([^/]+)\.fish$' '$1' $$plugin_files_var)
emit {$name}_uninstall
end
printf "%s\n" Removing\ (set_color red --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~
set --erase _fisher_plugins[$index]
end
command rm -rf (string replace -- \~ ~ $$plugin_files_var)
functions --erase (string replace --filter --regex -- '.+/functions/([^/]+)\.fish$' '$1' $$plugin_files_var)
for name in (string replace --filter --regex -- '.+/completions/([^/]+)\.fish$' '$1' $$plugin_files_var)
complete --erase --command $name
end
set --erase $plugin_files_var
end
end
if set --query update_plugins[1] || set --query install_plugins[1]
command mkdir -p $fisher_path/{functions,themes,conf.d,completions}
end
for plugin in $update_plugins $install_plugins
set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)]
set --local files $source/{functions,themes,conf.d,completions}/*
if set --local index (contains --index -- $plugin $install_plugins)
set --local user_files $fisher_path/{functions,themes,conf.d,completions}/*
set --local conflict_files
for file in (string replace -- $source/ $fisher_path/ $files)
contains -- $file $user_files && set --append conflict_files $file
end
if set --query conflict_files[1] && set --erase install_plugins[$index]
echo -s "fisher: Cannot install \"$plugin\": please remove or move conflicting files first:" \n" "$conflict_files >&2
continue
end
end
for file in (string replace -- $source/ "" $files)
command cp -RLf $source/$file $fisher_path/$file
end
set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
set --query files[1] && set --universal $plugin_files_var (string replace -- $source $fisher_path $files | string replace -- ~ \~)
contains -- $plugin $_fisher_plugins || set --universal --append _fisher_plugins $plugin
contains -- $plugin $install_plugins && set --local event install || set --local event update
printf "%s\n" Installing\ (set_color --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~
for file in (string match --regex -- '.+/[^/]+\.fish$' $$plugin_files_var | string replace -- \~ ~)
source $file
if set --local name (string replace --regex -- '.+conf\.d/([^/]+)\.fish$' '$1' $file)
emit {$name}_$event
end
end
end
command rm -rf $source_plugins
if set --query _fisher_plugins[1]
set --local commit_plugins
for plugin in $file_plugins
contains -- (string lower -- $plugin) (string lower -- $_fisher_plugins) && set --append commit_plugins $plugin
end
for plugin in $_fisher_plugins
contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin
end
string replace --regex -- $HOME \~ $commit_plugins >$fish_plugins
else
set --erase _fisher_plugins
command rm -f $fish_plugins
end
set --local total (count $install_plugins) (count $update_plugins) (count $remove_plugins)
test "$total" != "0 0 0" && echo (string join ", " (
test $total[1] = 0 || echo "Installed $total[1]") (
test $total[2] = 0 || echo "Updated $total[2]") (
test $total[3] = 0 || echo "Removed $total[3]")
) plugin/s
case \*
echo "fisher: Unknown command: \"$cmd\"" >&2 && return 1
end
end
if ! set --query _fisher_upgraded_to_4_4
set --universal _fisher_upgraded_to_4_4
if functions --query _fisher_list
set --query XDG_DATA_HOME[1] || set --local XDG_DATA_HOME ~/.local/share
command rm -rf $XDG_DATA_HOME/fisher
functions --erase _fisher_{list,plugin_parse}
fisher update >/dev/null 2>/dev/null
else
for var in (set --names | string match --entire --regex '^_fisher_.+_files$')
set $var (string replace -- ~ \~ $$var)
end
functions --erase _fisher_fish_postexec
end
end
+49
View File
@@ -0,0 +1,49 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Always installs bindings for insert and default mode for simplicity and b/c it has almost no side-effect
# https://gitter.im/fish-shell/fish-shell?at=60a55915ee77a74d685fa6b1
function fzf_configure_bindings --description "Installs the default key bindings for fzf.fish with user overrides passed as options."
# no need to install bindings if not in interactive mode or running tests
status is-interactive || test "$CI" = true; or return
set -f options_spec h/help 'directory=?' 'git_log=?' 'git_status=?' 'history=?' 'processes=?' 'variables=?'
argparse --max-args=0 --ignore-unknown $options_spec -- $argv 2>/dev/null
if test $status -ne 0
echo "Invalid option or a positional argument was provided." >&2
_fzf_configure_bindings_help
return 22
else if set --query _flag_help
_fzf_configure_bindings_help
return
else
# Initialize with default key sequences and then override or disable them based on flags
# index 1 = directory, 2 = git_log, 3 = git_status, 4 = history, 5 = processes, 6 = variables
set -f key_sequences ctrl-alt-f ctrl-alt-l ctrl-alt-s ctrl-r ctrl-alt-p ctrl-v
set --query _flag_directory && set key_sequences[1] "$_flag_directory"
set --query _flag_git_log && set key_sequences[2] "$_flag_git_log"
set --query _flag_git_status && set key_sequences[3] "$_flag_git_status"
set --query _flag_history && set key_sequences[4] "$_flag_history"
set --query _flag_processes && set key_sequences[5] "$_flag_processes"
set --query _flag_variables && set key_sequences[6] "$_flag_variables"
# If fzf bindings already exists, uninstall it first for a clean slate
if functions --query _fzf_uninstall_bindings
_fzf_uninstall_bindings
end
for mode in default insert
test -n $key_sequences[1] && bind --mode $mode $key_sequences[1] _fzf_search_directory
test -n $key_sequences[2] && bind --mode $mode $key_sequences[2] _fzf_search_git_log
test -n $key_sequences[3] && bind --mode $mode $key_sequences[3] _fzf_search_git_status
test -n $key_sequences[4] && bind --mode $mode $key_sequences[4] _fzf_search_history
test -n $key_sequences[5] && bind --mode $mode $key_sequences[5] _fzf_search_processes
test -n $key_sequences[6] && bind --mode $mode $key_sequences[6] "$_fzf_search_vars_command"
end
function _fzf_uninstall_bindings --inherit-variable key_sequences
bind --erase -- $key_sequences
bind --erase --mode insert -- $key_sequences
end
end
end
+13
View File
@@ -0,0 +1,13 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function gemini-resume
if test -f .gemini_session
set -l sid (cat .gemini_session)
# Use --resume (or -r) to jump back in
gemini --resume $sid
else
# Fallback to the interactive session browser
gemini --resume
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function get-color --wraps='/home/rootiest/scripts/hex2rgb.sh "$(wl-colorpicker-plasma)"' --description 'alias get-color=/home/rootiest/scripts/hex2rgb.sh "$(wl-colorpicker-plasma)"'
/home/rootiest/scripts/hex2rgb.sh "$(wl-colorpicker-plasma)" $argv
end
+9
View File
@@ -0,0 +1,9 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function gip -d "Show all public IP addresses"
echo -n "IPv4: "
curl -4 -s --max-time 2 https://icanhazip.com || echo "Not detected"
echo -n "IPv6: "
curl -6 -s --max-time 2 https://icanhazip.com || echo "Not detected"
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function gip4 -d "Get public IPv4 address"
curl -4 -s https://icanhazip.com
end
+14
View File
@@ -0,0 +1,14 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function gip6 -d "Get public IPv6 address"
# Use -6 to force IPv6 and --fail to catch network errors
set -l ip (curl -6 -s --fail https://icanhazip.com 2>/dev/null)
if test $status -eq 0
echo $ip
else
echo "❌ IPv6 is currently unavailable or not supported on this network."
return 1
end
end
+56
View File
@@ -0,0 +1,56 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function git-clean --description 'Sync main, prune remotes, and delete orphaned branches'
set -l options h/help f/force
argparse $options -- $argv
or return
if set -q _flag_help
echo (set_color --bold blue)"Usage: "(set_color normal)"git-clean [OPTIONS]"
echo
echo "Steps taken:"
echo " 1. Fetches and prunes to find deleted remote branches."
echo " 2. Switches to main if you are on an orphaned branch."
echo " 3. Pulls the latest changes from the remote."
echo " 4. Deletes local orphaned branches."
return 0
end
# 1. Fetch and prune (Quietly)
echo (set_color blue)"Fetching and pruning remote tracking..."(set_color normal)
git fetch --prune --quiet
# 2. Identify orphaned branches and current branch
set -l gone_branches (git branch -vv | awk '/: gone\]/ {gsub(/\*/, ""); print $1}')
set -l current_branch (git branch --show-current)
if test -n "$gone_branches"
# 3. Move to safety if needed (Quietly)
if contains "$current_branch" $gone_branches
echo (set_color yellow)"Current branch '$current_branch' was deleted on remote. Moving to main..."(set_color normal)
# Redirecting output to /dev/null to hide the 'Switched to branch' message
git checkout main >/dev/null 2>&1; or git checkout master >/dev/null 2>&1
end
end
# 4. Update the current branch (Quietly)
echo (set_color blue)"Updating current branch..."(set_color normal)
git pull --quiet
# 5. Final cleanup
if test -n "$gone_branches"
set -l delete_flag -d
if set -q _flag_force
set -l delete_flag -D
end
echo (set_color red)"Deleting orphaned local branches ($delete_flag):"(set_color normal)
for branch in $gone_branches
# We keep this output so you can see confirmation of which hashes were deleted
git branch $delete_flag $branch
end
else
echo (set_color green)"Everything is tidy. No orphaned branches found."(set_color normal)
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function gitui --description 'alias gitui=gitui -t mocha.ron'
command gitui -t frappe.ron $argv
end
+14
View File
@@ -0,0 +1,14 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function hist -d "Search fish history and put it in the prompt"
set -l selected (history | fzf --reverse --height 40% --with-nth 3..)
if test -n "$selected"
# Strip the timestamp for the final output
set -l command (echo $selected | string replace -r '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} ' '')
echo $command | wl-copy 2>/dev/null
commandline -r $command
end
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function l --wraps='lsd --almost-all --long' --description 'alias l=lsd --almost-all --long'
if which lsd >/dev/null 2>&1
lsd --almost-all --long --git --header --hyperlink=auto $argv
else
command ls --color=auto --almost-all -l $argv
end
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function lS --wraps='lsd --oneline --classic' --description 'alias lS=lsd --oneline --classic'
if which lsd >/dev/null 2>&1
lsd --oneline --classic $argv
else
command ls $argv
end
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function less --wraps=most --description 'alias less=most'
if which most >/dev/null 2>&1
most $argv
else
command less $argv
end
end
+22
View File
@@ -0,0 +1,22 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function limine-edit --description 'Safely edit and re-verify Limine configuration'
# 1. Open the config with sudoedit
sudoedit /boot/limine.conf
# 2. Re-enroll the config hash (This prevents the Checksum Panic)
echo "Enrolling Limine config..."
sudo limine-enroll-config
# 3. Run the CachyOS boot hooks (Updates snapshots/kernel links)
echo "Running CachyOS boot hooks..."
sudo limine-mkinitcpio
# 4. Sign any unsigned files tracked by sbctl
# 'sbctl sign-all' will re-apply signatures to everything in the database
echo "Verifying Secure Boot signatures..."
sudo sbctl sign-all
echo "✅ Limine config updated and verified. Ready for reboot."
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function llm --wraps='lsd --timesort --long' --description 'alias llm=lsd --timesort --long'
if which lsd >/dev/null 2>&1
lsd --timesort --long --git --header --hyperlink=auto $argv
else
command ls color=auto -l $argv
end
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function lock
loginctl lock-session
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function ls --wraps=lsd --wraps='lsd --hyperlink=auto' --description 'alias ls=lsd'
if which lsd >/dev/null 2>&1
lsd --hyperlink=auto $argv
else
command ls --color=auto $argv
end
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function lstree --wraps='ls --tree' --description 'alias lstree=ls --tree'
if which lsd >/dev/null 2>&1
lsd --tree --hyperlink=auto $argv
else
command ls --color=auto -R $argv
end
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function lt --wraps='lsd --tree --depth=2' --description 'alias lt=lsd --tree --depth=2'
if which lsdq >/dev/null 2>&1
lsd --tree --depth=2 --hyperlink=auto $argv
else
command ls --color=auto -R $argv
end
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function ltr --wraps='lsd -ltr' --description 'alias ltr=lsd -ltr'
lsd -ltr $argv
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function mkdir
if status is-interactive
command mkdir -p $argv
else
command mkdir $argv
end
end
+29
View File
@@ -0,0 +1,29 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function monitors
# 0. Capture the ID of the pane we are starting in (Top-Left)
set local_id $KITTY_WINDOW_ID
# Define remote commands
set racknerd_cmd "ssh -t racknerd btop"
set server_cmd "ssh -t rootiest-server btop"
set mini_cmd "ssh -t racknerd-mini btop"
# 1. Split vertically from Top-Left to create Top-Right (RackNerd)
set rack_id (kitty @ launch --location=vsplit --cwd=current sh -c "$racknerd_cmd")
# 2. Return focus to Top-Left and split horizontally to create Bottom-Left (Server)
kitty @ focus-window --match "id:$local_id"
set server_id (kitty @ launch --location=hsplit --cwd=current sh -c "$server_cmd")
# 3. Focus Top-Right (RackNerd) and split horizontally to create Bottom-Right (Mini)
kitty @ focus-window --match "id:$rack_id"
set mini_id (kitty @ launch --location=hsplit --cwd=current sh -c "$mini_cmd")
# 4. Final focus back to the Top-Left to launch local btop
kitty @ focus-window --match "id:$local_id"
# Run local btop
btop
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function nlazyup --wraps='nvim --headless "+Lazy! sync" +qa' --description 'alias nlazyup=nvim --headless "+Lazy! sync" +qa'
nvim --headless "+Lazy! sync" +qa $argv
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function nnotes --wraps='cd~/vaults/Rootiest Notes/;nvim' --wraps='cd ~/vaults/Rootiest Notes/;nvim' --wraps='cd ~/vaults/Rootiest\\ Notes/;nvim' --description 'alias nnotes=cd ~/vaults/Rootiest\\ Notes/;nvim'
cd ~/vaults/Rootiest\ Notes/;nvim $argv
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function nvimup --wraps='nvim "+UpdateNeovim"' --wraps='NVIMUPDATER_HEADLESS=1 nvim "+UpdateNeovim"' --description 'alias nvimup=NVIMUPDATER_HEADLESS=1 nvim "+UpdateNeovim"'
NVIMUPDATER_HEADLESS=1 nvim "+UpdateNeovim" $argv
end
+33
View File
@@ -0,0 +1,33 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function p --description 'Put from clipboard'
# Check for help flag
if contains -- -h $argv; or contains -- --help $argv
echo "Usage: p [OPTIONS]"
echo ""
echo "Description:"
echo " Pastes content from the system clipboard to stdout."
echo ""
echo "Examples:"
echo " p Print clipboard content"
echo " p > file.txt Save clipboard to a file"
echo " p | grep 'foo' Pipe clipboard content to another command"
echo " cat (p) Use clipboard content as a filename for cat"
return 0
end
# Determine the clipboard provider
set -l paste_cmd
if type -q wl-paste
set paste_cmd wl-paste
else if type -q xclip
set paste_cmd xclip -selection clipboard -o
else
echo "Error: No clipboard provider (wl-paste or xclip) found." >&2
return 1
end
# Execute the paste command with any provided arguments
$paste_cmd $argv
end
+18
View File
@@ -0,0 +1,18 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
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 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
else
echo "No packages selected for removal."
end
end
+13
View File
@@ -0,0 +1,13 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function paste --description 'Paste from clipboard'
if type -q wl-paste
wl-paste $argv
else if type -q xclip
xclip -selection clipboard -o $argv
else
echo "Error: Neither wl-paste nor xclip found." >&2
return 1
end
end
+16
View File
@@ -0,0 +1,16 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function ping --description 'prettyping with default nolegend'
if command -q prettyping
# Check if the user specifically asked for the legend
if contains -- --legend $argv
command prettyping $argv
else
command prettyping --nolegend $argv
end
else
# Fallback to standard ping if prettyping isn't installed
command ping $argv
end
end
+10
View File
@@ -0,0 +1,10 @@
# 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
paru -S $argv
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function ports -d "Show active network listeners"
sudo lsof -iTCP -sTCP:LISTEN -P -n
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function push-vim --wraps=/home/rootiest/projects/propogate-vim/send.sh --description 'alias push-vim=/home/rootiest/projects/propogate-vim/send.sh'
/home/rootiest/projects/propogate-vim/send.sh $argv
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function qr -d "Generate a QR code from text or pipe"
if set -q argv[1]
echo $argv | qrencode -t utf8
else
cat | qrencode -t utf8
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function rawfish --wraps='env NO_TMUX=1 fish' --description 'alias rawfish=env NO_TMUX=1 fish'
env NO_TMUX=1 fish $argv
end
+51
View File
@@ -0,0 +1,51 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function replay --description "Run Bash commands replaying changes in Fish"
switch "$argv"
case -v --version
echo "replay, version 1.2.1"
case "" -h --help
echo "Usage: replay <commands> Run Bash commands replaying changes in Fish"
echo "Options:"
echo " -v or --version Print version"
echo " -h or --help Print this help message"
case \*
set --local env
set --local sep @$fish_pid(random)(command date +%s)
set --local argv $argv[1] (string escape -- $argv[2..-1])
set --local out (command bash -c "
$argv
status=\$?
[ \$status -gt 0 ] && exit \$status
command compgen -e | command awk -v sep=$sep '{
gsub(/\n/, \"\\\n\", ENVIRON[\$0])
print \$0 sep ENVIRON[\$0]
}' && alias
") || return
string replace --all -- \\n \n (
for line in $out
if string split -- $sep $line | read --local --line name value
set --append env $name
contains -- $name SHLVL PS1 BASH_FUNC || test "$$name" = "$value" && continue
if test "$name" = PATH
echo set PATH (string split -- : $value | string replace --regex --all -- '(^.*$)' '"$1"')
else if test "$name" = PWD
echo builtin cd "\"$value\""
else
echo "set --global --export $name "(string escape -- $value)
end
else
set --query env[1] && string match --entire --regex -- "^alias" $line || echo "echo \"$line\""
end
end | string replace --all -- \$ \\\$
for name in (set --export --names)
contains -- $name $env || echo "set --erase $name"
end
) | source
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function rg --description 'alias rg=rg --hyperlink-format=kitty'
command rg --hyperlink-format=kitty $argv
end
+79
View File
@@ -0,0 +1,79 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function rm --description 'Ultimate rm: trash, list, empty, and secure-erase'
# 1. No arguments: Show the Trash contents (Quick view)
if not set -q argv[1]
if type -q trash
echo "🗑️ Current Trash Contents:"
trash list
else
command rm
end
return
end
# 2. Flag: Empty the Trash (-e / --empty)
# We check if the FIRST argument is -e or --empty
if string match -rq -- '^-e$|^--empty$' -- $argv[1]
if type -q trash
# Check if there are arguments after -e (like --within 2weeks)
if set -q argv[2]
# Pass everything after the first argument to trash empty
trash empty $argv[2..-1]
else
# Default behavior if no extra args provided
echo "🧹 Emptying all trash..."
trash empty --all
end
else
echo "Error: 'trash' command not found."
end
return
end
# 3. Flag: Secure Delete (-S / --secure)
if contains -- -S $argv; or contains -- --secure $argv
set -l clean_args
for arg in $argv
if not string match -rq -- '^-S$|^--secure$|^-r$|^-R$|^--recursive$' -- "$arg"
set -a clean_args $arg
end
end
echo "🛡️ Permanent delete + SSD Zeroing..."
command rm -rf $clean_args
fstrim --all 2>/dev/null &
return
end
# 4. Logic: Use 'trash' for simple paths OR recursive flags (-r, -R)
# Bail to real rm if ANY other flags (like -f) are detected
set -l is_safe_for_trash true
for arg in $argv
if string match -q -- "-*" $arg
if not string match -rq -- '^-r$|^-R$|^--recursive$' -- "$arg"
set is_safe_for_trash false
break
end
end
end
if test "$is_safe_for_trash" = true
set -l trash_paths
for arg in $argv
if not string match -rq -- '^-r$|^-R$|^--recursive$' -- "$arg"
set -a trash_paths $arg
end
end
if type -q trash; and set -q trash_paths[1]
trash put $trash_paths
# Refresh Dolphin view
dbus-send --type=signal /OrgKdeKDirNotify org.kde.KDirNotify.FilesChanged stringArray:"trash:/" >/dev/null 2>&1 &
return
end
end
# 5. Fallback: Standard rm for everything else (including -rf)
command rm $argv
end
+31
View File
@@ -0,0 +1,31 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
#!/usr/bin/env fish
# 1. Read input and extract session ID
set -l input (cat)
set -l sid (echo $input | python3 -c "import sys,json; print(json.load(sys.stdin).get('session_id', ''))")
set -l session_file ".claude_session"
if test -n "$sid"
# 2. Save the session ID locally
echo "$sid" >$session_file
# 3. Smart .gitignore check
# We check if git even knows about this file.
# If 'git check-ignore' returns 1, it means the file is NOT ignored.
if git rev-parse --is-inside-work-tree >/dev/null 2>&1
if not git check-ignore -q $session_file
# Append the filename to .gitignore
echo -e "\n# AI Session IDs\n$session_file" >>.gitignore
echo "Added $session_file to .gitignore"
end
end
# 4. Update universal variable
set -U LAST_CLAUDE_SESSION "$sid"
end
# MANDATORY: Every hook must output valid JSON
echo '{}'
+32
View File
@@ -0,0 +1,32 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
#!/usr/bin/env fish
# 1. Read the JSON from stdin
set -l input (cat)
# 2. Extract session_id using Python
set -l sid (echo $input | python3 -c "import sys,json; print(json.load(sys.stdin).get('session_id', ''))")
set -l session_file ".gemini_session"
if test -n "$sid"
# 3. Save the session ID locally
echo "$sid" >$session_file
# 4. Smart .gitignore check
# We only attempt this if we are inside a Git repository
if git rev-parse --is-inside-work-tree >/dev/null 2>&1
# If 'git check-ignore' fails, it means the file is NOT currently ignored
if not git check-ignore -q $session_file
# Append a labeled entry to .gitignore
echo -e "\n# AI Session IDs\n$session_file" >>.gitignore
end
end
# 5. Update universal variable for cross-terminal access
set -U LAST_GEMINI_SESSION "$sid"
end
# MANDATORY: Every hook must output valid JSON or an empty object
echo '{}'
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function sbver --wraps='~/sbctl-verify-clean.sh' --description 'alias sbver=~/sbctl-verify-clean.sh'
~/sbctl-verify-clean.sh $argv
end
+12
View File
@@ -0,0 +1,12 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function screensleep --description 'Turn off the display using KDE PowerDevil'
# Optional: 1-second delay to ensure no keystrokes wake it immediately
sleep 1
busctl --user call \
org.kde.kglobalaccel \
/component/org_kde_powerdevil \
org.kde.kglobalaccel.Component \
invokeShortcut s "Turn Off Screen"
end
+10
View File
@@ -0,0 +1,10 @@
# 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
paru $argv
end
+36
View File
@@ -0,0 +1,36 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function spark --description Sparklines
argparse --ignore-unknown --name=spark v/version h/help m/min= M/max= -- $argv || return
if set --query _flag_version[1]
echo "spark, version 1.1.0"
else if set --query _flag_help[1]
echo "Usage: spark <numbers ...>"
echo " stdin | spark"
echo "Options:"
echo " --min=<number> Minimum range"
echo " --max=<number> Maximum range"
echo " -v or --version Print version"
echo " -h or --help Print this help message"
echo "Examples:"
echo " spark 1 1 2 5 14 42"
echo " seq 64 | sort --random-sort | spark"
else if set --query argv[1]
printf "%s\n" $argv | spark --min="$_flag_min" --max="$_flag_max"
else
command awk -v min="$_flag_min" -v max="$_flag_max" '
{
m = min == "" ? m == "" ? $0 : m > $0 ? $0 : m : min
M = max == "" ? M == "" ? $0 : M < $0 ? $0 : M : max
nums[NR] = $0
}
END {
n = split("▁ ▂ ▃ ▄ ▅ ▆ ▇ █", sparks, " ") - 1
while (++i <= NR)
printf("%s", sparks[(M == m) ? 3 : sprintf("%.f", (1 + (nums[i] - m) * n / (M - m)))])
}
' && echo
end
end
+22
View File
@@ -0,0 +1,22 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function split --description 'Run a command in a new Kitty split'
set -l location hsplit
switch $argv[1]
case -h --horizontal
set location hsplit
set -e argv[1]
case -v --vertical
set location vsplit
set -e argv[1]
end
if test (count $argv) -gt 0
# Set HIDE_GREETING=1 before fish starts
kitty @ launch --location=$location --cwd=$PWD env HIDE_GREETING=1 fish -c "$argv; exec fish"
else
kitty @ launch --location=$location --cwd=$PWD env HIDE_GREETING=1 fish -c "exec fish"
end
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function spwin --wraps='~/.config/kitty/spawn-window.sh' --description 'alias spwin=~/.config/kitty/spawn-window.sh'
~/.config/kitty/spawn-window.sh $argv
end
+10
View File
@@ -0,0 +1,10 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function ssh --description 'Alias ssh to kitten ssh when using Kitty terminal'
if test "$TERM" = xterm-kitty
kitten ssh $argv
else
command ssh $argv
end
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function steam-dl --description 'Run Steam while inhibiting system sleep'
echo "Inhibiting sleep while Steam downloads..."
systemd-inhibit --why="Active Download" --who="User" --what=idle:sleep steam
end
+49
View File
@@ -0,0 +1,49 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function superpowers --description "Toggle superpowers extension for Gemini and Claude"
set -l scope_gemini workspace
set -l scope_claude project
set -l mode ""
set -l help_text "
Usage: superpowers [on|off] [options]
Commands:
on Enable superpowers for Gemini and Claude
off Disable superpowers for Gemini and Claude
Options:
-g, --global Apply settings to the user/global scope
-h, --help Show this help message
"
# Parse arguments
for arg in $argv
switch $arg
case on
set mode enable
case off
set mode disable
case -g --global
set scope_gemini user
set scope_claude user
case -h --help
echo $help_text
return 0
end
end
# Handle no arguments or invalid mode
if test -z "$mode"
echo $help_text
return 1
end
echo "Setting superpowers to: $mode (Scope: Gemini=$scope_gemini, Claude=$scope_claude)..."
# Execute Gemini command
gemini extensions $mode superpowers --scope $scope_gemini
# Execute Claude command
claude plugins $mode superpowers --scope $scope_claude
end
+37
View File
@@ -0,0 +1,37 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function swapstat --description "View colorized zRAM and swappiness status"
set -l swappiness (sysctl -n vm.swappiness)
set -l zdata (zramctl --bytes --noheadings --output DATA,TOTAL /dev/zram0 2>/dev/null)
echo (set_color --bold blue)"── Memory & zRAM Report ──"(set_color normal)
# Kernel & Compression Stats
if test -n "$zdata"
set -l raw (echo $zdata | awk '{print $1}')
set -l compressed (echo $zdata | awk '{print $2}')
if test "$compressed" -gt 0
set -l ratio (math -s2 "$raw / $compressed")
echo (set_color yellow)"Compression Ratio: "(set_color normal)"$ratio:1"
end
end
echo (set_color yellow)"Kernel Swappiness: "(set_color normal)"$swappiness"
echo ""
# Colorized zRAM Table
# Colors the header green and the device path (/dev/...) cyan
echo (set_color --bold --underline magenta)"zRAM Device Details"(set_color normal)
zramctl --output NAME,ALGORITHM,DISKSIZE,DATA,COMPR,TOTAL,STREAMS | sed \
-e "1s/.*/$(set_color --bold green)&$(set_color normal)/" \
-e "s|/dev/zram[0-9]|$(set_color cyan)&$(set_color normal)|"
echo ""
# Colorized Swapon Table
# Colors the header green and the device path cyan
echo (set_color --bold --underline magenta)"Active Swap Priority"(set_color normal)
swapon --show | sed \
-e "1s/.*/$(set_color --bold green)&$(set_color normal)/" \
-e "s|/dev/[^ ]*|$(set_color cyan)&$(set_color normal)|"
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function tab --wraps='konsole --new-tab --workdir "$cdto"' --description 'alias tab=konsole --new-tab --workdir "$cdto"'
konsole --new-tab --workdir "$cdto" $argv
end
+6
View File
@@ -0,0 +1,6 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function tailart --wraps='tailscale file get ~/Pictures/Art/' --description 'alias tailart=tailscale file get ~/Pictures/Art/'
tailscale file get ~/Pictures/Art/ $argv
end
+17
View File
@@ -0,0 +1,17 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function tmux-clean --description 'Kill all tmux sessions except the current one'
# Get a list of all session names that are NOT currently attached
set sessions (tmux list-sessions -F '#{session_name} #{session_attached}' | string match -rv ' 1$' | string split -f1 ' ')
if test -n "$sessions"
for session in $sessions
echo "Stopping session: $session"
tmux kill-session -t "$session"
end
echo "Clean-up complete."
else
echo "No detached sessions to clean."
end
end
+14
View File
@@ -0,0 +1,14 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function top --wraps=btop --description 'Use btop as a modern replacement for top'
# 1. Check if btop is actually installed
if type -q btop
# 2. Launch btop with any arguments passed
btop $argv
else
# 3. Fallback to the original system top if btop is missing
echo "btop not found, falling back to classic top..."
command top $argv
end
end
+9
View File
@@ -0,0 +1,9 @@
# 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
paru -Syu --noconfirm
end
+7
View File
@@ -0,0 +1,7 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function view --wraps='neovim -R' --wraps='nvim -R' --description 'alias view=nvim -R'
nvim -R $argv
end
+15
View File
@@ -0,0 +1,15 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function wake-lock --description 'Run a command while inhibiting system sleep'
if test (count $argv) -eq 0
echo "Usage: wake-lock [command] [args...]"
return 1
end
echo "Running '$argv' with sleep inhibition active..."
# --what=idle:sleep prevents the system from auto-sleeping or being suspended
# --who identifies your function in 'systemd-inhibit --list'
systemd-inhibit --why="Manual task inhibition" --who="wake-lock" --what=idle:sleep $argv
end

Some files were not shown because too many files have changed in this diff Show More