aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorMohammad Reza Karimi <m.r.karimi.j@gmail.com>2026-01-04 21:28:36 -0500
committerMohammad Reza Karimi <m.r.karimi.j@gmail.com>2026-01-04 21:28:36 -0500
commit06d1242317f7159ccf3014f0a1480e7c56236ebb (patch)
tree89863b3287ae2c7cc88cd532220f18c38e8d8657 /scripts
parent5a41da5881a11ba3fdc3890c342aa3b7eb53e0cf (diff)
add all sorts of things
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/dot-local/bin/rotdir12
-rwxr-xr-xscripts/dot-local/bin/screenshot-hypr82
-rwxr-xr-xscripts/dot-local/bin/shortcuts46
-rwxr-xr-xscripts/dot-local/bin/stowify74
-rwxr-xr-xscripts/dot-local/bin/update-led-mute16
5 files changed, 230 insertions, 0 deletions
diff --git a/scripts/dot-local/bin/rotdir b/scripts/dot-local/bin/rotdir
new file mode 100755
index 0000000..d171f29
--- /dev/null
+++ b/scripts/dot-local/bin/rotdir
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# When I open an image from the file manager in nsxiv (the image viewer), I want
+# to be able to press the next/previous keys to key through the rest of the
+# images in the same directory. This script "rotates" the content of a
+# directory based on the first chosen file, so that if I open the 15th image,
+# if I press next, it will go to the 16th etc. Autistic, I know, but this is
+# one of the reasons that nsxiv is great for being able to read standard input.
+
+[ -z "$1" ] && echo "usage: rotdir regex 2>&1" && exit 1
+base="$(basename "$1")"
+ls "$PWD" | awk -v BASE="$base" 'BEGIN { lines = ""; m = 0; } { if ($0 == BASE) { m = 1; } } { if (!m) { if (lines) { lines = lines"\n"; } lines = lines""$0; } else { print $0; } } END { print lines; }'
diff --git a/scripts/dot-local/bin/screenshot-hypr b/scripts/dot-local/bin/screenshot-hypr
new file mode 100755
index 0000000..d949a80
--- /dev/null
+++ b/scripts/dot-local/bin/screenshot-hypr
@@ -0,0 +1,82 @@
+#!/usr/bin/env bash
+
+OUTPUT_DIR="$HOME/Pictures/scrots"
+TIMESTAMP="$(date +'%Y-%m-%d_%H-%M-%S')"
+OUTPUT_FILE="$OUTPUT_DIR/screenshot-$TIMESTAMP.png"
+
+pkill slurp && exit 0
+
+MODE="${1:-smart}"
+PROCESSING="${2:-slurp}"
+
+get_rectangles()
+{
+ local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id')
+ hyprctl monitors -j | jq -r --arg ws "$active_workspace" '.[] | select(.activeWorkspace.id == ($ws | tonumber)) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"'
+ hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"'
+}
+
+# Select based on mode
+case "$MODE" in
+ region)
+ wayfreeze &
+ PID=$!
+ sleep .1
+ SELECTION=$(slurp 2>/dev/null)
+ kill $PID 2>/dev/null
+ ;;
+ windows)
+ wayfreeze &
+ PID=$!
+ sleep .1
+ SELECTION=$(get_rectangles | slurp -r 2>/dev/null)
+ kill $PID 2>/dev/null
+ ;;
+ fullscreen)
+ SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"')
+ ;;
+ smart | *)
+ RECTS=$(get_rectangles)
+ wayfreeze &
+ PID=$!
+ sleep .1
+ SELECTION=$(echo "$RECTS" | slurp 2>/dev/null)
+ kill $PID 2>/dev/null
+
+ # If the selction area is L * W < 20, we'll assume you were trying to select whichever
+ # window or output it was inside of to prevent accidental 2px snapshots
+ if [[ "$SELECTION" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]]; then
+ if ((${BASH_REMATCH[3]} * ${BASH_REMATCH[4]} < 20)); then
+ click_x="${BASH_REMATCH[1]}"
+ click_y="${BASH_REMATCH[2]}"
+
+ while IFS= read -r rect; do
+ if [[ "$rect" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+) ]]; then
+ rect_x="${BASH_REMATCH[1]}"
+ rect_y="${BASH_REMATCH[2]}"
+ rect_width="${BASH_REMATCH[3]}"
+ rect_height="${BASH_REMATCH[4]}"
+
+ if ((click_x >= rect_x && click_x < rect_x + rect_width && click_y >= rect_y && click_y < rect_y + rect_height)); then
+ SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}"
+ break
+ fi
+ fi
+ done <<<"$RECTS"
+ fi
+ fi
+ ;;
+esac
+
+[ -z "$SELECTION" ] && exit 0
+
+if [[ $PROCESSING == "slurp" ]]; then
+ grim -g "$SELECTION" - |
+ satty --filename - \
+ --output-filename "$OUTPUT_FILE" \
+ --actions-on-enter="save-to-file,exit" \
+ --actions-on-escape="save-to-clipboard,exit" \
+ --initial-tool=arrow
+else
+ grim -g "$SELECTION" - | wl-copy
+fi
diff --git a/scripts/dot-local/bin/shortcuts b/scripts/dot-local/bin/shortcuts
new file mode 100755
index 0000000..d5644c0
--- /dev/null
+++ b/scripts/dot-local/bin/shortcuts
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+confdir="${XDG_CONFIG_HOME:-$HOME/.config}/shellshort"
+
+bmdirs="$confdir/bm-dirs"
+bmfiles="$confdir/bm-files"
+
+# Output locations. Unactivated progs should go to /dev/null.
+shell_shortcuts="$confdir/shortcutrc"
+shell_env_shortcuts="/dev/null"
+zsh_named_dirs="/dev/null"
+lf_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/lf/shortcutrc"
+vim_shortcuts="/dev/null"
+qute_shortcuts="/dev/null"
+fish_shortcuts="/dev/null"
+vifm_shortcuts="/dev/null"
+
+# Remove, prepare files
+rm -f "$lf_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" "$vim_shortcuts" 2>/dev/null
+printf "# vim: filetype=sh\\n" >"$fish_shortcuts"
+printf "# vim: filetype=sh\\nalias " >"$shell_shortcuts"
+printf "# vim: filetype=sh\\n" >"$shell_env_shortcuts"
+printf "\" vim: filetype=vim\\n" >"$vifm_shortcuts"
+
+# Format the `directories` file in the correct syntax and sent it to all three configs.
+eval "echo \"$(cat "$bmdirs")\"" |
+ awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
+ printf(\"%s=\42cd %s && ls -A\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ;
+ printf(\"[ -n \42%s\42 ] && export %s=\42%s\42 \n\",\$1,\$1,\$2) >> \"$shell_env_shortcuts\" ;
+ printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
+ printf(\"abbr %s \42cd %s; and ls -A\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ;
+ printf(\"map g%s :cd %s<CR>\nmap t%s <tab>:cd %s<CR><tab>\nmap M%s <tab>:cd %s<CR><tab>:mo<CR>\nmap Y%s <tab>:cd %s<CR><tab>:co<CR> \n\",\$1,\$2, \$1, \$2, \$1, \$2, \$1, \$2) >> \"$vifm_shortcuts\" ;
+ printf(\"config.bind(';%s', \42set downloads.location.directory %s ;; hint links download\42) \n\",\$1,\$2) >> \"$qute_shortcuts\" ;
+ printf(\"map C%s cd \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
+ printf(\"vim.keymap.set('c', ';%s', '%s', { noremap=true })\n\",\$1,\$2) >> \"$vim_shortcuts\" }"
+
+# Format the `files` file in the correct syntax and sent it to both configs.
+eval "echo \"$(cat "$bmfiles")\"" |
+ awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
+ printf(\"%s=\42\$EDITOR %s\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ;
+ printf(\"[ -n \42%s\42 ] && export %s=\42%s\42 \n\",\$1,\$1,\$2) >> \"$shell_env_shortcuts\" ;
+ printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
+ printf(\"abbr %s \42\$EDITOR %s\42 \n\",\$1,\$2) >> \"$fish_shortcuts\" ;
+ printf(\"map %s :e %s<CR> \n\",\$1,\$2) >> \"$vifm_shortcuts\" ;
+ printf(\"map E%s \$\$EDITOR \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
+ printf(\"vim.keymap.set('c', ';%s', '%s', { noremap=true })\n\",\$1,\$2) >> \"$vim_shortcuts\" }"
diff --git a/scripts/dot-local/bin/stowify b/scripts/dot-local/bin/stowify
new file mode 100755
index 0000000..fb51025
--- /dev/null
+++ b/scripts/dot-local/bin/stowify
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+
+set -Eeuo pipefail
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 <source1> [source2 ...] <package_name>"
+ return 1
+fi
+
+pkg="${@:$#}"
+stowdir="$HOME/dotfiles"
+sources=("${@:1:$#-1}")
+
+mkdir -p "$stowdir/$pkg"
+
+_stowify_convert_path() {
+ local rel_path="$1"
+ local IFS='/'
+ local parts out_parts part
+
+ read -ra parts <<<"$rel_path"
+ for part in "${parts[@]}"; do
+ if [[ $part == .* ]]; then
+ out_parts+=("dot-${part#.}")
+ else
+ out_parts+=("$part")
+ fi
+ done
+
+ local out=""
+ for part in "${out_parts[@]}"; do
+ if [ -z "$out" ]; then
+ out="$part"
+ else
+ out="$out/$part"
+ fi
+ done
+ printf '%s\n' "$out"
+}
+
+for src in "${sources[@]}"; do
+ src="$(realpath -m "$src")" # expand to absolute path
+
+ if [ ! -e "$src" ]; then
+ echo "Error: $src does not exist"
+ continue
+ fi
+
+ if [[ $src == "$HOME"/* ]]; then
+ rel_path="${src#"$HOME"/}"
+ else
+ echo "Warning: $src is not under \$HOME — skipping"
+ continue
+ fi
+
+ conv_rel_path="$(_stowify_convert_path "$rel_path")" || continue
+
+ dest_path="$stowdir/$pkg/$conv_rel_path"
+ dest_dir="$(dirname "$dest_path")"
+
+ echo "$dest_dir"
+ echo "$dest_path"
+
+ mkdir -pv "$dest_dir" || {
+ echo "Failed to create $dest_dir"
+ continue
+ }
+ mv -v "$src" "$dest_path" || {
+ echo "Failed to move $src"
+ continue
+ }
+done
+
+stow -d "$stowdir" -v --dotfiles "$pkg"
diff --git a/scripts/dot-local/bin/update-led-mute b/scripts/dot-local/bin/update-led-mute
new file mode 100755
index 0000000..49832e1
--- /dev/null
+++ b/scripts/dot-local/bin/update-led-mute
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+case $1 in
+ source) # mic
+ val=$(wpctl get-volume '@DEFAULT_AUDIO_SOURCE@' | grep -q MUTED && echo 1 || echo 0)
+ echo "$val" | sudo tee /sys/class/leds/platform::micmute/brightness
+ ;;
+ sink) # speaker
+ val=$(wpctl get-volume '@DEFAULT_AUDIO_SINK@' | grep -q MUTED && echo 1 || echo 0)
+ echo "$val" | sudo tee /sys/class/leds/platform::mute/brightness
+ ;;
+ *)
+ echo "Usage: $0 source|sink"
+ exit 1
+ ;;
+esac