Initial commit of bash scripts

This commit is contained in:
2026-06-05 23:49:54 -04:00
parent b7cf4a0224
commit 8e0e4dfc79
16 changed files with 519 additions and 70 deletions
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env zsh
LC_CTYPE="en_US.UTF-8"
set -x
charging_status () {
cat /sys/class/power_supply/BAT0/status
}
battery_percentage () {
ibam --percentbattery | grep -Pom 1 '\d{1,3}'
}
if [[ "$(charging_status)" == "Charging" ]] && \
[[ $(battery_percentage) -gt 5 ]] && \
[[ -f /run/user/${UID}/battery_low ]]; then
logger "Power reconnected and above 5 percent, clearing nofication state."
rm /run/user/${UID}/battery_low
for id in $(dunstctl history | jq '.data[0][] | select(.summary.data == "LOW BATTERY!")| .id.data' \
| tee /tmp/dunst_history.json); do
dunstify --close=${id}
done
elif [[ "$(charging_status)" == "Discharging" ]] && \
[[ $(battery_percentage) -le 5 ]] && \
[[ ! ( -f /run/user/${UID}/battery_low ) ]] ; then
logger "Low power! Triggering notification...."
dunstify --urgency=critical \
--icon=/usr/share/icons/breeze-dark/emblems/16/emblem-warning.svg \
'LOW BATTERY!' \
'Battery level is low, plug power quick!'
touch /run/user/${UID}/battery_low
fi
set +x
# vim: ft=zsh
+8 -1
View File
@@ -2,5 +2,12 @@
#set -x
source ~/.config/hypr/scripts/functions
create_workspace ${@}
name="$(rofi -dmenu -p "new workspace name" -l 0 < /dev/null)"
if [[ -z "${@}" ]]; then
create_workspace "${name}"
else
after_name="${1}"; shift
create_workspace "${name}" "${after_name}"
fi
#set +x
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env zsh
#set -x
source ~/.config/hypr/scripts/functions
delete_workspace "${active_ws_name}"
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env zsh
hyprctl --instance 0 'keyword misc:allow_session_lock_restore 1'
hyprctl --instance 0 'dispatch exec hyprlock'
+141 -69
View File
@@ -2,9 +2,40 @@
export HYPRLAND_INSTANCE_SIGNATURE=$(hyprctl -j instances | jq -r '.[0] | .instance')
unset workspaces_conf
unset monitors
unset active_mon
unset active_ws_name
unset total_ws
unset workspaces
unset last_id
workspaces_conf="${XDG_CONFIG_HOME}/hypr/workspaces.conf"
set -x
monitors=$(hyprctl -j monitors)
active_mon=$(hyprctl -j monitors | jq --raw-output '.[] | select(.focused) | .name')
active_ws_name="$(hyprctl -j activeworkspace | jq --raw-output '.name')"
#set +x
total_ws=$(hyprctl -j workspaces | jq --compact-output --raw-output 'sort_by(.id)')
if (( $(jq length <<< "${monitors}") > 1 )); then
workspaces="$(jq --compact-output --raw-output \
--arg mon "${active_mon}" '[.[] | select(.monitor == $mon)]' \
<<< "${total_ws}")"
else
workspaces="${total_ws}"
fi
set +x
clients=$(hyprctl -j clients)
cycle_workspace () {
set -x
local names=$(jq --raw-output --compact-output '[.[].name]' <<< ${workspaces})
local prev_ws=$(jq --raw-output --arg ws "${active_ws_name}" '.[index($ws) - 1]' <<< "${names}")
local next_ws=$(jq --raw-output --arg ws "${active_ws_name}" '.[index($ws) + 1]' <<< "${names}")
if [[ -n "${@}" ]]; then
direction="${1}"
@@ -13,89 +44,130 @@ cycle_workspace () {
exit 1
fi
monitors=$(hyprctl -j monitors)
workspaces=$(hyprctl -j workspaces)
active_mon=$(hyprctl -j monitors | jq '.[] | select(.focused) | .id')
active_ws=$(hyprctl -j monitors | jq --argjson mon ${active_mon} '.[$mon].activeWorkspace.id')
first_ws=$(jq '.[0].id' <<< "${workspaces}")
last_ws=$(jq '.[-1].id' <<< "${workspaces}")
#set -x
case "${direction}" in
"next")
if [[ ${active_ws} -eq ${last_ws} ]]; then
hyprctl dispatch workspace ${first_ws}
else
hyprctl dispatch workspace +1
fi
prev)
hyprctl dispatch workspace m-1
;;
"prev")
if [[ ${active_ws} -eq ${first_ws} ]]; then
hyprctl dispatch workspace ${last_ws}
else
hyprctl dispatch workspace -1
fi
next)
#if [[ "${next_ws}" != null ]]; then
hyprctl dispatch workspace m+1
#else
# hyprctl dispatch workspace "name:$(jq --raw-output '.[0]' <<< ${names})"
#fi
;;
*)
print "Invalid direction! Exiting..." >&2
exit 2
;;
esac
set +x
}
add_persistent_ws () {
set -x
new_id=${1}; shift
new_name=${1}; shift
if [[ -n "${1}" ]]; then
after_name=${1}; shift
fi
not_written=true
tmp=$(mktemp /tmp/ws.confXXX)
if [[ -n ${after_name} ]]; then
while read -r line; do
print "${line}"
if grep -q ${after_name} <<< "${line}" && ${not_written}; then
printf "workspace = %s, " ${new_id}
printf "defaultName:%s, " "${new_name}"
printf "monitor:%s, " "${active_mon}"
print "persistent:true, default:true"
not_written=false
fi
done < "${workspaces_conf}" | tee "${tmp}"
else
cp "${workspaces_conf}" "${tmp}"
printf "workspace = %s, " ${new_id} | tee -a "${tmp}"
printf "defaultName:%s, " "${new_name}" | tee -a "${tmp}"
printf "monitor:%s, " "${active_mon}" | tee -a "${tmp}"
print "persistent:true, default:true" | tee -a "${tmp}"
fi
mv "${tmp}" "${workspaces_conf}"
set +x
}
reorder_ws_conf () {
set -x
local found=false
local new_id=${1}; shift
local in="${1}"; shift
local tmp=$(mktemp /tmp/ws.confXXX)
while read -r line; do
if ! ${found}; then
print "${line}"
if grep -q ${new_id} <<< "${line}"; then
found=true
old_id=${curr_id}
new_id=$(( curr_id + 1 ))
fi
else
perl -pse 's/^workspace\s*=\s*$old,\s*/workspace = $new, /' -- -old="${curr_id}" -new="${new_id}" <<< "${line}"
old_id=${curr_id}
curr_id=$(( curr_id + 1 ))
fi
done < "${in}" | tee "${tmp}"
mv "${tmp}" "${in}"
}
create_workspace () {
active_mon=$(hyprctl -j monitors | jq '.[] | select(.focused) | .id')
workspaces="$(hyprctl -j workspaces | jq --compact-output .)"
first_ws=$(jq '.[0].id' <<< "${workspaces}")
last_ws=$(jq '.[-1].id' <<< "${workspaces}")
set -x
curr_id=$(hyprctl -j activeworkspace | jq --raw-output '.id')
last_id=$(jq '.[-1].id' <<< "${total_ws}")
new_id=$(( last_id + 1 ))
if [[ -n "${@}" ]]; then
new_name="${1}"
shift
else
print "Must suplly at least a new workspace name! Exiting..." >&2
exit 1
fi
# save current workspace name
print "${active_ws_name}" | \
tee /run/user/${UID}/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/last.ws
if [[ -n "${@}" ]]; then
new_ws="${1}"
else
new_ws=$(( last_ws + 1 ))
fi
case ${#@} in
1)
# add at the end
new_name="${1}"
shift
add_persistent_ws ${new_id} "${new_name}"
;;
2)
new_name="${1}"; shift
after_name="${1}"; shift
after_id=$(jq --compact-output --raw-output --arg after "${after_name}" \
'.[] | select(.name == $after).id' <<< "${total_ws}")
new_id=$(( after_id + 1))
add_persistent_ws ${new_id} "${new_name}"
reorder_ws_conf ${new_id} "${workspaces_conf}"
;;
*)
print "Wrong number of arguments to ${0}! Exiting..." >&2
;;
esac
old_ws=$(hyprctl -j activeworkspace | jq '.id')
if [[ ${old_ws} -ne ${last_ws} ]]; then
hyprctl dispatch workspace ${last_ws}
fi
# create new workspace
hyprctl dispatch workspace +1
active_ws=$(hyprctl -j activeworkspace | jq '.id')
hyprctl dispatch renameworkspace ${active_ws} ${new_name}
hyprctl keyword workspace "${active_ws},defaultName:${new_name}, monitor:${active_mon}, persistent:true"
if [[ ${new_ws} -lt ${last_ws} ]]; then
for ws in {${new_ws}..${last_ws}}; do
curr_name=$(jq --raw-output --argjson ws ${ws} '.[] | select(.id == $ws) | .name' <<< "${workspaces}")
if [[ ${new_ws} -eq ${ws} ]]; then
next_name=${curr_name}
else
hyprctl dispatch renameworkspace ${ws} ${next_name}
next_name=${curr_name}
fi
done
last_ws=$(hyprctl -j workspaces | jq '.[-1].id')
hyprctl dispatch renameworkspace ${last_ws} ${next_name}
fi
hyprctl dispatch renameworkspace ${new_ws} ${new_name}
active_ws=$(hyprctl -j activeworkspace | jq '.id')
hyprctl keyword workspace "${active_ws},defaultName:${next_name}, monitor:${active_mon}, persistent:true"
#set -x
if [[ ${active_ws} -ne ${new_ws} ]]; then
hyprctl dispatch workspace ${new_ws}
create_workspace ${next_name}
hyprctl dispatch workspace ${old_ws}
fi
#set +x
hyprctl reload
set +x
}
delete_workspace () {
set -x
unset old_workspace
old_workspace="$(cat /run/user/${UID}/${HYPRLAND_INSTANCE_SIGNATURE}/last.ws)"
sed -i "/${active_ws_name}/d" ${workspaces_conf}
hyprctl dispatch workspace "name:${old_workspace}"
hyprctl reload
set +x
}
cycle_clients () {
hyprctl dispatch movefocus d
}
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
hyprctl activeworkspace -j | jq --raw-output '.name'
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env zsh
eval $(gnome-keyring-daemon --start --components=secrets --unlock)
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env zsh
#set -x
# Define your Monitor Serials (from your Kanshi config)
# Left Monitor: Ancor Communications Inc ASUS VS228 E3LMTF071438
SERIAL_LEFT="E3LMTF071438"
# Right Monitor: Ancor Communications Inc ASUS VS228 E3LMTF071391
SERIAL_RIGHT="E3LMTF071391"
### --- HELPER FUNCTIONS --- ###
# Function to find the current port name (e.g., DP-6, HDMI-A-1) for a given serial
get_monitor_port() {
local serial=$1
hyprctl monitors -j | jq -r --arg s "$serial" '.[] | select(.serial == $s) | .name'
}
# Wait for a specific monitor serial to appear in Hyprland
wait_for_monitor() {
local serial=$1
local max_retries=10 # Wait up to 5 seconds (10 * 0.5s)
local count=0
while [[ $count -lt $max_retries ]]; do
local port=$(get_monitor_port "$serial")
if [[ -n "$port" ]]; then
echo "$port"
return 0
fi
sleep 0.5
count=$(( count+1 ))
done
return 1
}
# Function to safely restart Waybar
restart_waybar() {
# Kill any running instances
pkill waybar
# Wait a moment for them to die
while pgrep -x waybar > /dev/null; do sleep 0.1; done
# Start fresh instance via uwsm in the background
uwsm app -- waybar &
}
### --- MAIN LOGIC --- ###
# Get current profile and arguments
old_profile="$(kanshictl status | awk -F': ' '{print $NF}')"
new_profile="${1}"
shift
# Check if profile actually changed (unless forced)
if [[ "${old_profile}" == "${new_profile}" ]]; then
if [[ "${1}" != "--force" ]] && [[ "${1}" != '-f' ]]; then
exit 0
fi
fi
# Path to your workspaces config
WS_CONFIG="${XDG_CONFIG_HOME}/hypr/workspaces.conf"
PAPER_CONFIG="${XDG_CONFIG_HOME}/hypr/hyprpaper.conf"
case "${new_profile}" in
home_office)
# 1. Dynamically find which port the monitors are currently plugged into
PORT_RIGHT=$(wait_for_monitor "$SERIAL_RIGHT")
PORT_LEFT=$(wait_for_monitor "$SERIAL_LEFT")
# Fallback: If for some reason we can't find them, default to eDP-1 to prevent crash
[[ -z "$PORT_LEFT" ]] && PORT_LEFT="eDP-1"
[[ -z "$PORT_RIGHT" ]] && PORT_RIGHT="eDP-1"
# 2. Assign Workspaces to the detected ports
# Right Monitor (Shell, Browser)
perl -pi -e "if (/defaultName:shell/) {s/monitor:.+?,/monitor:${PORT_RIGHT},/}" $WS_CONFIG
perl -pi -e "if (/defaultName:browser/) {s/monitor:.+?,/monitor:${PORT_RIGHT},/}" $WS_CONFIG
# Left Monitor (Work, Jobs)
perl -pi -e "if (/defaultName:work/) {s/monitor:.+?,/monitor:${PORT_LEFT},/}" $WS_CONFIG
perl -pi -e "if (/defaultName:jobs/) {s/monitor:.+?,/monitor:${PORT_LEFT},/}" $WS_CONFIG
# Laptop Screen (Meeting, Monitoring) - Explicitly assigning these ensures they don't get "stuck"
perl -pi -e "if (/defaultName:meeting/) {s/monitor:.+?,/monitor:eDP-1,/}" "$WS_CONFIG"
perl -pi -e "if (/defaultName:monitoring/) {s/monitor:.+?,/monitor:eDP-1,/}" "$WS_CONFIG"
# 3. Apply changes
kanshictl switch home_office
hyprctl reload
restart_waybar
;;
single_headed)
# Move EVERYTHING to the internal laptop screen
perl -pi -e 's/monitor:.*?,/monitor:eDP-1,/' "$WS_CONFIG"
kanshictl switch single_headed
hyprctl reload
restart_waybar
;;
fix_me)
# Treat "fix_me" (2 monitors) as single_headed temporarily
# This prevents the script from erroring out while waiting for the 3rd monitor
perl -pi -e 's/monitor:.*?,/monitor:eDP-1,/' "$WS_CONFIG"
kanshictl switch fix_me
hyprctl reload
restart_waybar
;;
*)
print "Invalid profile!" >&2
;;
esac
#set +x
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env zsh
#set -x
old_profile="$(kanshictl status | jq -r '.current_profile')"
new_profile="${1}"
shift
if [[ "${old_profile}" == "${new_profile}" ]]; then
if [[ "${1}" != "--force" ]] && [[ "${1}" != '-f' ]]; then
exit 0
fi
fi
case "${new_profile}" in
home_office)
perl -pi -e 'if (/shell/) {s/monitor:.*?,/monitor:DP-6,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
perl -pi -e 'if (/browser/) {s/monitor:.*?,/monitor:DP-6,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
perl -pi -e 'if (/work/) {s/monitor:.*?,/monitor:HDMI-A-1,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
perl -pi -e 'if (/jobs/) {s/monitor:.*?,/monitor:HDMI-A-1,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
kanshictl switch home_office
hyprctl reload
killall -s USR2 waybar
;;
single_headed)
perl -pi -e 's/monitor:.*?,/monitor:eDP-1,/' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
kanshictl switch single_headed
hyprctl reload
killall -s USR2 waybar
;;
*)
print "Invalid profile!" >&2
;;
esac
#set +x
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env zsh
set -x
current_window="$(hyprctl -j activewindow | jq --compact-output)"
current_addr=$(jq --raw-output '.address' <<< "${current_window}")
current_class=$(jq --raw-output '.class' <<< "${current_window}")
current_title=$(jq --raw-output '.title' <<< "${current_window}")
typeset -a workspaces
workspaces=("$(hyprctl -j workspaces | jq --raw-output --compact-output '.[] | .name')")
new_workspace_name="$(rofi -dmenu -p "Move window of ${current_class} with title '${current_title}' to which workspace? " <<< ${workspaces})"
hyprctl dispatch movetoworkspacesilent "${new_workspace_name}","address:${current_addr}"
set +x
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env zsh
#set -x
unset april sbm
unset paths
unset images
unset img_set
unset monitors
unset paper_conf
monitors="$(hyprctl -j monitors | jq --compact-output --raw-output '[.[] | {"id": .id, "name": .name, "serial": .serial}]')"
monitor_count=$(jq length <<< "${monitors}")
paper_conf="${XDG_CONFIG_HOME}/hypr/hyprpaper.conf"
typeset -a paths
#april="${HOME}/images/April"
april="/home/trey/images/April/april-nightclub.png"
sbm="${HOME}/images/Seven Beats Music"
black="${HOME}/images/black.png"
if [[ ${monitor_count} -eq 1 ]]; then
paths=(${april})
else
if [[ "$(kanshictl status | awk -F': ' '{print $NF}')" == "home_office" ]]; then
paths=(${sbm})
fi
fi
if [[ -n "${paths}" ]]; then
typeset -a images
for pathd in "${paths[@]}"; do
# this line is idiomatic zsh (globbing)
# - N: skip dir if it is empty
# - .: only add regular files
images+=("${pathd}"/**/*(N.))
done
images=(${april})
#for image in ${images[@]}; do
# print "${image}"
#done
typeset -a img_set
while [[ ${#img_set} -le ${monitor_count} ]]; do
#set -x
idx=$(( ${RANDOM} % ${#images} ))
if (( img_set[(I)${images[idx]}] )); then # if image is already in img_set
continue
else
img_set+=${images[idx]}
fi
done
#
#for img in ${img_set[@]}; do
# print ${img}
#done
#set -x
index=1
for pic in ${img_set[@]}; do
if (( index > monitor_count )); then
break
fi
monitor="$(jq --compact-output --raw-output --argjson i $(( index - 1 )) '.[$i].name' <<< "${monitors}")"
#if [[ "${monitor}" == eDP-1 ]]; then
# index=$(( index + 1 ))
# continue
#fi
#perl -i -spe '$c+=m/^\s*monitor = .*/ if !($c xor N); s/monitor = .*$/monitor = $mon/ if $c == $N' -- -N=${idx} -mon="${monitor}" "${paper_conf}"
#perl -i -spe '$c+=m/^\s*path = .*/ if !($c xor N); s/path = .*$/path = $img/ if $c == $N' -- -N=${idx} -img="${pic}" "${paper_conf}"
#perl -i -pe '$c+=m/pattern/ if !($c xor N); s/old_string/new_string/g if $c == N' yourfile
perl -i -s -pe '$_ = " monitor = $mon\n" if /monitor/ && ++$n == $N' -- -N="${index}" -mon="${monitor}" "${paper_conf}"
perl -i -s -pe '$_ = " path = $img\n" if /path/ && ++$n == $N' -- -N="${index}" -img="${pic}" "${paper_conf}"
index=$(( index + 1 ))
done
#set +x
fi
+1
View File
@@ -0,0 +1 @@
slurp | grim -g - "$(date +%FT%H%M%S)_screenshot.png" && paplay ~/wav/camera.wav
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env zsh
mon_count=$(hyprctl monitors -j | jq length)
current_profile=$(kanshictl status | awk -F': ' '{print $NF}')
if [[ ${mon_count} -eq 1 ]]; then
~/.config/hypr/scripts/multihead.zsh single_headed --force
else
~/.config/hypr/scripts/multihead.zsh ${current_profile} --force
fi
if nmcli dev wifi list | awk '/^\*/ {print $2}' | grep -q keep; then
~/.config/hypr/scripts/randomize-wallpaper
else
perl -i -pe 's/^\s*path = .*/ path = \/home\/trey\/images\/black.png/ if ! $found; $found=1 if /^\s*path = .*/' ${XDG_CONFIG_HOME}/hypr/hyprpaper.conf
fi
systemctl --user restart hyprpaper
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env zsh
#!/bin/bash
# 1. THE BARRIER: Wake the sleeping PAM stub and claim the D-Bus channel.
# Because there is no '&' at the end of this line, the script will halt here
# and wait for the daemon to successfully return an exit code before proceeding.
gnome-keyring-daemon --start --components=secrets,ssh,pkcs11
# 2. THE LAUNCH: Now that the vault is definitively unlocked and registered,
# launch the dependent apps in the background.
uwsm app -- waybar &
uwsm app -- nm-applet &
uwsm app -- signal-desktop &
uwsm app -- blueman-applet &
uwsm app -- hp-systray &
uwsm app -- vivaldi-stable &
uswm app -- qutebrowser &
uswm app -- alacritty &
uwsm-app -- kanshi &
# Hyprland ecosystem stuff
hyprpolkitagent &
uwsm-app -- hypridle &
uwsm-app -- hyprpaper &
# espanso (text expander)
uwsm-app -- espanso start &
# notification daemon
uwsm-app -- dunst &
# clipboard
wl-paste --watch cliphist store &
wl-clip-persist --clipboard regular &
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env zsh
while read -r input; do
case "${input}" in
'Begin...')
wtype -k Escape
wtype "I$(date '+%F %T: Begin ')"
;;
'End...')
wtype -k Escape
wtype "I$(date '+%F %T: End ')"
wtype -k Escape
wtype 'kly$jpo'
wtype "$(date '+%F %T: Begin ')"
;;
esac
done
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env zsh
printf "%s\n%s" "Begin..." "End..."