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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+11 -10
View File
@@ -42,6 +42,7 @@ fi
if type opam &>/dev/null; then
eval "$(opam env)"
fi
prepend_path "$HOME/.local/share/fnm/aliases/default/bin" # 'fnm env' is eval'ed in .bashrc
prepend_path "$HOME/.cargo/bin"
prepend_path "$HOME/go/bin"
prepend_path "$HOME/.local/bin"
@@ -54,20 +55,20 @@ if type gpgconf &>/dev/null && type gpg-connect-agent &>/dev/null &&
[ -x "$HOME/.local/scripts/gpg-init" ] &&
[ "${UY_ENABLE_GPG_AGENT_SSH:-0}" = "1" ]; then
# GPG agent for SSH
eval "$($HOME/.local/scripts/gpg-init 2>/dev/null)" &>/dev/null
eval "$("$HOME/.local/scripts/gpg-init" 2>/dev/null)" &>/dev/null
fi
if type ssh-add &>/dev/null && type ssh-agent &>/dev/null &&
{ [ -z "$SSH_AUTH_SOCK" ] ||
[ "$(
ssh-add -l &>/dev/null
echo $?
)" -eq 2 ]; } &&
[ -x "$HOME/.local/scripts/ssh-init" ]; then
if type ssh-add &>/dev/null && type ssh-agent &>/dev/null; then
# ssh-add -l: 0 = agent with keys, 1 = agent without keys, 2 = no agent
if [ -n "$SSH_AUTH_SOCK" ] &&
{ ssh-add -l &>/dev/null; [ $? -ne 2 ]; }; then
export UY_USING_SSH_AGENT=1
elif [ -x "$HOME/.local/scripts/ssh-init" ]; then
unset SSH_AUTH_SOCK
# SSH with cross-session ssh-agent
eval "$($HOME/.local/scripts/ssh-init 2>/dev/null)" &>/dev/null
export UY_USING_SSH_AGENT=1
eval "$("$HOME/.local/scripts/ssh-init" 2>/dev/null)" &>/dev/null
[ -n "$SSH_AUTH_SOCK" ] && export UY_USING_SSH_AGENT=1
fi
fi
[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc"
+7 -3
View File
@@ -53,11 +53,15 @@ if type fnm &>/dev/null; then
eval "$(fnm env --shell bash --use-on-cd)"
fi
if [[ ${UY_USING_SSH_AGENT:-0} == 1 ]]; then
# $uy_ssh_keys should be set in a device-specific file or left empty for defaults
if [[ ${UY_ENABLE_GPG_AGENT_SSH:-0} == 1 ]] &&
[ -x "$HOME/.local/scripts/gpg-init" ] && type gpgconf &>/dev/null; then
: # GPG agent handles SSH — nothing to do
elif [[ ${UY_USING_SSH_AGENT:-0} == 1 ]]; then
function sshs() {
if ! ssh-add -l &>/dev/null; then
if [ -n "$ssh_keys" ]; then
ssh-add "${ssh_keys[@]}"
if [ ${#uy_ssh_keys[@]} -gt 0 ]; then
ssh-add "${uy_ssh_keys[@]}"
else
ssh-add
fi
@@ -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"
+32 -6
View File
@@ -9,10 +9,33 @@ zmodload zsh/datetime
: ${uy_done_min_cmd_duration:=10}
: ${uy_done_exclude:='^(nvim|helix|hx|vim|vi|nano|less|more|man|ssh|top|htop|btop|sudoedit)$'}
uy_done_get_focused_window_id() {
(( $+commands[jq] )) || return
niri msg --json focused-window 2>/dev/null | jq -r '.id // empty'
}
# Returns the id in $REPLY, empty if there is none or niri did not answer.
if zmodload zsh/net/socket 2>/dev/null; then
uy_done_get_focused_window_id() {
setopt local_options extended_glob
local fd line
local -a match mbegin mend
REPLY=
zsocket "$NIRI_SOCKET" 2>/dev/null || return
fd=$REPLY
REPLY=
if print -u $fd -r -- '"FocusedWindow"' 2>/dev/null; then
read -t 1 -u $fd -r line 2>/dev/null
fi
exec {fd}>&-
# With no focused window the payload is null, so the id is simply absent.
[[ $line == (#b)*'"FocusedWindow":'*'"id":'(<->)* ]] && REPLY=$match[1]
}
elif (( $+commands[jq] )); then
uy_done_get_focused_window_id() {
REPLY=$(niri msg --json focused-window 2>/dev/null | jq -r '.id // empty')
}
else
return
fi
uy_done_cmd_name() {
local -a words
@@ -33,9 +56,11 @@ uy_done_cmd_name() {
}
uy_done_preexec() {
local REPLY
uy_done_cmd="$1"
uy_done_start=$EPOCHSECONDS
uy_done_window_id=$(uy_done_get_focused_window_id)
uy_done_get_focused_window_id
uy_done_window_id=$REPLY
}
uy_done_precmd() {
@@ -54,7 +79,8 @@ uy_done_precmd() {
# skip if window is still focused
local current_id
current_id=$(uy_done_get_focused_window_id)
uy_done_get_focused_window_id
current_id=$REPLY
[[ -n "$uy_done_window_id" && "$uy_done_window_id" = "$current_id" ]] && return
# humanize duration
+1 -7
View File
@@ -7,7 +7,7 @@ fi
# Editor
for _uy_app in nvim helix vim vi nano; do
for _uy_app in helix nvim vim vi nano; do
if (( $+commands[$_uy_app] )); then
export EDITOR=$_uy_app
export VISUAL=$_uy_app
@@ -30,12 +30,6 @@ fi
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#6c7086"
# Vscode shell integration
if (( $+commands[code] )) && [[ "$TERM_PROGRAM" == "vscode" ]]; then
source "$(code --locate-shell-integration-path zsh)"
fi
# fnm
if (( $+commands[fnm] )); then
+15 -6
View File
@@ -17,7 +17,7 @@ uy_oops_confirm() {
# when the current one ends in a backslash; zsh writes a command that itself
# ends in a backslash as "\ " (trailing space), so the marker is unambiguous.
# Walking forward and remembering the start of each entry is exact for
# entries of any length — scanning backwards over a fixed window is not.
# entries of any length.
local start
start=$(awk '{ if (!cont) start = NR; cont = /\\$/ } END { print start + 0 }' "$HISTFILE")
@@ -49,11 +49,20 @@ uy_oops_confirm() {
# one) correctly leaves an empty file.
local n=${#ordered[@]}
head -n $(( start - 1 )) "$HISTFILE" > "$HISTFILE.tmp" && mv "$HISTFILE.tmp" "$HISTFILE"
# Replace the in-memory history with the updated file.
# `fc -R` would *append* the file on top of what is already in memory,
# which both duplicates every entry and leaves the deleted command in
# memory — the next `fc -W` (e.g. the one at the top of this function
# on a second `oops`) would then write it straight back to the file.
# Replace the in-memory history with the updated file. `fc -p` is the
# only primitive that replaces it: `fc -R` *appends* the file on top of
# what is already in memory, which both duplicates every entry and
# leaves the deleted command there for the next `fc -W` to write back.
#
# `fc -p` pushes a history layer, and each layer retains a full copy of
# the history, so pop the layer the previous call left behind first —
# that keeps exactly one live no matter how often `oops` runs. `fc -P`
# only restores the old in-memory list, it does not write to $HISTFILE,
# so it cannot undo the deletion above; and the push on the very next
# line replaces that stale list immediately. Both must stay in this
# branch: on the cancel path nothing was deleted, so memory already
# matches the file and popping would corrupt it.
fc -P 2>/dev/null
fc -p "$HISTFILE" $HISTSIZE $SAVEHIST
print -P "%F{green}Deleted ($n line(s) removed).%f"
else
+35 -7
View File
@@ -5,13 +5,42 @@ PROMPT='%F{blue}%n@%m%f %F{cyan}%~%f > '
if (( $+commands[starship] )); then
eval "$(starship init zsh)"
function uy_transient_prompt() {
local file palette color
file=${STARSHIP_CONFIG:-"$HOME/.config/starship.toml"}
palette=$(sed -n "s/^palette\s*=\s*'\(.*\)'/\1/p" "$file")
color=$(sed -n "/^\[palettes\.${palette}\]/,/^\[/{s/^accent\s*=\s*\"\(.*\)\"/\1/p}" "$file")
# accent of the [palettes.<name>] named by the top-level `palette` key.
function uy_starship_accent() {
setopt local_options extended_glob
local line palette in_palette=0
local -a lines
[[ -r $1 ]] || return 1
lines=( ${(f)"$(<$1)"} )
PROMPT="%F{$color}#%f " zle .reset-prompt
for line in $lines; do
if [[ $line == palette[[:blank:]]#=[[:blank:]]#\'*\' ]]; then
palette=${${line#*\'}%\'}
break
fi
done
[[ -n $palette ]] || return 1
for line in $lines; do
if (( in_palette )); then
[[ $line == \[* ]] && return 1
if [[ $line == accent[[:blank:]]#=[[:blank:]]#\"*\" ]]; then
REPLY=${${line#*\"}%\"}
return 0
fi
elif [[ $line == "[palettes.$palette]" ]]; then
in_palette=1
fi
done
return 1
}
function uy_transient_prompt() {
local REPLY
uy_starship_accent "${STARSHIP_CONFIG:-$HOME/.config/starship.toml}" &&
uy_accent=$REPLY
PROMPT="%F{${uy_accent:-blue}}#%f " zle .reset-prompt
}
autoload -Uz add-zle-hook-widget
@@ -21,4 +50,3 @@ if (( $+commands[starship] )); then
elif [[ -f "$HOME/.config/posh_theme.omp.json" ]] && (( $+commands[oh-my-posh] )); then
eval "$(oh-my-posh init zsh --config "$HOME/.config/posh_theme.omp.json")"
fi
+10 -4
View File
@@ -5,9 +5,9 @@ if (( $+commands[fzf] )); then
# use fd if available (search cwd only, skip vcs/cache junk)
if (( $+commands[fd] )); then
export FD_CMD="fd"
FD_CMD="fd"
elif (( $+commands[fdfind] )); then
export FD_CMD="fdfind"
FD_CMD="fdfind"
fi
if [[ -n "$FD_CMD" ]]; then
export FZF_DEFAULT_COMMAND="$FD_CMD --type f --hidden --exclude .git"
@@ -225,8 +225,14 @@ if (( $+commands[jj] )); then
jjp() {
default_branch() {
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|.*/||' \
|| git remote show origin | awk '/HEAD branch/ {print $NF}' || echo "master"
local ref
ref=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)
if [[ -n "$ref" ]]; then
print -r -- "${ref:t}"
return
fi
ref=$(git remote show origin 2>/dev/null | awk '/HEAD branch/ {print $NF}')
print -r -- "${ref:-master}"
}
local branch pos
branch=${1:-$(default_branch)}
@@ -52,6 +52,10 @@ sixel)
uy_fetch_args=(--logo-type raw --logo-width 42 --logo "$HOME/.config/fastfetch/logo_ros/42x.sixel" --color "$uy_fetch_color")
uy_fetch_args_brief=(--logo-type raw --logo-width 28 --logo "$HOME/.config/fastfetch/logo_ros/28x.sixel" --color "$uy_fetch_color")
;;
unicode)
uy_fetch_args=(--logo-type raw --logo-width 42 --logo "$HOME/.config/fastfetch/logo_ros/42x.unicode" --color "$uy_fetch_color")
uy_fetch_args_brief=(--logo-type raw --logo-width 28 --logo "$HOME/.config/fastfetch/logo_ros/28x.unicode" --color "$uy_fetch_color")
;;
*) # kitty, auto, etc.
uy_fetch_args=(--logo-type "$uy_fetch_logo_type" --logo-width 42 --logo "$HOME/.config/fastfetch/logo_ros/ros.png" --color "$uy_fetch_color")
uy_fetch_args_brief=(--logo-type "$uy_fetch_logo_type" --logo-width 28 --logo "$HOME/.config/fastfetch/logo_ros/ros.png" --color "$uy_fetch_color")