update shell config

This commit is contained in:
2026-07-27 02:53:24 +02:00
parent 678cfb76ba
commit 21e902bd61
24 changed files with 300 additions and 634 deletions
@@ -1,13 +1,4 @@
*
!.gitignore
!05-done.fish
!10-env.fish
!10-kitty.fish
!10-niri-env.fish
!10-sshs.fish
!50-prompt.fish
!50-theme.fish
!60-alias.fish
!60-fetch.fish
!fish_frozen_key_bindings.fish
!fish_frozen_theme.fish
@@ -1,349 +0,0 @@
# MIT License
# Copyright (c) 2016 Francisco Lourenço & Daniel Wehner
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
if not status is-interactive
exit
end
set -g __done_version 1.21.1
function __done_run_powershell_script
set -f powershell_exe (command --search "powershell.exe")
if test "$status" -ne 0
and command --search wslvar
set -f powershell_exe (wslpath (wslvar windir)/System32/WindowsPowerShell/v1.0/powershell.exe)
end
if string length --quiet "$powershell_exe"
and test -x "$powershell_exe"
set cmd (string escape $argv)
eval "$powershell_exe -Command $cmd"
end
end
function __done_windows_notification -a title -a message
if test "$__done_notify_sound" -eq 1
set soundopt "<audio silent=\"false\" src=\"ms-winsoundevent:Notification.Default\" />"
else
set soundopt "<audio silent=\"true\" />"
end
__done_run_powershell_script "
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
\$toast_xml_source = @\"
<toast>
$soundopt
<visual>
<binding template=\"ToastText02\">
<text id=\"1\">$title</text>
<text id=\"2\">$message</text>
</binding>
</visual>
</toast>
\"@
\$toast_xml = New-Object Windows.Data.Xml.Dom.XmlDocument
\$toast_xml.loadXml(\$toast_xml_source)
\$toast = New-Object Windows.UI.Notifications.ToastNotification \$toast_xml
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier(\"fish\").Show(\$toast)
"
end
function __done_get_focused_window_id
if type -q lsappinfo
lsappinfo info -only bundleID (lsappinfo front | string replace 'ASN:0x0-' '0x') | cut -d '"' -f4
else if test -n "$SWAYSOCK"
and type -q jq
swaymsg --type get_tree | jq '.. | objects | select(.focused == true) | .id'
else if test -n "$HYPRLAND_INSTANCE_SIGNATURE"
hyprctl activewindow | awk 'NR==1 {print $2}'
else if test -n "$NIRI_SOCKET"
and type -q jq
niri msg --json focused-window | jq ".id"
else if begin
test "$XDG_SESSION_DESKTOP" = gnome; and type -q gdbus
end
gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell --method org.gnome.Shell.Eval 'global.display.focus_window.get_id()'
else if type -q xprop
and test -n "$DISPLAY"
# Test that the X server at $DISPLAY is running
and xprop -grammar >/dev/null 2>&1
xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2
else if uname -a | string match --quiet --ignore-case --regex microsoft
__done_run_powershell_script '
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WindowsCompat {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
"@
[WindowsCompat]::GetForegroundWindow()
'
else if set -q __done_allow_nongraphical
echo 12345 # dummy value
end
end
function __done_is_tmux_window_active
set -q fish_pid; or set -l fish_pid %self
# find the outermost process within tmux
# ppid != "tmux" -> pid = ppid
# ppid == "tmux" -> break
set tmux_fish_pid $fish_pid
while set tmux_fish_ppid (ps -o ppid= -p $tmux_fish_pid | string trim)
# remove leading hyphen so that basename does not treat it as an argument (e.g. -fish), and return only
# the actual command and not its arguments so that basename finds the correct command name.
# (e.g. '/usr/bin/tmux' from command '/usr/bin/tmux new-session -c /some/start/dir')
and ! string match -q "tmux*" (basename (ps -o command= -p $tmux_fish_ppid | string replace -r '^-' '' | string split ' ')[1])
set tmux_fish_pid $tmux_fish_ppid
end
# tmux session attached and window is active -> no notification
# all other combinations -> send notification
tmux list-panes -a -F "#{session_attached} #{window_active} #{pane_pid}" | string match -q "1 1 $tmux_fish_pid"
end
function __done_is_screen_window_active
string match --quiet --regex "$STY\s+\(Attached" (screen -ls)
end
function __done_is_process_window_focused
# Return false if the window is not focused
if set -q __done_allow_nongraphical
return 1
end
if set -q __done_kitty_remote_control
kitty @ --password="$__done_kitty_remote_control_password" ls | jq -e ".[].tabs[] | select(any(.windows[]; .is_self)) | .is_focused" >/dev/null
return $status
end
set __done_focused_window_id (__done_get_focused_window_id)
if test "$__done_sway_ignore_visible" -eq 1
and test -n "$SWAYSOCK"
string match --quiet --regex "^true" (swaymsg -t get_tree | jq ".. | objects | select(.id == "$__done_initial_window_id") | .visible" 2>/dev/null)
return $status
else if test -n "$HYPRLAND_INSTANCE_SIGNATURE"
and test "$__done_initial_window_id" = (hyprctl activewindow | awk 'NR==1 {print $2}')
return $status
else if test -n "$NIRI_SOCKET"
and test "$__done_initial_window_id" = (niri msg --json focused-window | jq ".id")
return $status
else if test "$__done_initial_window_id" != "$__done_focused_window_id"
return 1
end
# If inside a tmux session, check if the tmux window is focused
if type -q tmux
and test -n "$TMUX"
__done_is_tmux_window_active
return $status
end
# If inside a screen session, check if the screen window is focused
if type -q screen
and test -n "$STY"
__done_is_screen_window_active
return $status
end
return 0
end
function __done_humanize_duration -a milliseconds
set -l seconds (math --scale=0 "$milliseconds/1000" % 60)
set -l minutes (math --scale=0 "$milliseconds/60000" % 60)
set -l hours (math --scale=0 "$milliseconds/3600000")
if test "$hours" -gt 0
printf '%s' $hours'h '
end
if test "$minutes" -gt 0
printf '%s' $minutes'm '
end
if test "$seconds" -gt 0
printf '%s' $seconds's'
end
end
# verify that the system has graphical capabilities before initializing
if test -z "$SSH_CLIENT" # not over ssh
and count (__done_get_focused_window_id) >/dev/null # is able to get window id
set __done_enabled
end
if set -q __done_allow_nongraphical
and set -q __done_notification_command
set __done_enabled
end
if set -q __done_enabled
set -g __done_initial_window_id ''
set -q __done_min_cmd_duration; or set -g __done_min_cmd_duration 5000
set -q __done_exclude; or set -g __done_exclude '^git (?!push|pull|fetch)'
set -q __done_notify_sound; or set -g __done_notify_sound 0
set -q __done_sway_ignore_visible; or set -g __done_sway_ignore_visible 0
set -q __done_tmux_pane_format; or set -g __done_tmux_pane_format '[#{window_index}]'
set -q __done_notification_duration; or set -g __done_notification_duration 3000
function __done_started --on-event fish_preexec
set __done_initial_window_id (__done_get_focused_window_id)
end
function __done_ended --on-event fish_postexec
set -l exit_status $status
# backwards compatibility for fish < v3.0
set -q cmd_duration; or set -l cmd_duration $CMD_DURATION
if test -n "$cmd_duration"
and test "$cmd_duration" -gt "$__done_min_cmd_duration" # longer than notify_duration
and not __done_is_process_window_focused # process pane or window not focused
# don't notify if command matches exclude list
for pattern in $__done_exclude
if string match -qr -- $pattern $argv[1]
return
end
end
# Store duration of last command
set -l humanized_duration (__done_humanize_duration "$cmd_duration")
set -l title "Done in $humanized_duration"
set -l wd (string replace --regex "^$HOME" "~" (pwd))
set -l message "$wd/ $argv[1]"
set -l sender $__done_initial_window_id
if test "$exit_status" -ne 0
set title "Failed ($exit_status) after $humanized_duration"
end
if test -n "$TMUX_PANE"
set message (tmux lsw -F"$__done_tmux_pane_format" -f '#{==:#{pane_id},'$TMUX_PANE'}')" $message"
end
if set -q __done_notification_command
eval $__done_notification_command
if test "$__done_notify_sound" -eq 1
echo -e "\a" # bell sound
end
else if set -q KITTY_WINDOW_ID
printf "\x1b]99;i=done:d=0;$title\x1b\\"
printf "\x1b]99;i=done:d=1:p=body;$message\x1b\\"
else if test "$TERM_PROGRAM" = ghostty; or test "$TERM_PROGRAM" = WezTerm
printf "\x1b]777;notify;%s;%s\x1b\\" "$title" "$message"
else if test "$TERM_PROGRAM" = iTerm.app
printf "\x1b]9;%s: %s\x1b\\" "$title" "$message"
else if type -q terminal-notifier # https://github.com/julienXX/terminal-notifier
if test "$__done_notify_sound" -eq 1
# pipe message into terminal-notifier to avoid escaping issues (https://github.com/julienXX/terminal-notifier/issues/134). fixes #140
# not using the -sender option because it hangs for some apps (https://github.com/julienXX/terminal-notifier/issues/301)
echo "$message" | terminal-notifier -title "$title" -sound default
else
echo "$message" | terminal-notifier -title "$title"
end
else if type -q osascript # AppleScript
# escape double quotes that might exist in the message and break osascript. fixes #133
set -l message (string replace --all '"' '\"' "$message")
set -l title (string replace --all '"' '\"' "$title")
if test "$__done_notify_sound" -eq 1
osascript -e "display notification \"$message\" with title \"$title\" sound name \"Glass\""
else
osascript -e "display notification \"$message\" with title \"$title\""
end
else if type -q notify-send # Linux notify-send
# set urgency to normal
set -l urgency normal
# use user-defined urgency if set
if set -q __done_notification_urgency_level
set urgency "$__done_notification_urgency_level"
end
# override user-defined urgency level if non-zero exitstatus
if test "$exit_status" -ne 0
set urgency critical
if set -q __done_notification_urgency_level_failure
set urgency "$__done_notification_urgency_level_failure"
end
end
notify-send --hint=int:transient:1 --urgency=$urgency --icon=utilities-terminal --app-name=fish --expire-time=$__done_notification_duration "$title" "$message"
if test "$__done_notify_sound" -eq 1
echo -e "\a" # bell sound
end
else if type -q notify-desktop # Linux notify-desktop
set -l urgency
if test "$exit_status" -ne 0
set urgency "--urgency=critical"
end
notify-desktop $urgency --icon=utilities-terminal --app-name=fish "$title" "$message"
if test "$__done_notify_sound" -eq 1
echo -e "\a" # bell sound
end
else if uname -a | string match --quiet --ignore-case --regex microsoft
__done_windows_notification "$title" "$message"
else # anything else
echo -e "\a" # bell sound
end
end
end
end
function __done_uninstall -e done_uninstall
# Erase all __done_* functions
functions -e __done_ended
functions -e __done_started
functions -e __done_get_focused_window_id
functions -e __done_is_tmux_window_active
functions -e __done_is_screen_window_active
functions -e __done_is_process_window_focused
functions -e __done_windows_notification
functions -e __done_run_powershell_script
functions -e __done_humanize_duration
# Erase __done variables
set -e __done_version
end
@@ -1,18 +0,0 @@
# ssh with encrypted private keys
# $ssh_keys should be set in advance or left empty to use the default keys
if set -q UY_ENABLE_GPG_AGENT_SSH; and test $UY_ENABLE_GPG_AGENT_SSH != "0";\
and type -q gpg-init; and type -q gpgconf
true # do nothing
else if type -q ssh-init; and type -q ssh-add
# avoid entering passphrase every time
function sshs
# test if keys are added to ssh-agent
if not ssh-add -l > /dev/null 2>&1
ssh-add $ssh_keys
end
ssh $argv
end
end
@@ -1,209 +0,0 @@
# fzf
if type -q fzf
fzf --fish | source
# use fd if available
if type -q fd
set -x FD_CMD "fd"
else if type -q fdfind
set -x FD_CMD "fdfind"
end
if test -n "$FD_CMD"
set -x FZF_DEFAULT_COMMAND "$FD_CMD --type f --hidden --exclude .git"
set -x FZF_CTRL_T_COMMAND "$FZF_DEFAULT_COMMAND"
set -x FZF_ALT_C_COMMAND "$FD_CMD --type d --hidden --exclude .git"
end
# C-y to copy fzf's output
if type -q wl-copy
set -x FZF_DEFAULT_OPTS "--bind \"ctrl-y:execute-silent(echo -n {+} | wl-copy)+abort\""
end
# fz: fuzzy find a file and preview
if type -q bat
alias fz="fzf --preview 'bat --style=numbers --color=always {}'"
else
alias fz="fzf --preview 'cat -n {}'"
end
# fe: fuzzy find a file and edit using $EDITOR
function fe
set -l file $(fz --header "[edit with $EDITOR]")
if test -n "$file"
$EDITOR "$file"
end
end
# fkp: fuzzy find a process and kill with SIGKILL
function fkp
set -l pids (ps -ef | sed 1d | fzf -m --preview 'pstree -p $(echo {} | awk "{print \$2}")' --header '[kill process]' | awk '{print $2}')
if test -n "$pids"
kill -9 $pids
end
end
# fks: fuzzy find a TCP process and kill with SIGKILL
if type -q ss
function fks
set -l entries (sudo ss -lptn)
set -l pids (echo "$entries" | fzf -m --header-lines 1 --header '[kill process]' | grep -oP 'pid=\K\d+')
if test -n "$pids"
sudo kill -9 $pids
end
end
end
if type -q yay
# fyq: fuzzy yay query
alias fyq="yay -Qq | fzf --preview 'yay -Qi {}'"
# fyi: fuzzy yay install
function fyi
set -l pkg (yay -Sl | awk '{print $1"/"$2}' | fzf -m --preview 'yay -Si {}' --header "[install package]" $argv)
if test -n "$pkg"
yay -S $pkg
end
end
# fyr: fuzzy yay remove
function fyr
set -l pkg (yay -Qq | fzf -m --preview 'yay -Qi {}' --header "[remove package]" $argv)
if test -n "$pkg"
yay -Rn $pkg
end
end
end
end
# cd
if type -q zoxide
zoxide init fish | source
alias cd=z
end
# rm
# if type -q trash
# alias rm="echo \"use 'trash' instead :)\" && sh -c \"exit 42\""
# end
# ls
if type -q eza
alias ll="eza -lh --group-directories-first --icons=auto"
alias la="eza -lh --group-directories-first --icons=auto --all"
alias lt="eza --tree --level=2 --long --icons --git"
else
alias ll="ls -lh --group-directories-first --color=auto"
alias la="ls -lah --group-directories-first --color=auto"
end
# directories
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
# grep
alias grep="grep --color=auto"
# copy DIR1 DIR2
function copy
set count (count $argv | tr -d \n)
if test "$count" = 2; and test -d "$argv[1]"
set from (echo $argv[1] | trim-right /)
set to (echo $argv[2])
command cp -r $from $to
else
command cp $argv
end
end
# wget
if type -q wget
alias wget="wget -c "
end
# colorize
alias dir='dir --color=auto'
alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
# Sort pacman packages by size
if type -q expac
alias big="expac -H M '%m\t%n' | sort -h | nl"
end
# clock
if type -q tty-clock
alias clock="tty-clock -c -C 4"
end
# journalctl
alias jctl="journalctl -p 3 -xb"
# nohup
function nh
nohup $argv >/dev/null 2>&1 & disown
end
# ffmpeg
alias ffmpeg="ffmpeg -hide_banner -nostdin"
alias ffprobe="ffprobe -hide_banner"
# git
if type -q git
function gcp
git add -A || return 1
if test (count $argv) -eq 0
git commit -m "👐 foo: too lazy to come up with a helpful commit message :)" || return 1
else
git commit -m "$argv" || return 1
end
git push
end
if type -q wl-paste
# alias gc="git clone \$(wl-paste)"
function gc
set -l repo (wl-paste)
if not string match -r '^(http|https|git|ssh)://|^git@' "$repo" >/dev/null 2>&1
echo "Error: Clipboard does not contain a valid git repository URL." >&2
echo "Error: Clipboard content: $repo" >&2
read -P "Enter a valid git repository URL: " repo
if not string match -r '^(http|https|git|ssh)://|^git@' "$repo"
echo "Error: Invalid git repository URL." >&2
return 1
end
end
git clone $repo
end
function pingo
cd "$HOME/Repositories/PGdP" || return 1
set -l repo (wl-paste)
if not string match -r '^(http|https|git|ssh)://|^git@' "$repo" >/dev/null 2>&1
echo "Error: Clipboard does not contain a valid git repository URL." >&2
echo "Error: Clipboard content: $repo" >&2
read -P "Enter a valid git repository URL: " repo
if not string match -r '^(http|https|git|ssh)://|^git@' "$repo"
echo "Error: Invalid git repository URL." >&2
return 1
end
end
set -l dir_name (basename "$repo" .git)
if ! test -d "$dir_name"
git clone $repo || return 1
end
set -l app $argv[1]
if test -n "$app"; and type -q "$app"
echo Opening project with "$app"
nohup $app $dir_name >/dev/null 2>&1 & disown
else
echo Opening method missing or invalid
cd $dir_name
end
end
end
end
+4
View File
@@ -4,3 +4,7 @@ end
# no greeting
set fish_greeting
for f in $__fish_config_dir/rc.d/*.fish
source $f
end
+11
View File
@@ -0,0 +1,11 @@
*
!.gitignore
!05-done.fish
!10-env.fish
!10-kitty.fish
!10-niri-env.fish
!10-sshs.fish
!50-prompt.fish
!50-theme.fish
!60-alias.fish
!60-fetch.fish
@@ -7,7 +7,7 @@ if type -q bat
end
# Editor
for app in nvim helix vim vi nano
for app in helix nvim vim vi nano
if type -q $app
set -x -g EDITOR $app
set -x -g VISUAL $app
@@ -31,3 +31,9 @@ set -U __done_notification_urgency_level low
if type -q fnm
fnm env --shell fish --use-on-cd | source
end
# bat
if type -q bat
set -xg BAT_THEME "Catppuccin Mocha"
set -xg BAT_STYLE "default,-numbers"
end
@@ -0,0 +1,18 @@
# ssh with encrypted private keys
# $uy_ssh_keys should be set in a device-specific file or left empty for defaults
if test "$UY_ENABLE_GPG_AGENT_SSH" = 1;\
and test -x "$HOME/.local/scripts/gpg-init"; and type -q gpgconf
true # GPG agent handles SSH — nothing to do
else if test "$UY_USING_SSH_AGENT" = 1
# avoid entering passphrase every time
function sshs
# test if keys are added to ssh-agent
if not ssh-add -l > /dev/null 2>&1
ssh-add $uy_ssh_keys
end
ssh $argv
end
end
@@ -1,7 +1,4 @@
function fish_prompt -d "Write out the prompt"
# This shows up as USER@HOST /home/user/ >, with the directory colored
# $USER and $hostname are set by fish, so you can just use them
# instead of using `whoami` and `hostname`
printf '%s@%s %s%s%s > ' $USER $hostname \
(set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
end
@@ -0,0 +1,84 @@
# fzf
if type -q fzf
fzf --fish | source
# use fd if available
if type -q fd
set -g FD_CMD "fd"
else if type -q fdfind
set -g FD_CMD "fdfind"
end
if test -n "$FD_CMD"
set -x FZF_DEFAULT_COMMAND "$FD_CMD --type f --hidden --exclude .git"
set -x FZF_CTRL_T_COMMAND "$FZF_DEFAULT_COMMAND"
set -x FZF_ALT_C_COMMAND "$FD_CMD --type d --hidden --exclude .git"
end
# C-y to copy fzf's output
if type -q wl-copy
set -x FZF_DEFAULT_OPTS "--bind \"ctrl-y:execute-silent(echo -n {+} | wl-copy)+abort\""
end
end
# cd
if type -q zoxide
zoxide init fish | source
alias cd=z
end
# rm
# if type -q trash
# alias rm="echo \"use 'trash' instead :)\" && sh -c \"exit 42\""
# end
# ls
if type -q eza
alias ls="eza --color=auto --hyperlink=auto"
alias ll="eza -lh --group-directories-first --icons=auto --hyperlink=auto"
alias la="eza -lh --group-directories-first --icons=auto --hyperlink=auto --all"
alias lt="eza --tree --level=2 --long --icons --git --hyperlink=auto"
else
alias ls="ls --color=auto --hyperlink=auto"
alias ll="ls -lh --group-directories-first --color=auto --hyperlink=auto"
alias la="ls -lah --group-directories-first --color=auto --hyperlink=auto"
end
# directories
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
# colorize
alias grep="grep --color=auto"
alias dir="dir --color=auto"
alias vdir="vdir --color=auto"
alias fgrep="fgrep --color=auto"
alias egrep="egrep --color=auto"
alias diff="diff --color=auto"
# wget
if type -q wget
alias wget="wget -c"
end
# Sort pacman packages by size
if type -q expac
alias big="expac -H M '%m\t%n' | sort -h | nl"
end
# clock
if type -q tty-clock
alias clock="tty-clock -c -C 4"
end
# journalctl
alias jctl="journalctl -p 3 -xb"
# nohup
function nh
nohup $argv >/dev/null 2>&1 & disown
end
# ffmpeg
alias ffmpeg="ffmpeg -hide_banner -nostdin"
alias ffprobe="ffprobe -hide_banner"