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:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
function lock
|
||||
loginctl lock-session
|
||||
end
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Executable
+31
@@ -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 '{}'
|
||||
Executable
+32
@@ -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 '{}'
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user