aboutsummaryrefslogtreecommitdiff
path: root/.local/bin
diff options
context:
space:
mode:
authorkrolxon <krolyxon@tutanota.com>2025-08-16 20:49:05 +0530
committerkrolxon <krolyxon@tutanota.com>2025-08-16 20:49:05 +0530
commitf3bdd21020b8e618433a06c1efc1cc665cb6839d (patch)
tree32427d47c079637b670a20b62e0339df0e248641 /.local/bin
first commit using stow
Diffstat (limited to '.local/bin')
-rwxr-xr-x.local/bin/bcn24
-rwxr-xr-x.local/bin/cam2
-rwxr-xr-x.local/bin/compiletex5
-rwxr-xr-x.local/bin/ext45
-rwxr-xr-x.local/bin/madd23
-rwxr-xr-x.local/bin/mounter41
-rwxr-xr-x.local/bin/movie12
-rwxr-xr-x.local/bin/rofipass9
-rwxr-xr-x.local/bin/rofiunicode13
-rwxr-xr-x.local/bin/screenshot18
-rwxr-xr-x.local/bin/setwall52
-rwxr-xr-x.local/bin/sysact23
-rwxr-xr-x.local/bin/tms25
-rwxr-xr-x.local/bin/transadd14
-rwxr-xr-x.local/bin/ufetch83
-rwxr-xr-x.local/bin/unmounter22
-rwxr-xr-x.local/bin/upfile13
-rwxr-xr-x.local/bin/vimv46
-rwxr-xr-x.local/bin/waldl158
19 files changed, 628 insertions, 0 deletions
diff --git a/.local/bin/bcn b/.local/bin/bcn
new file mode 100755
index 0000000..1c64085
--- /dev/null
+++ b/.local/bin/bcn
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+#bcn, Bluetooth Connect
+
+
+device_amount=$(bluetoothctl devices | wc -l)
+
+if [[ $device_amount = 1 ]]; then
+ MAC=$(bluetoothctl devices | awk {'print $2'})
+ [ -z $MAC ] && MAC=NoDeviceFound # Prevents accidental disconnect error
+else
+ select=$(bluetoothctl devices | awk {'print $3'} | rofi -dmenu -l 10 -fn Monospace-15)
+ MAC=$(bluetoothctl devices | grep $select | awk {'print $2'})
+ [ -z $MAC ] && MAC=NoDeviceFound # Prevents accidental disconnect error
+fi
+
+connect=$(bluetoothctl info $MAC | grep Connected: | awk '{print $2}')
+if [[ $connect = no ]]; then
+ notify-send "Attempting to connect to $select"
+ bluetoothctl connect $MAC || notify-send "Failed to Connect"
+elif [[ $connect = yes ]]; then
+ notify-send "Attempting to disconnect $select"
+ bluetoothctl disconnect $MAC
+fi
diff --git a/.local/bin/cam b/.local/bin/cam
new file mode 100755
index 0000000..368ce03
--- /dev/null
+++ b/.local/bin/cam
@@ -0,0 +1,2 @@
+#!/bin/sh
+mpv --untimed --no-cache --no-osc --no-input-default-bindings --profile=low-latency --input-conf=/dev/null --title=webcam /dev/video0
diff --git a/.local/bin/compiletex b/.local/bin/compiletex
new file mode 100755
index 0000000..cf9ba44
--- /dev/null
+++ b/.local/bin/compiletex
@@ -0,0 +1,5 @@
+#!/bin/bash
+tmpdir=$(mktemp -d)
+pdflatex -output-directory="$tmpdir" "$1"
+mv "$tmpdir"/*.pdf .
+rm -rf "$tmpdir"
diff --git a/.local/bin/ext b/.local/bin/ext
new file mode 100755
index 0000000..9810c83
--- /dev/null
+++ b/.local/bin/ext
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# A general, all-purpose extraction script. Not all extraction programs here
+# are installed by LARBS automatically.
+#
+# Default behavior: Extract archive into new directory
+# Behavior with `-c` option: Extract contents into current directory
+
+while getopts "hc" o; do case "${o}" in
+ c) extracthere="True" ;;
+ *) printf "Options:\\n -c: Extract archive into current directory rather than a new one.\\n" && exit 1 ;;
+esac done
+
+if [ -z "$extracthere" ]; then
+ archive="$(readlink -f "$*")" &&
+ directory="$(echo "$archive" | sed 's/\.[^\/.]*$//')" &&
+ mkdir -p "$directory" &&
+ cd "$directory" || exit 1
+else
+ archive="$(readlink -f "$(echo "$*" | cut -d' ' -f2)" 2>/dev/null)"
+fi
+
+[ -z "$archive" ] && printf "Give archive to extract as argument.\\n" && exit 1
+
+if [ -f "$archive" ] ; then
+ case "$archive" in
+ *.tar.bz2|*.tbz2) bsdtar -xf "$archive" ;;
+ *.tar.xz) bsdtar -xf "$archive" ;;
+ *.tar.gz|*.tgz) bsdtar -xf "$archive" ;;
+ *.tar.zst) bsdtar -xf "$archive" ;;
+ *.tar) bsdtar -xf "$archive" ;;
+ *.lzma) unlzma "$archive" ;;
+ *.bz2) bunzip2 "$archive" ;;
+ *.rar) unrar x -ad "$archive" ;;
+ *.gz) gunzip "$archive" ;;
+ *.zip) unzip "$archive" ;;
+ *.Z) uncompress "$archive" ;;
+ *.7z) 7z x "$archive" ;;
+ *.xz) unxz "$archive" ;;
+ *.exe) cabextract "$archive" ;;
+ *) printf "extract: '%s' - unknown archive method\\n" "$archive" ;;
+ esac
+else
+ printf "File \"%s\" not found.\\n" "$archive"
+fi \ No newline at end of file
diff --git a/.local/bin/madd b/.local/bin/madd
new file mode 100755
index 0000000..d1cb8ef
--- /dev/null
+++ b/.local/bin/madd
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+madd() {
+ queue="$(mpc playlist)"
+ if [ -z "$queue" ]; then
+ mpc insert "$filename"
+ mpc play
+ else
+ mpc insert "$filename"
+ mpc next
+ fi
+}
+
+if [ -t 0 ]; then
+ filename=$(mpc listall | fzf)
+else
+ filename=$(mpc listall | rofi -dmenu -l 30 -case-smart)
+fi
+
+if [ -n "$filename" ]; then
+ madd
+fi
+
diff --git a/.local/bin/mounter b/.local/bin/mounter
new file mode 100755
index 0000000..38d3c9c
--- /dev/null
+++ b/.local/bin/mounter
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# Gives a rofi -dmenu prompt to mount unmounted drives. If
+# they're in /etc/fstab, they'll be mounted automatically. Otherwise, you'll
+# be prompted to give a mountpoint from already existsing directories. If you
+# input a novel directory, it will prompt you to create that directory.
+
+getmount() { \
+ [ -z "$chosen" ] && exit 1
+ # shellcheck disable=SC2086
+ mp="$(find $1 2>/dev/null | rofi -dmenu -i -p "Type in mount point.")" || exit 1
+ test -z "$mp" && exit 1
+ if [ ! -d "$mp" ]; then
+ mkdiryn=$(printf "No\\nYes" | rofi -dmenu -i -p "$mp does not exist. Create it?") || exit 1
+ [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp")
+ fi
+ }
+
+mountusb() { \
+ chosen="$(echo "$usbdrives" | rofi -dmenu -i -p "Mount which drive?")" || exit 1
+ chosen="$(echo "$chosen" | awk '{print $1}')"
+ sudo -A mount "$chosen" 2>/dev/null && notify-send "💻 USB mounting" "$chosen mounted." && exit 0
+ alreadymounted=$(lsblk -nrpo "name,type,mountpoint" | awk '$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not ( -path *%s -prune ) ",$3}')
+ getmount "/mnt /media /mount /home -maxdepth 5 -type d $alreadymounted"
+ partitiontype="$(lsblk -no "fstype" "$chosen")"
+ case "$partitiontype" in
+ "vfat") sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000;;
+ "exfat") sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)";;
+ *) sudo -A mount "$chosen" "$mp"; user="$(whoami)"; ug="$(groups | awk '{print $1}')"; sudo -A chown "$user":"$ug" "$mp";;
+ esac
+ notify-send "💻 USB mounting" "$chosen mounted to $mp."
+ }
+
+usbdrives="$(lsblk -rpo "name,type,size,mountpoint" | grep 'part\|rom' | awk '$4==""{printf "%s (%s)\n",$1,$3}')"
+
+if [ -z "$usbdrives" ]; then
+ echo "No USB drive detected" && exit
+else
+ echo "USB drive(s) detected."
+ mountusb
+fi
diff --git a/.local/bin/movie b/.local/bin/movie
new file mode 100755
index 0000000..4ceb432
--- /dev/null
+++ b/.local/bin/movie
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+
+if [ -t 0 ]; then
+ filename="$(find ~/media/movies/ -type f -regex ".*\.\(mkv\|mp4\|mpeg\|avi\|mov\|webm\)" -printf "%f\n" | sort | fzf)"
+else
+ filename="$(find ~/media/movies/ -type f -regex ".*\.\(mkv\|mp4\|mpeg\|avi\|mov\|webm\)" -printf "%f\n" | sort | rofi -case-smart -matching "fuzzy" -dmenu -l 25)"
+fi
+
+filepath="$(find ~/media/movies/ -type f -regex ".*\.\(mkv\|mp4\|mpeg\|avi\|mov\|webm\)")"
+mpv "$(grep "$filename" <<< "$filepath")"
+
diff --git a/.local/bin/rofipass b/.local/bin/rofipass
new file mode 100755
index 0000000..b1bf6a3
--- /dev/null
+++ b/.local/bin/rofipass
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Take password prompt from STDIN, print password to STDOUT
+# the sed piece just removes the colon from the provided
+# prompt: rofi -p already gives us a colon
+rofi -dmenu \
+ -password \
+ -no-fixed-num-lines \
+ -p "$(printf "$1" | sed s/://)"
diff --git a/.local/bin/rofiunicode b/.local/bin/rofiunicode
new file mode 100755
index 0000000..d6d4239
--- /dev/null
+++ b/.local/bin/rofiunicode
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# The famous "get a menu of emojis to copy" script.
+
+# Get user selection via dmenu from emoji file.
+chosen=$(cut -d ';' -f1 ~/.local/share/chars/* | rofi -dmenu -i -l 30 | sed "s/ .*//")
+
+# Exit if none chosen.
+[ -z "$chosen" ] && exit
+
+wtype "$chosen"
+printf "$chosen" | wl-copy
+notify-send "'$chosen' copied to clipboard." &
diff --git a/.local/bin/screenshot b/.local/bin/screenshot
new file mode 100755
index 0000000..3cb9b0f
--- /dev/null
+++ b/.local/bin/screenshot
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+ocr_cmd="wl-copy"
+
+case "$(printf "a selected area (copy)\ncurrent window (copy)\nfull screen (copy)\na selected area\ncurrent window\nfull screen\na selected area (OCR)" | rofi -dmenu -l 7 -i -p "Screenshot which area?")" in
+ "a selected area (copy)") hyprshot -m region --clipboard-only ;;
+ "current window (copy)") hyprshot -m window --clipboard-only ;;
+ "full screen (copy)") hyprshot -m output --clipboard-only ;;
+
+ "a selected area") hyprshot -m region -o ~/pix/ss -f "pic-selected-$(uuidgen | awk -F- '{printf $2}')-$(date '+%y-%m-%d').png" ;;
+ "current window") hyprshot -m window -o ~/pix/ss -f "pic-window-$(uuidgen | awk -F- '{printf $2}')-$(date '+%y-%m-%d').png" ;;
+ "full screen") hyprshot -m output -o ~/pix/ss -f "pic-full-$(uuidgen | awk -F- '{printf $2}')-$(date '+%y-%m-%d').png" ;;
+
+ "a selected area (OCR)") tmpfile=$(mktemp /tmp/ocr-XXXXXX.png) && \
+ hyprshot -m region -o "$(dirname "$tmpfile")" -f "$(basename "$tmpfile")" && \
+ tesseract "$tmpfile" - -l eng | ${ocr_cmd} && rm "$tmpfile" ;;
+esac
+
diff --git a/.local/bin/setwall b/.local/bin/setwall
new file mode 100755
index 0000000..36c46db
--- /dev/null
+++ b/.local/bin/setwall
@@ -0,0 +1,52 @@
+#!/bin/bash
+WALL_DIR="$HOME/pix/wallpapers/onedarkwallpapers/"
+MODE="random"
+CUSTOM_PATH=""
+
+# Parse options
+while getopts ":mp:" opt; do
+ case $opt in
+ m) MODE="menu" ;;
+ p) MODE="path"; CUSTOM_PATH="$OPTARG" ;;
+ \?) echo "Usage: $0 [-m] [-p /path/to/image]" >&2; exit 1 ;;
+ :) echo "Option -$OPTARG requires an argument." >&2; exit 1 ;;
+ esac
+done
+
+# Choose wallpaper
+case $MODE in
+ random)
+ NEW_WALL=$(find "$WALL_DIR" -type f | shuf -n 1)
+ ;;
+ path)
+ if [[ -f "$CUSTOM_PATH" ]]; then
+ NEW_WALL="$CUSTOM_PATH"
+ else
+ echo "Error: File not found -> $CUSTOM_PATH" >&2
+ exit 1
+ fi
+ ;;
+ menu)
+ WALLPAPER_LIST=$(find "$WALL_DIR" -type f | sort | sed "s|$WALL_DIR||")
+ CHOSEN=$(echo "$WALLPAPER_LIST" | rofi -dmenu -i -p "Choose wallpaper:")
+ if [[ -z "$CHOSEN" ]]; then
+ NEW_WALL=$(find "$WALL_DIR" -type f | shuf -n 1)
+ else
+ NEW_WALL="$WALL_DIR$CHOSEN"
+ fi
+ ;;
+esac
+
+# Apply wallpaper
+if ! pgrep -x hyprpaper >/dev/null; then
+ # Hyprpaper not running → start with chosen wallpaper
+ cat > ~/.config/hypr/hyprpaper.conf <<EOF
+preload = $NEW_WALL
+wallpaper = ,$NEW_WALL
+EOF
+ hyprpaper &
+else
+ # Hyprpaper is running → change it live
+ hyprctl hyprpaper preload "$NEW_WALL"
+ hyprctl hyprpaper wallpaper ",$NEW_WALL"
+fi
diff --git a/.local/bin/sysact b/.local/bin/sysact
new file mode 100755
index 0000000..5ea92fa
--- /dev/null
+++ b/.local/bin/sysact
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+export WM="Hyprland"
+case "$(readlink -f /sbin/init)" in
+ *systemd*) ctl='systemctl' ;;
+ *) ctl='loginctl' ;;
+esac
+
+wmpid(){ # Get Hyprland process PID
+ pgrep -o hyprland
+}
+
+case "$(printf " lock\n󰠚 leave $WM\n renew $WM\n󱣻 hibernate\n reboot\n shutdown\n sleep\n display off" | rofi -dmenu -i -l 15 -p 'Action: ')" in
+ ' lock') hyprlock ;;
+ "ó° š leave $WM") kill -TERM "$(wmpid)" ;;
+ " renew $WM") hyprctl reload ;;
+ 'ó±£» hibernate') $ctl hibernate -i ;;
+ ' sleep') $ctl suspend -i ;;
+ ' reboot') $ctl reboot -i ;;
+ ' shutdown') $ctl poweroff -i ;;
+ 'ï“¢ display off') hyprctl dispatch dpms off ;;
+ *) exit 1 ;;
+esac
diff --git a/.local/bin/tms b/.local/bin/tms
new file mode 100755
index 0000000..f6e9b97
--- /dev/null
+++ b/.local/bin/tms
@@ -0,0 +1,25 @@
+#!/bin/env bash
+
+if [[ $# -eq 1 ]]; then
+ selected=$1;
+else
+ selected=$(find ~/code/dev ~/code/repos ~/code/rust -mindepth 1 -maxdepth 1 -type d | fzf);
+fi
+
+if [[ -z $selected ]]; then
+ exit 0
+fi
+
+selected_name=$(basename "$selected" | tr . _)
+tmux_running=$(pgrep tmux)
+
+if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then
+ tmux new-session -s $selected_name -c $selected
+ exit 0
+fi
+
+if ! tmux has-session -t=$selected_name 2> /dev/null; then
+ tmux new-session -ds $selected_name -c $selected
+fi
+
+tmux switch-client -t $selected_name
diff --git a/.local/bin/transadd b/.local/bin/transadd
new file mode 100755
index 0000000..652150c
--- /dev/null
+++ b/.local/bin/transadd
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Starting transmission-daemon if not already running
+# transmission-daemon sometimes fails to take remote requests in its first moments, hence the sleep.
+pidof transmission-daemon >/dev/null || (transmission-daemon && notify-send "Starting transmission daemon...")
+sleep 3
+
+# adding the Torrent
+if [ -z "$*" ]; then
+ magnetlink="$(wl-paste)"
+ transmission-remote -a "$magnetlink" && notify-send "🔽 Torrent added."
+else
+ transmission-remote -a "$@" && notify-send "🔽 Torrent added."
+fi
diff --git a/.local/bin/ufetch b/.local/bin/ufetch
new file mode 100755
index 0000000..eb29af3
--- /dev/null
+++ b/.local/bin/ufetch
@@ -0,0 +1,83 @@
+#!/bin/sh
+#
+# ufetch-arch - tiny system info for arch
+
+## INFO
+
+# user is already defined
+host="$(cat /etc/hostname)"
+os='Arch Linux'
+kernel="$(uname -sr)"
+uptime="$(uptime -p | sed 's/up //')"
+packages="$(pacman -Q | wc -l)"
+shell="$(basename "${SHELL}")"
+
+## UI DETECTION
+
+parse_rcs() {
+ for f in "${@}"; do
+ wm="$(tail -n 1 "${f}" 2> /dev/null | cut -d ' ' -f 2)"
+ [ -n "${wm}" ] && echo "${wm}" && return
+ done
+}
+
+rcwm="$(parse_rcs "${HOME}/.xinitrc" "${HOME}/.xsession")"
+
+ui='unknown'
+uitype='UI'
+if [ -n "${DE}" ]; then
+ ui="${DE}"
+ uitype='DE'
+elif [ -n "${WM}" ]; then
+ ui="${WM}"
+ uitype='WM'
+elif [ -n "${XDG_CURRENT_DESKTOP}" ]; then
+ ui="${XDG_CURRENT_DESKTOP}"
+ uitype='DE'
+elif [ -n "${DESKTOP_SESSION}" ]; then
+ ui="${DESKTOP_SESSION}"
+ uitype='DE'
+elif [ -n "${rcwm}" ]; then
+ ui="${rcwm}"
+ uitype='WM'
+elif [ -n "${XDG_SESSION_TYPE}" ]; then
+ ui="${XDG_SESSION_TYPE}"
+fi
+
+ui="$(basename "${ui}")"
+
+## DEFINE COLORS
+
+# probably don't change these
+if [ -x "$(command -v tput)" ]; then
+ bold="$(tput bold)"
+ black="$(tput setaf 0)"
+ red="$(tput setaf 1)"
+ green="$(tput setaf 2)"
+ yellow="$(tput setaf 3)"
+ blue="$(tput setaf 4)"
+ magenta="$(tput setaf 5)"
+ cyan="$(tput setaf 6)"
+ white="$(tput setaf 7)"
+ reset="$(tput sgr0)"
+fi
+
+# you can change these
+lc="${reset}${bold}${blue}" # labels
+nc="${reset}${bold}${blue}" # user and hostname
+ic="${reset}" # info
+c0="${reset}${blue}" # first color
+
+## OUTPUT
+
+cat <<EOF
+
+${c0} /\\ ${nc}${USER}${ic}@${nc}${host}${reset}
+${c0} / \\ ${lc}OS: ${ic}${os}${reset}
+${c0} /\\ \\ ${lc}KERNEL: ${ic}${kernel}${reset}
+${c0} / __ \\ ${lc}UPTIME: ${ic}${uptime}${reset}
+${c0} / ( ) \\ ${lc}PACKAGES: ${ic}${packages}${reset}
+${c0} / __| |__\\\\ ${lc}SHELL: ${ic}${shell}${reset}
+${c0} /.\` \`.\\ ${lc}${uitype}: ${ic}${ui}${reset}
+
+EOF
diff --git a/.local/bin/unmounter b/.local/bin/unmounter
new file mode 100755
index 0000000..184b3ae
--- /dev/null
+++ b/.local/bin/unmounter
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# A rofi -dmenu prompt to unmount drives.
+# Provides you with mounted partitions, select one to unmount.
+# Drives mounted at /, /boot and /home will not be options to unmount.
+
+unmountusb() {
+ [ -z "$drives" ] && exit
+ chosen="$(echo "$drives" | rofi -dmenu -i -p "Unmount which drive?")" || exit 1
+ chosen="$(echo "$chosen" | awk '{print $1}')"
+ [ -z "$chosen" ] && exit
+ sudo -A umount "$chosen" && notify-send "💻 USB unmounting" "$chosen unmounted."
+ }
+
+drives=$(lsblk -nrpo "name,type,size,mountpoint,label" | awk -F':' '{gsub(/ /,":")}$4!~/\/boot|\/efi|\/home$|SWAP/&&length($4)>1{printf "%s (%s) %s\n",$4,$3,$5}')
+
+if [ -z "$drives" ]; then
+ echo "No drives to unmount." && exit
+else
+ echo "Unmountable USB drive detected."
+ unmountusb
+fi
diff --git a/.local/bin/upfile b/.local/bin/upfile
new file mode 100755
index 0000000..78c0321
--- /dev/null
+++ b/.local/bin/upfile
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if [ -n "$1" ]; then
+ file=$1
+else
+ file=$(find . -maxdepth 2 -type f | fzf)
+fi
+
+[ -z "$file" ] && exit
+
+# curl -F"file=@$file" 0x0.st | xclip -sel c
+curl -F"file=@$file" 0.vern.cc | xclip -sel c
+notify-send "The url has been copied to your clipboard. $(xclip -sel c -o)"
diff --git a/.local/bin/vimv b/.local/bin/vimv
new file mode 100755
index 0000000..81f85a2
--- /dev/null
+++ b/.local/bin/vimv
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+set -eu
+
+# Lists the current directory's files in Vim, so you can edit it and save to rename them
+# USAGE: vimv [file1 file2]
+# https://github.com/thameera/vimv
+
+declare -r FILENAMES_FILE=$(mktemp "${TMPDIR:-/tmp}/vimv.XXX")
+
+trap '{ rm -f "${FILENAMES_FILE}" ; }' EXIT
+
+if [ $# -ne 0 ]; then
+ src=( "$@" )
+else
+ # in this line where is says src=($(ls)), you can change the "ls" to "exa"
+ # if you want the proper number sorting.
+ IFS=$'\r\n' GLOBIGNORE='*' command eval 'src=($(ls))'
+fi
+
+for ((i=0;i<${#src[@]};++i)); do
+ echo "${src[i]}" >> "${FILENAMES_FILE}"
+done
+
+${EDITOR:-vi} "${FILENAMES_FILE}"
+
+IFS=$'\r\n' GLOBIGNORE='*' command eval 'dest=($(cat "${FILENAMES_FILE}"))'
+
+if (( ${#src[@]} != ${#dest[@]} )); then
+ echo "WARN: Number of files changed. Did you delete a line by accident? Aborting.." >&2
+ exit 1
+fi
+
+declare -i count=0
+for ((i=0;i<${#src[@]};++i)); do
+ if [ "${src[i]}" != "${dest[i]}" ]; then
+ mkdir -p "$(dirname "${dest[i]}")"
+ if git ls-files --error-unmatch "${src[i]}" > /dev/null 2>&1; then
+ git mv "${src[i]}" "${dest[i]}"
+ else
+ mv "${src[i]}" "${dest[i]}"
+ fi
+ ((++count))
+ fi
+done
+
+echo "$count" files renamed.
diff --git a/.local/bin/waldl b/.local/bin/waldl
new file mode 100755
index 0000000..48f8fa9
--- /dev/null
+++ b/.local/bin/waldl
@@ -0,0 +1,158 @@
+#!/bin/sh
+
+# https://github.com/pystardust/waldl
+# script to find and download wallpapers from wallhaven
+version="0.0.1"
+
+# Usage:
+# waldl <query>
+# if query left empty then sh_menu will be used (dmenu by default)
+# after the thumbnails are cached, nsxiv would open up with the thumbnails
+# Select the wallpapers using `m` on the image. ( marking the image in nsxiv )
+# press `q` to quit nsxiv, the marked images would start downloading
+
+####################
+## User variables ##
+####################
+
+# the dir where wallpapers are stored
+walldir="$HOME/pix/wallhaven"
+# the dir used to cache thumbnails
+cachedir="$HOME/.cache/wallhaven"
+# nsxiv options
+nsxiv_otps=" -tfpo -z 200" # o is needed for selection
+# number of pages to show in search results
+# each page contains 24 results
+max_pages=4
+# sorting : date_added, relevance, random, views, favorites, toplist
+sorting=relevance
+# quality : large original small
+quality=large
+# atleast : least res
+atleast=1920x1080
+
+# the menu command used when no query is provided
+sh_menu () {
+ : | dmenu -p "search wallhaven: "
+ # ROFI: comment the previous line and uncomment the next line for rofi
+ # rofi -dmenu -l 0 -p "search wallpapers"
+}
+
+##########################
+## getting search query ##
+##########################
+
+[ -n "$*" ] && query="$*" || query=$( sh_menu )
+[ -z "$query" ] && exit 1
+query=$(printf '%s' "$query" | tr ' ' '+' )
+
+######################
+## start up commands #
+######################
+
+rm -rf "$cachedir"
+mkdir -p "$walldir" "$cachedir"
+
+# progress display command
+sh_info () {
+ printf "%s\n" "$1" >&2
+ notify-send "wallhaven" "$1"
+ [ -n "$2" ] && exit "$2"
+}
+
+# dependency checking
+dep_ck () {
+ for pr; do
+ command -v $pr >/dev/null 2>&1 || sh_info "command $pr not found, install: $pr" 1
+ done
+}
+dep_ck "nsxiv" "curl" "jq"
+
+
+# clean up command that would be called when the program exits
+clean_up () {
+ printf "%s\n" "cleaning up..." >&2
+ rm -rf "$datafile" "$cachedir"
+}
+
+# data file to store the api information
+datafile="/tmp/wald.$$"
+
+# clean up if killed
+trap "exit" INT TERM
+trap "clean_up" EXIT
+
+##################
+## getting data ##
+##################
+
+# request the search results for each page
+get_results () {
+ for page_no in $(seq $max_pages)
+ do
+ {
+ json=$(curl -s -G "https://wallhaven.cc/api/v1/search" \
+ -d "q=$1" \
+ -d "page=$page_no" \
+ -d "atleast=$atleast" \
+ -d "sorting=$sorting"
+ )
+ printf "%s\n" "$json" >> "$datafile"
+ } &
+ sleep 0.001
+ done
+ wait
+}
+
+# search wallpapers
+sh_info "getting data..."
+get_results "$query"
+
+# check if data file is empty, if so then exit
+[ -s "$datafile" ] || sh_info "no images found" 1
+
+############################
+## downloading thumbnails ##
+############################
+
+# get a list of thumnails from the data
+thumbnails=$( jq -r '.data[]?|.thumbs.'"$quality" < "$datafile")
+
+[ -z "$thumbnails" ] && sh_info "no-results found" 1
+
+# download the thumbnails
+sh_info "caching thumbnails..."
+for url in $thumbnails
+do
+ printf "url = %s\n" "$url"
+ printf "output = %s\n" "$cachedir/${url##*/}"
+done | curl -Z -K -
+#sh_info "downloaded thumbnails..."
+
+###########################
+## user selection (nsxiv) ##
+###########################
+
+# extract the id's out of the thumbnail name
+image_ids="$(nsxiv $sxiv_otps "$cachedir")"
+[ -z "$image_ids" ] && exit
+
+#########################
+## download wallpapers ##
+#########################
+
+# download the selected wall papers
+mkdir "$walldir/$query"
+cd "$walldir/$query"
+sh_info "downloading wallpapers..."
+for ids in $image_ids
+do
+ ids="${ids##*/}"
+ ids="${ids%.*}"
+ url=$( jq -r '.data[]?|select( .id == "'$ids'" )|.path' < "$datafile" )
+ printf "url = %s\n" "$url"
+ printf -- "-O\n"
+done | curl -K -
+
+sh_info "wallpapers downloaded in:- '$walldir/$query'"
+nsxiv $(ls -c)