diff options
| -rwxr-xr-x | .local/bin/bukuopener | 7 | ||||
| -rwxr-xr-x | .local/bin/bukutagexplorer | 4 | ||||
| -rwxr-xr-x | .local/bin/epub_lander | 14 | ||||
| -rwxr-xr-x | .local/bin/pulse-volume-watcher.py | 48 | ||||
| -rwxr-xr-x | .local/bin/rfv | 14 | ||||
| -rw-r--r-- | .local/bin/template.sh | 100 | ||||
| -rwxr-xr-x | .local/bin/texclear | 14 | ||||
| -rwxr-xr-x | .local/bin/toggle_notifications.sh | 14 | ||||
| -rwxr-xr-x | .local/bin/type_clipboard.sh | 3 |
9 files changed, 218 insertions, 0 deletions
diff --git a/.local/bin/bukuopener b/.local/bin/bukuopener new file mode 100755 index 0000000..0378810 --- /dev/null +++ b/.local/bin/bukuopener | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #!/usr/bin/env sh | ||
| 2 | |||
| 3 | url=$(buku -p -f4 | fzf -m --reverse --preview "buku --nostdin -p {1}" --preview-window=wrap | cut -f2) | ||
| 4 | |||
| 5 | if [ -n "$url" ]; then | ||
| 6 | echo "$url" | xargs brave | ||
| 7 | fi | ||
diff --git a/.local/bin/bukutagexplorer b/.local/bin/bukutagexplorer new file mode 100755 index 0000000..8cfaba2 --- /dev/null +++ b/.local/bin/bukutagexplorer | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | |||
| 3 | # TODO cannot handle tags with multiple tokens | ||
| 4 | buku -t "$(buku --np -t | fzf --reverse --preview "buku --nostdin --np -t {2}" --preview-window=wrap | awk {'print $2'})" | ||
diff --git a/.local/bin/epub_lander b/.local/bin/epub_lander new file mode 100755 index 0000000..3179649 --- /dev/null +++ b/.local/bin/epub_lander | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | |||
| 3 | mv $HOME/down/*.epub $HOME/docs/epub_landing/ | ||
| 4 | |||
| 5 | if [[ $? -ne 1 ]]; then | ||
| 6 | notify-send "Moved some epubs" "" --app-name="epub_lander" --icon="emblem_success" | ||
| 7 | fi | ||
| 8 | |||
| 9 | mv $HOME/down/*.pdf $HOME/docs/pdf_landing/ | ||
| 10 | |||
| 11 | if [[ $? -ne 1 ]]; then | ||
| 12 | notify-send "Moved some pdfs" "" --app-name="epub_lander" --icon="emblem_success" | ||
| 13 | fi | ||
| 14 | |||
diff --git a/.local/bin/pulse-volume-watcher.py b/.local/bin/pulse-volume-watcher.py new file mode 100755 index 0000000..1b0fcd5 --- /dev/null +++ b/.local/bin/pulse-volume-watcher.py | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #!/usr/bin/env python3 | ||
| 2 | import sys | ||
| 3 | |||
| 4 | from pulsectl import Pulse, PulseLoopStop | ||
| 5 | |||
| 6 | with Pulse() as pulse: | ||
| 7 | |||
| 8 | def callback(ev): | ||
| 9 | if ev.index == sink_index: | ||
| 10 | raise PulseLoopStop | ||
| 11 | |||
| 12 | def current_status(sink): | ||
| 13 | return round(sink.volume.value_flat * 100), sink.mute == 1 | ||
| 14 | |||
| 15 | try: | ||
| 16 | sinks = {s.index: s for s in pulse.sink_list()} | ||
| 17 | if len(sys.argv) > 1: | ||
| 18 | # Sink index from command line argument if provided | ||
| 19 | sink_index = int(sys.argv[1]) | ||
| 20 | if sink_index not in sinks: | ||
| 21 | raise KeyError(f"Sink index {sink_index} not found in list of sinks.") | ||
| 22 | else: | ||
| 23 | # Automatic determination of default sink otherwise | ||
| 24 | default_sink_name = pulse.server_info().default_sink_name | ||
| 25 | try: | ||
| 26 | sink_index = next( | ||
| 27 | index | ||
| 28 | for index, sink in sinks.items() | ||
| 29 | if sink.name == default_sink_name | ||
| 30 | ) | ||
| 31 | except StopIteration: | ||
| 32 | raise StopIteration("No default sink was found.") | ||
| 33 | |||
| 34 | pulse.event_mask_set("sink") | ||
| 35 | pulse.event_callback_set(callback) | ||
| 36 | last_value, last_mute = current_status(sinks[sink_index]) | ||
| 37 | |||
| 38 | while True: | ||
| 39 | pulse.event_listen() | ||
| 40 | sinks = {s.index: s for s in pulse.sink_list()} | ||
| 41 | value, mute = current_status(sinks[sink_index]) | ||
| 42 | if value != last_value or mute != last_mute: | ||
| 43 | print(str(value) + ("!" if mute else "")) | ||
| 44 | last_value, last_mute = value, mute | ||
| 45 | sys.stdout.flush() | ||
| 46 | |||
| 47 | except Exception as e: | ||
| 48 | print(f"ERROR: {e}", file=sys.stderr) | ||
diff --git a/.local/bin/rfv b/.local/bin/rfv new file mode 100755 index 0000000..4c9a632 --- /dev/null +++ b/.local/bin/rfv | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | |||
| 3 | # 1. Search for text in files using Ripgrep | ||
| 4 | # 2. Interactively narrow down the list using fzf | ||
| 5 | # 3. Open the file in Vim | ||
| 6 | IFS=: read -ra selected < <( | ||
| 7 | rg --color=always --line-number --no-heading --smart-case "${*:-}" | | ||
| 8 | fzf --ansi \ | ||
| 9 | --color "hl:-1:underline,hl+:-1:underline:reverse" \ | ||
| 10 | --delimiter : \ | ||
| 11 | --preview 'bat --color=always {1} --highlight-line {2}' \ | ||
| 12 | --preview-window='up:60%:+{2}+3/3:~3' | ||
| 13 | ) | ||
| 14 | [ -n "${selected[0]}" ] && nvim "${selected[0]}" "+${selected[1]}" | ||
diff --git a/.local/bin/template.sh b/.local/bin/template.sh new file mode 100644 index 0000000..4afcb5f --- /dev/null +++ b/.local/bin/template.sh | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # https://betterdev.blog/minimal-safe-bash-script-template/ | ||
| 3 | |||
| 4 | set -Eeuo pipefail | ||
| 5 | |||
| 6 | cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 | ||
| 7 | |||
| 8 | trap cleanup SIGINT SIGTERM ERR EXIT | ||
| 9 | |||
| 10 | usage() { | ||
| 11 | cat <<EOF | ||
| 12 | Usage: $(basename "$0") [-h] [-v] [-f] -p param_value arg1 [arg2...] | ||
| 13 | |||
| 14 | Script description here. | ||
| 15 | |||
| 16 | Available options: | ||
| 17 | |||
| 18 | -h, --help Print this help and exit | ||
| 19 | -v, --verbose Print script debug info | ||
| 20 | -f, --flag Some flag description | ||
| 21 | -p, --param Some param description | ||
| 22 | EOF | ||
| 23 | exit | ||
| 24 | } | ||
| 25 | |||
| 26 | cleanup() { | ||
| 27 | trap - SIGINT SIGTERM ERR EXIT | ||
| 28 | # script cleanup here | ||
| 29 | } | ||
| 30 | |||
| 31 | setup_colors() { | ||
| 32 | if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then | ||
| 33 | NOCOLOR='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m' | ||
| 34 | else | ||
| 35 | NOCOLOR='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW='' | ||
| 36 | fi | ||
| 37 | } | ||
| 38 | |||
| 39 | msg() { | ||
| 40 | echo >&2 -e "${1-}" | ||
| 41 | } | ||
| 42 | |||
| 43 | die() { | ||
| 44 | local msg=$1 | ||
| 45 | local code=${2-1} # default exit status 1 | ||
| 46 | msg "$msg" | ||
| 47 | exit "$code" | ||
| 48 | } | ||
| 49 | |||
| 50 | parse_params() { | ||
| 51 | # default values of variables set from params | ||
| 52 | flag=0 | ||
| 53 | param='' | ||
| 54 | |||
| 55 | while :; do | ||
| 56 | case "${1-}" in | ||
| 57 | -h | --help) | ||
| 58 | usage | ||
| 59 | ;; | ||
| 60 | -v | --verbose) | ||
| 61 | set -x | ||
| 62 | ;; | ||
| 63 | --no-color) | ||
| 64 | NO_COLOR=1 | ||
| 65 | ;; | ||
| 66 | -f | --flag) # example flag | ||
| 67 | flag=1 | ||
| 68 | ;; | ||
| 69 | -p | --param) # example named parameter | ||
| 70 | param="${2-}" | ||
| 71 | shift | ||
| 72 | ;; | ||
| 73 | -?*) | ||
| 74 | die "Unknown option: $1" | ||
| 75 | ;; | ||
| 76 | *) | ||
| 77 | break | ||
| 78 | ;; | ||
| 79 | esac | ||
| 80 | shift | ||
| 81 | done | ||
| 82 | |||
| 83 | args=("$@") | ||
| 84 | |||
| 85 | # check required params and arguments | ||
| 86 | [[ -z "${param-}" ]] && die "Missing required parameter: param" | ||
| 87 | [[ ${#args[@]} -eq 0 ]] && die "Missing script arguments" | ||
| 88 | |||
| 89 | return 0 | ||
| 90 | } | ||
| 91 | |||
| 92 | parse_params "$@" | ||
| 93 | setup_colors | ||
| 94 | |||
| 95 | # script logic here | ||
| 96 | |||
| 97 | msg "${RED}Read parameters:${NOCOLOR}" | ||
| 98 | msg "- flag: ${flag}" | ||
| 99 | msg "- param: ${param}" | ||
| 100 | msg "- arguments: ${args[*]-}" | ||
diff --git a/.local/bin/texclear b/.local/bin/texclear new file mode 100755 index 0000000..f6a5062 --- /dev/null +++ b/.local/bin/texclear | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | # Clears the build files of a LaTeX/XeLaTeX build. | ||
| 4 | # I have vim run this file whenever I exit a .tex file. | ||
| 5 | |||
| 6 | case "$1" in | ||
| 7 | *.tex) | ||
| 8 | file=$(readlink -f "$1") | ||
| 9 | dir=$(dirname "$file") | ||
| 10 | base="${file%.*}" | ||
| 11 | find "$dir" -maxdepth 1 -type f -regextype gnu-awk -regex "^$base\\.(4tc|xref|tmp|pyc|pyo|fls|vrb|fdb_latexmk|bak|swp|aux|log|synctex\\(busy\\)|lof|lot|maf|idx|mtc|mtc0|nav|out|snm|toc|bcf|run\\.xml|synctex\\.gz|blg|bbl)" -delete ;; | ||
| 12 | *) printf "Give .tex file as argument.\\n" ;; | ||
| 13 | esac | ||
| 14 | |||
diff --git a/.local/bin/toggle_notifications.sh b/.local/bin/toggle_notifications.sh new file mode 100755 index 0000000..9b700b5 --- /dev/null +++ b/.local/bin/toggle_notifications.sh | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | |||
| 3 | TOGGLE=$HOME/.local/share/.pause_notifications | ||
| 4 | |||
| 5 | if [ ! -e $TOGGLE ]; then | ||
| 6 | touch $TOGGLE | ||
| 7 | dunstify --appname="notifications" --icon="chronometer-pause" "pausing" -u low | ||
| 8 | sleep 3 | ||
| 9 | killall -SIGUSR1 dunst # pause | ||
| 10 | else | ||
| 11 | rm $TOGGLE | ||
| 12 | killall -SIGUSR2 dunst # resume | ||
| 13 | dunstify --appname="notifications" --icon="chronometer-start" "here's what happened" -u low | ||
| 14 | fi | ||
diff --git a/.local/bin/type_clipboard.sh b/.local/bin/type_clipboard.sh new file mode 100755 index 0000000..3e7e792 --- /dev/null +++ b/.local/bin/type_clipboard.sh | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | xclip -selection clipboard -out | tr \\n \\r | xdotool selectwindow windowfocus type --clearmodifiers --delay 25 --window %@ --file - | ||
