From 2c485ce2b43bd810a88278215b771136a2a17881 Mon Sep 17 00:00:00 2001 From: Martin Michalec Date: Wed, 11 Feb 2026 05:47:33 +0300 Subject: add scripts --- private_dot_local/bin/executable_emacs-dired | 3 + private_dot_local/bin/executable_emacs-message | 3 + private_dot_local/bin/executable_emacs-telega | 3 + .../bin/executable_emacs-transmission | 3 + private_dot_local/bin/executable_hibernate | 3 + private_dot_local/bin/executable_lock | 4 + private_dot_local/bin/executable_menu | 3 + private_dot_local/bin/executable_menu-drun | 23 ++ private_dot_local/bin/executable_menu-network | 34 ++ private_dot_local/bin/executable_menu-run | 3 + private_dot_local/bin/executable_passmenu | 42 ++ private_dot_local/bin/executable_pinentry-menu | 33 ++ private_dot_local/bin/executable_powermenu | 28 ++ private_dot_local/bin/executable_suspend | 3 + private_dot_local/bin/executable_sway-shot-output | 5 + .../bin/executable_sway-shot-window-or-selection | 5 + .../bin/executable_sway-swappy-clipboard | 3 + private_dot_local/bin/executable_sync-mail | 5 + .../bin/executable_toggle-screen-capture | 39 ++ private_dot_local/bin/executable_toggle-vpn | 9 + private_dot_local/bin/executable_tspreed | 441 +++++++++++++++++++++ private_dot_local/bin/executable_waybar-inbox | 5 + .../bin/executable_waybar-screen-recorder | 9 + private_dot_local/bin/executable_waybar-sunset | 64 +++ private_dot_local/bin/executable_waybar-vpn | 7 + private_dot_local/bin/executable_wine-run-with-cd | 6 + 26 files changed, 786 insertions(+) create mode 100644 private_dot_local/bin/executable_emacs-dired create mode 100644 private_dot_local/bin/executable_emacs-message create mode 100644 private_dot_local/bin/executable_emacs-telega create mode 100644 private_dot_local/bin/executable_emacs-transmission create mode 100644 private_dot_local/bin/executable_hibernate create mode 100644 private_dot_local/bin/executable_lock create mode 100644 private_dot_local/bin/executable_menu create mode 100644 private_dot_local/bin/executable_menu-drun create mode 100644 private_dot_local/bin/executable_menu-network create mode 100644 private_dot_local/bin/executable_menu-run create mode 100644 private_dot_local/bin/executable_passmenu create mode 100644 private_dot_local/bin/executable_pinentry-menu create mode 100644 private_dot_local/bin/executable_powermenu create mode 100644 private_dot_local/bin/executable_suspend create mode 100644 private_dot_local/bin/executable_sway-shot-output create mode 100644 private_dot_local/bin/executable_sway-shot-window-or-selection create mode 100644 private_dot_local/bin/executable_sway-swappy-clipboard create mode 100644 private_dot_local/bin/executable_sync-mail create mode 100644 private_dot_local/bin/executable_toggle-screen-capture create mode 100644 private_dot_local/bin/executable_toggle-vpn create mode 100644 private_dot_local/bin/executable_tspreed create mode 100644 private_dot_local/bin/executable_waybar-inbox create mode 100644 private_dot_local/bin/executable_waybar-screen-recorder create mode 100644 private_dot_local/bin/executable_waybar-sunset create mode 100644 private_dot_local/bin/executable_waybar-vpn create mode 100644 private_dot_local/bin/executable_wine-run-with-cd diff --git a/private_dot_local/bin/executable_emacs-dired b/private_dot_local/bin/executable_emacs-dired new file mode 100644 index 0000000..a0b8442 --- /dev/null +++ b/private_dot_local/bin/executable_emacs-dired @@ -0,0 +1,3 @@ +#!/bin/sh + +exec /usr/bin/emacsclient --no-wait --quiet --alternate-editor= --create-frame --eval '(progn (set-frame-name "Dired - Emacs Client") (dired (pop server-eval-args-left)))' "$@" diff --git a/private_dot_local/bin/executable_emacs-message b/private_dot_local/bin/executable_emacs-message new file mode 100644 index 0000000..0f17496 --- /dev/null +++ b/private_dot_local/bin/executable_emacs-message @@ -0,0 +1,3 @@ +#!/bin/sh + +exec /usr/bin/emacsclient --no-wait --quiet --alternate-editor= --create-frame --eval '(progn (set-frame-name "Send Email - Emacs Client") (browse-url-mail (pop server-eval-args-left)))' "$@" diff --git a/private_dot_local/bin/executable_emacs-telega b/private_dot_local/bin/executable_emacs-telega new file mode 100644 index 0000000..854fccf --- /dev/null +++ b/private_dot_local/bin/executable_emacs-telega @@ -0,0 +1,3 @@ +#!/bin/sh + +exec /usr/bin/emacsclient --no-wait --quiet --alternate-editor= --create-frame --eval "(progn (set-frame-name \"Telega - Emacs Client\") (if (and (boundp 'telega--status) (equal telega--status \"Ready\")) (telega-browse-url (pop server-eval-args-left)) (telega) (add-hook 'telega-ready-hook (lambda () (telega-browse-url (pop server-eval-args-left))))))" "$@" diff --git a/private_dot_local/bin/executable_emacs-transmission b/private_dot_local/bin/executable_emacs-transmission new file mode 100644 index 0000000..1b0f665 --- /dev/null +++ b/private_dot_local/bin/executable_emacs-transmission @@ -0,0 +1,3 @@ +#!/bin/sh + +exec /usr/bin/emacsclient --no-wait --quiet --alternate-editor= --eval "(let* ((torrent (pop server-eval-args-left))) (require 'notifications) (condition-case nil (progn (transmission-add torrent) (notifications-notify :title \"Transmission\" :body (format \"Torrent probably added: %s\" torrent) :timeout 2000)) (error (notifications-notify :title \"Transmission\" :body \"Something went wrong, check if transmission daemon is running.\") nil)))" "$@" diff --git a/private_dot_local/bin/executable_hibernate b/private_dot_local/bin/executable_hibernate new file mode 100644 index 0000000..199d5c6 --- /dev/null +++ b/private_dot_local/bin/executable_hibernate @@ -0,0 +1,3 @@ +#!/bin/sh + +swaylock && doas ZZZ diff --git a/private_dot_local/bin/executable_lock b/private_dot_local/bin/executable_lock new file mode 100644 index 0000000..37a30b5 --- /dev/null +++ b/private_dot_local/bin/executable_lock @@ -0,0 +1,4 @@ +#!/bin/sh + +gpg-connect-agent reloadagent /bye +swaylock \ No newline at end of file diff --git a/private_dot_local/bin/executable_menu b/private_dot_local/bin/executable_menu new file mode 100644 index 0000000..6d47fb1 --- /dev/null +++ b/private_dot_local/bin/executable_menu @@ -0,0 +1,3 @@ +#!/bin/sh + +wmenu -f "$HOME/.local/share/fonts/TTF/aporetic-serif-mono-normalregularupright.ttf 17" "$@" diff --git a/private_dot_local/bin/executable_menu-drun b/private_dot_local/bin/executable_menu-drun new file mode 100644 index 0000000..e655672 --- /dev/null +++ b/private_dot_local/bin/executable_menu-drun @@ -0,0 +1,23 @@ +#!/bin/sh + +SEARCH_PATHS=$(echo $XDG_DATA_HOME:$XDG_DATA_DIRS | tr ':' '\n' | awk '{print $1 "/applications"}') + +LIST=$(find -L $SEARCH_PATHS -maxdepth 1 -name "*.desktop" -print0 2>/dev/null | xargs -0 awk -F'=' ' + BEGINFILE { name=""; section="" } + /^\[Desktop Entry\]/ { section="main" } + /^\[Desktop Action / { section=substr($0, 17, length($0)-17) } + /^Name=/ && section=="main" { name=$2 } + ENDFILE { + if (name != "") { + printf "%s:%s\n", FILENAME, name + } + } +') + +CHOICE=$(echo "$LIST" | cut -d: -f2 | sort -u | $MENU "$@") + +[ -z "$CHOICE" ] && exit + +FILE=$(echo "$LIST" | grep -F ":$CHOICE" | head -n 1 | cut -d: -f1) + +gtk4-launch $(basename $FILE) diff --git a/private_dot_local/bin/executable_menu-network b/private_dot_local/bin/executable_menu-network new file mode 100644 index 0000000..b3a31a9 --- /dev/null +++ b/private_dot_local/bin/executable_menu-network @@ -0,0 +1,34 @@ +#!/bin/sh + +set -xe + +wpa_cli scan + +REFRESH="-- REFRESH --" + +SELECTION=$REFRESH +while [ "$SELECTION" = "$REFRESH" ]; do + NETWORKS=$(wpa_cli scan_results | awk 'NR > 2 { $1=$2=$3=$4=""; print $0 }' | sed 's/^[ \t]*//' | sort -u) + SELECTION=$(echo "$REFRESH$NETWORKS" | menu -l 10 -p "Connect to:") + [ -z "$SELECTION" ] && exit 0 +done + +ID=$(wpa_cli list_networks | grep "$SELECTION" | awk '{print $1}') + +if [ -z "$ID" ]; then + # New connection: Prompt for password + PASS=$(echo -n | menu -Pp "Password:") + + ID=$(wpa_cli add_network | tail -n -1) + wpa_cli set_network "$ID" ssid "\"$SELECTION\"" + + if [ -z "$PASS" ]; then + wpa_cli set_network "$ID" key_mgmt NONE + else + wpa_cli set_network "$ID" psk "\"$PASS\"" + fi + wpa_cli save_config +fi + +wpa_cli select_network "$ID" +wpa_cli enable_network "$ID" diff --git a/private_dot_local/bin/executable_menu-run b/private_dot_local/bin/executable_menu-run new file mode 100644 index 0000000..a588245 --- /dev/null +++ b/private_dot_local/bin/executable_menu-run @@ -0,0 +1,3 @@ +#!/bin/sh + +wmenu-run -f "$HOME/.local/share/fonts/TTF/aporetic-serif-mono-normalregularupright.ttf 17" $@ diff --git a/private_dot_local/bin/executable_passmenu b/private_dot_local/bin/executable_passmenu new file mode 100644 index 0000000..1aa1158 --- /dev/null +++ b/private_dot_local/bin/executable_passmenu @@ -0,0 +1,42 @@ +#!/bin/sh + +typeit=0 +nameit=0 +while true; do + case $1 in + "--type") + typeit=1 + shift + ;; + "--name") + nameit=1 + shift + ;; + *) + break + ;; + esac +done + +prefix=${PASSWORD_STORE_DIR-~/.password-store} +password=$(find $prefix -name '*.gpg' | sed "s@$prefix/\(.*\)\.gpg@\1@" | $MENU "$@") + +[ -n "$password" ] || exit + +if [ $nameit = 0 ]; then + what=$(pass show "$password" | head -n 1) + [ -n "$what" ] || exit +else + what=$(basename $password) +fi + +if [ $typeit = 0 ]; then + printf "$what" | wl-copy + if [ $nameit = 0 ]; then + notify-send "Coppied password for:" "$password" + else + notify-send "Coppied password name:" "$password" + fi +else + printf "$what" | wtype - -k Tab +fi diff --git a/private_dot_local/bin/executable_pinentry-menu b/private_dot_local/bin/executable_pinentry-menu new file mode 100644 index 0000000..5f42c0c --- /dev/null +++ b/private_dot_local/bin/executable_pinentry-menu @@ -0,0 +1,33 @@ +#!/bin/sh + +echo "OK Pleased to meet you" + +while read line; do + echo "GPG sent: $line" >> /tmp/pinentry-trace.log + # Ignore empty lines + [ -z "$line" ] && continue + + case "$line" in + *GETPIN*) + # Run menu and capture output + # We use /dev/tty for input if needed, but wmenu usually handles its own window + PIN=$(echo -n | menu -p "Passphrase: " -P) + + if [ $? -ne 0 ] || [ -z "$PIN" ]; then + echo "CAN" + else + echo "D $PIN" + echo "OK" + fi + ;; + *BYE*) + echo "OK" + exit 0 + ;; + *) + # For everything else (SETDESC, SETPROMPT, OPTION, etc.) + # We MUST say OK or the agent thinks we crashed + echo "OK" + ;; + esac +done diff --git a/private_dot_local/bin/executable_powermenu b/private_dot_local/bin/executable_powermenu new file mode 100644 index 0000000..ae168cd --- /dev/null +++ b/private_dot_local/bin/executable_powermenu @@ -0,0 +1,28 @@ +#!/bin/sh + +selection=$(cat < if more recent, for details. +# This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. + +# Notes about disabled ShellChecks: +# SC1090 -- Config files do not need to/cannot be checked as they are user-written. Default config is checked separately +# SC2015 -- Disabled where behaviour resembling an if-then-else is not intended +# SC3045 -- Disabled where support for non-POSIX options are tested for and handled + +# Exit from caught signals +exit_catch() { + [ "$term_presenting" = true ] && end_term 8 + ! [ "$quietexit" = true ] && printf "%s/%s\n" "$word_num" "$input_words" + exit 8 +} + +# Exit from error +# $1 return value +# $2 error message +exit_err() { + [ "$term_presenting" = true ] && end_term "$1" + [ "$1" -eq 3 ] && printf "Terminal does not support capability '%s'\n" "$2" >&2 || printf "%s\n" "$2" >&2 + [ "$1" -eq 1 ] && printf "Usage: tspreed [-lqhikfbv] [-w wpm] [-n num] [-p style] [-c color] [-K path]\n" >&2 + printf "See 'man tspreed'\n" >&2 + exit "$1" +} + +# Move cursor to position +# $1 row +# $2 column +term_move() { + tput cup "$1" "$2" 2>/dev/null || printf "%b[%s;%sH" "\033" "$1" "$2" +} + +# Set foreground color +# $1 color +term_color() { + tput setaf "$1" 2>/dev/null || { + # shellcheck disable=SC2015 + [ "$1" -le 7 ] && printf "%b[3%sm" "\033" "$1" || exit_err 3 "setaf" + } +} + +# Move to top row and clear +term_init_top() { + printf "%s%s" "${term_home}" "${term_clear_line}" +} + +# Move to bottom row and clear +term_init_bottom() { + term_move "$term_height" 0 && printf "%s" "${term_clear_line}" +} + +# Initialise output +init_presentation() { + printf "%s" "$term_clear" + [ -n "$focuspointer" ] && [ "$focus" = true ] && { + term_move $((term_y_center - 1)) "$term_x_center" && printf "%s" "$focus_pointer_1" + term_move $((term_y_center + 1)) "$term_x_center" && printf "%s" "$focus_pointer_2" + } +} + +# Initialise terminal output +init_term() { + term_height="$(tput lines)" || { + [ -n "$LINES" ] && [ "$LINES" -gt 0 ] 2>/dev/null && term_height="$LINES" || term_height=24 + } + term_width="$(tput cols)" || { + [ -n "$COLUMNS" ] && [ "$COLUMNS" -gt 0 ] 2>/dev/null && term_width="$COLUMNS" || term_width=80 + } + term_x_center=$((term_width / 2)) + term_y_center=$((term_height / 2)) + init_presentation +} + +# Finish terminal output +# $1 return value of exit function +end_term() { + term_presenting=false + if [ "$term_session" = true ]; then + tput rmcup 2>/dev/null || exit_err 3 "rmcup" + else + if [ "$1" -eq 8 ]; then + term_move $((term_height - 1)) 0 + else + term_move "$term_height" 0 + fi + fi + printf "%s" "$term_reset" + [ "$hidecursor" = true ] && { + tput cnorm 2>/dev/null || exit_err 3 "cnorm" + } +} + +# Get current epoch timestamp in milliseconds +get_date_ms() { + # Epoch timestamp without '%s' taken from https://www.etalabs.net/sh_tricks.html + [ "$non_posix_date_s" = true ] && curr_epoch_sec="$(date -u "+%s")" || curr_epoch_sec="$(($(date -u "+((%Y-1600)*365+(%Y-1600)/4-(%Y-1600)/100+(%Y-1600)/400+1%j-1000-135140)*86400+(1%H-100)*3600+(1%M-100)*60+(1%S-100)")))" + echo "$(($(date -u "+${curr_epoch_sec}%N / 1000000")))" +} + +# Get substring +# $1 string +# $2 index (from 1) to get from +# $3 number of characters to get (all if not provided) +get_substr() { + if [ "$use_cut" = true ]; then + if [ -n "$3" ]; then + printf "%s" "$1" | cut -c "$2"-$(($2 - 1 + $3)) + else + printf "%s" "$1" | cut -c "$2"- + fi + else + if [ -n "$3" ]; then + printf "%s" "$1" | awk -v pos="$2" -v len="$3" '{ printf("%s", substr($0, pos, len)) }' + else + printf "%s" "$1" | awk -v pos="$2" '{ printf("%s", substr($0, pos)) }' + fi + fi +} + +# Perform floating point calculation +# $1 calculation to perform +calc_float() { + if [ "$use_bc" = true ]; then + # No floating point calculation in script should return a negative result, so no handling of negative results implemented + printf "scale=3; %s\n" "$1" | bc | sed 's/^\./0./' + else + awk "BEGIN { print ${1} }" + fi +} + +# $1 Word number +# $2 Total number of words +print_presentation_info() { + printf "%s%b%s" "${1}/${2}" "\t" "$((($1 * 100) / $2))%" +} + +# Import configs +config_global="/etc/tspreed/tspreed.rc" +config_local="${XDG_CONFIG_HOME:-$HOME/.config}/tspreed/tspreed.rc" +# shellcheck disable=SC1090 +[ -f "$config_global" ] && . "$config_global" +# shellcheck disable=SC1090 +[ -f "$config_local" ] && . "$config_local" + +# Init +input= +term_presenting=false +word_first=true +word_num=0 +word_paused=false +word_len_average=5 # Based on average English word length of 5.1 letters +focus_pointer_1= +focus_pointer_2= +prev_word_len_exceed=false + +# Catch signals +trap "exit_catch" 2 # SIGINT +trap "exit_catch" 3 # SIGQUIT +trap "exit_catch" 6 # SIGABRT +trap "exit_catch" 14 # SIGALRM +trap "exit_catch" 15 # SIGTERM +trap "init_term" WINCH # Terminal emulator resize + +# Convert long options to short options +for arg in "$@"; do + shift + case "$arg" in + "--wpm") set -- "$@" "-w" ;; + "--num-start") set -- "$@" "-n" ;; + "--separators") set -- "$@" "-s" ;; + "--length-vary") set -- "$@" "-l" ;; + "--quiet-exit") set -- "$@" "-q" ;; + "--hide-cursor") set -- "$@" "-h" ;; + "--progress-info") set -- "$@" "-i" ;; + "--key-controls") set -- "$@" "-k" ;; + "--focus") set -- "$@" "-f" ;; + "--focus-pointer") set -- "$@" "-p" ;; + "--focus-bold") set -- "$@" "-b" ;; + "--focus-color") set -- "$@" "-c" ;; + "--dev-key-input") set -- "$@" "-K" ;; + "--version") set -- "$@" "-v" ;; + *) set -- "$@" "$arg" ;; + esac +done +OPTIND=1 + +# Parse options +while getopts ":w:n:s:qhiklfp:bc:K:vV" opt; do + case "$opt" in + w) wpm=$OPTARG ;; + n) numstart="$OPTARG" ;; + s) separators="$OPTARG" ;; + l) lengthvary=true ;; + q) quietexit=true ;; + h) hidecursor=true ;; + i) proginfo=true ;; + k) keycontrols=true ;; + f) focus=true ;; + p) focuspointer="$OPTARG" ;; + b) focusbold=true ;; + c) focuscolor="$OPTARG" ;; + K) devkeyinput="$OPTARG" ;; + v|V) printf "tspreed 2.6.2\n" && exit 0 ;; + \?) exit_err 1 "Invalid option '-${OPTARG}'" ;; + :) exit_err 1 "Option -${OPTARG} requires an argument." ;; + esac +done + +# Validate and set keyboard input device/path +[ -z "$devkeyinput" ] && devkeyinput='/dev/tty' +[ -e "$devkeyinput" ] || exit_err 1 "Invalid keyboard input path '${devkeyinput}'" + +# Validate word speed +[ -z "$wpm" ] && exit_err 1 "WPM not set" +! { [ "$wpm" -ge 1 ] && [ "$wpm" -le 60000 ]; } 2>/dev/null && exit_err 1 "Invalid WPM '${wpm}'" + +# Validate and set nth word as starting word +[ -n "$numstart" ] && ! [ "$numstart" -ge 1 ] 2>/dev/null && exit_err 1 "Invalid starting word position '${numstart}'" +[ -z "$numstart" ] && numstart=1 + +# Validate focus letter options +[ "$focus" = true ] && { + # Validate and set focus letter pointers + [ -n "$focuspointer" ] && [ "$focuspointer" != "none" ] && { + case "$focuspointer" in + line) focus_pointer_1="|" && focus_pointer_2="|" ;; + point) focus_pointer_1="v" && focus_pointer_2="^" ;; + *) exit_err 1 "Invalid focus letter pointer '${focuspointer}'" ;; + esac + } + # Validate focus letter color + [ -n "$focuscolor" ] && ! { [ "$focuscolor" -ge 0 ] && [ "$focuscolor" -le 255 ]; } 2>/dev/null && exit_err 1 "Invalid focus letter color '${focuscolor}'" +} + +# Set IFS +IFS="$(printf "%s%b" "$IFS" "$separators")" + +# Determine non-POSIX capabilities +# shellcheck disable=SC3045 +read -rs -n 0 -t 0.0 2>/dev/null && non_posix_read=true || non_posix_read=false +sleep 0e-3 2>/dev/null && non_posix_sleep_enotation=true || non_posix_sleep_enotation=false +sleep 0.0 2>/dev/null && non_posix_sleep_fractional=true || non_posix_sleep_fractional=false +[ -n "$(command -v usleep)" ] && non_posix_usleep=true || non_posix_usleep=false +[ "$(date "+%N")" -ge 0 ] 2>/dev/null && non_posix_date_n=true || non_posix_date_n=false +[ "$(date "+%s")" -ge 0 ] 2>/dev/null && non_posix_date_s=true || non_posix_date_s=false + +# Validate required non-POSIX capabilities +if [ "$keycontrols" = true ]; then + [ "$non_posix_read" = false ] && exit_err 2 "System or shell does not support non-POSIX read(1)" + [ "$non_posix_date_n" = false ] && exit_err 2 "System or shell does not support non-POSIX date(1) '%N' format" +else + [ "$non_posix_sleep_enotation" = false ] && [ "$non_posix_sleep_fractional" = false ] && [ "$non_posix_usleep" = false ] && [ "$non_posix_date_n" = false ] && exit_err 2 "System or shell does not support at least one of the required non-POSIX features or commands" +fi + +# Determine terminal capabilities +term_reset="$(tput sgr0 2>/dev/null || printf "%b[m" "\033")" +term_bold="$(tput bold 2>/dev/null || printf "%b[1m" "\033")" +term_home="$(tput home 2>/dev/null || term_move 0 0)" +term_clear_line="$(tput el 2>/dev/null || printf "%b[K" "\033")" +[ -n "$(tput smcup 2>/dev/null)" ] && [ -n "$(tput rmcup 2>/dev/null)" ] && term_session=true || term_session=false +[ "$term_session" = false ] && term_clear="$(printf "%s%s" "$term_home" "$(tput ed 2 2>/dev/null || printf "%b[2J" "\033")")" || term_clear="$(tput clear)" 2>/dev/null + +# Determine wide character capabilities +wide_char="$(printf "%b" "\0316\0251")" +[ "${#wide_char}" -eq 1 ] && wide_param_expansion=true || wide_param_expansion=false +[ "$(printf "%s" "$wide_char" | cut -c 1)" = "$wide_char" ] && wide_cut=true || wide_cut=false + +# Get input +while read -r inp; do + input="${input}${inp} " +done + +# Get input info +input_info="$(printf "%s" "$input" | wc -wmc)" +input_words="$(echo "$input_info" | awk '{ print $1 }')" +[ "$(echo "$input_info" | awk '{ print $3 - $2 }')" -gt 0 ] && wide_input=true || wide_input=false + +# Determine command usage +{ [ "$wide_input" = false ] || [ "$wide_param_expansion" = true ]; } && use_param_expansion=true || use_param_expansion=false +{ [ "$wide_input" = false ] || [ "$wide_cut" = true ]; } && use_cut=true || use_cut=false +[ -n "$(command -v bc)" ] && use_bc=true || use_bc=false + +# Init presentation +if [ "$term_session" = true ]; then + tput smcup 2>/dev/null || exit_err 3 "smcup" +else + printf "%s" "$term_clear" +fi +term_presenting=true +[ "$hidecursor" = true ] && { + tput civis 2>/dev/null || exit_err 3 "civis" +} +init_term + +# Present +for word in $input; do + + # Init word + [ "$use_param_expansion" = true ] && word_len=${#word} || word_len="$(printf "%s" "$word" | wc -m)" + [ "$word_len" -le 0 ] && continue + word_num=$((word_num + 1)) + [ "$word_num" -lt "$numstart" ] && continue + word_x=0 + + # Clear word + if [ "$prev_word_len_exceed" = true ]; then + init_presentation + else + term_move "$term_y_center" 0 + printf "%s" "$term_clear_line" + fi + + [ "$non_posix_date_n" = true ] && word_start_date="$(get_date_ms)" + + # Highlighted focus letter + if [ "$focus" = true ]; then + + # Set focus letter + case "$word_len" in + 1|2) word_focus_pos=1 ;; + 3|4|5) word_focus_pos=2 ;; + 6|7|8|9) word_focus_pos=3 ;; + 10|11|12|13) word_focus_pos=4 ;; + *) word_focus_pos=5 ;; + esac + # Set horizontal position of word + word_x=$((term_x_center - word_focus_pos + 1)) + term_move "$term_y_center" "$word_x" + + # Formatted focus letter + if [ "$focusbold" = true ] || [ -n "$focuscolor" ]; then + + # Print start of word + [ "$word_focus_pos" -gt 1 ] && printf "%s" "$(get_substr "$word" 1 $((word_focus_pos - 1)))" + + # Print focus letter + [ "$focusbold" = true ] && printf "%s" "$term_bold" + [ -n "$focuscolor" ] && term_color "$focuscolor" + printf "%s" "$(get_substr "$word" "$word_focus_pos" 1)" + printf "%s" "$term_reset" + + # Print end of word + printf "%s" "$(get_substr "$word" $((word_focus_pos + 1)))" + + # No formatting + else + printf "%s" "$word" + fi + + # No focus letter highlighting + else + # Set horizontal position of word + [ $((word_x + word_len)) -le "$term_width" ] && word_x=$((term_x_center - (word_len / 2))) + term_move "$term_y_center" "$word_x" + # Print + printf "%s" "$word" + fi + + # Print presentation information + [ "$proginfo" = true ] && term_init_top && print_presentation_info "$word_num" "$input_words" + + # End word + term_move "$term_height" 0 + [ $((word_x + word_len)) -gt "$term_width" ] && prev_word_len_exceed=true || prev_word_len_exceed=false + + # Calculate sleep time + # No sleep time calculation should return a negative result, so no handling of negative sleep times implemented + sleep_ms_float=$(calc_float "1000 / (${wpm} / 60)") + [ "$lengthvary" = true ] && sleep_ms_float="$(calc_float "${sleep_ms_float} * ($([ "$word_len" -gt "$word_len_average" ] && echo "$word_len" || echo $((word_len_average - 1))) / ${word_len_average})")" + # Account for word processing time if possible + [ "$non_posix_date_n" = true ] && sleep_ms_float=$(calc_float "${sleep_ms_float} + ${word_start_date} - $(get_date_ms)") + + # Convert sleep time to int + sleep_ms="${sleep_ms_float%.*}" + + # Sleep first word for minimum 1 second + [ "$word_first" = true ] && { + word_first=false + [ "$sleep_ms" -lt 1000 ] && sleep_ms=1000 + } + + # Sleep with keyboard controls + if [ "$keycontrols" = true ]; then + sleep_date=$(($(get_date_ms) + sleep_ms)) + while [ "$(get_date_ms)" -lt "$sleep_date" ] || [ "$word_paused" = true ]; do + # shellcheck disable=SC3045 + read -rs -n 1 -t 0.001 input_key < "$devkeyinput" + case "$input_key" in + i) + if [ "$proginfo" = true ]; then + proginfo=false + term_init_top + else + proginfo=true + term_init_top && print_presentation_info "$word_num" "$input_words" + fi + ;; + p) + if [ "$word_paused" = true ]; then + word_paused=false + term_init_bottom + # Sleep after unpause for minimum 0.5 seconds + [ "$sleep_ms" -lt 500 ] && sleep_ms=500 + sleep_date=$(($(get_date_ms) + sleep_ms)) + else + word_paused=true + term_init_bottom && printf "[ Paused ]" + fi + ;; + q) + exit_catch + ;; + esac + done + term_init_bottom + # Sleep only + elif [ "$sleep_ms" -gt 0 ]; then + if [ "$non_posix_sleep_enotation" = true ]; then + sleep "${sleep_ms}e-3" + elif [ "$non_posix_usleep" = true ]; then + usleep $((sleep_ms * 1000)) + elif [ "$non_posix_sleep_fractional" = true ]; then + sleep "$(calc_float "${sleep_ms} / 1000")" + elif [ "$non_posix_date_n" = true ]; then + sleep_date=$(($(get_date_ms) + sleep_ms)) + while [ "$(get_date_ms)" -lt "$sleep_date" ]; do + : + done + else + exit_err 2 "System or shell does not support at least one of the required non-POSIX features or commands" + fi + fi + +done + +sleep 1 && end_term 0 +exit 0 diff --git a/private_dot_local/bin/executable_waybar-inbox b/private_dot_local/bin/executable_waybar-inbox new file mode 100644 index 0000000..2ac6378 --- /dev/null +++ b/private_dot_local/bin/executable_waybar-inbox @@ -0,0 +1,5 @@ +#!/bin/sh + +COUNT=$(notmuch count tag:inbox) + +printf '{"alt":"%s","tooltip":"%s"}\n' "$alt" "$tooltip" diff --git a/private_dot_local/bin/executable_waybar-screen-recorder b/private_dot_local/bin/executable_waybar-screen-recorder new file mode 100644 index 0000000..23cdc6f --- /dev/null +++ b/private_dot_local/bin/executable_waybar-screen-recorder @@ -0,0 +1,9 @@ +#!/bin/sh + +PID=`pgrep wf-recorder` + +if [ "$PID" ]; then + echo "{ \"text\": \"⬤\", \"tooltip\": \"Kill recording\" }" +else + echo "{ \"text\": \"\" }" +fi diff --git a/private_dot_local/bin/executable_waybar-sunset b/private_dot_local/bin/executable_waybar-sunset new file mode 100644 index 0000000..88c98f0 --- /dev/null +++ b/private_dot_local/bin/executable_waybar-sunset @@ -0,0 +1,64 @@ +#!/bin/sh + +start () +{ + wlsunset -l "59.8" -L "30.2" -t "3000" -T "6500" & +} + +stop () +{ + pkill -x wlsunset +} + +rotate () +{ + pkill -x -SIGUSR1 wlsunset +} + +update_waybar () +{ + pkill -x -SIGRTMIN+10 waybar +} + +is_active () +{ + pkill -x -0 wlsunset +} + +has_wlsunset () +{ + command -v wlsunset >/dev/null +} + +case "$1" in + 'start') + start + update_waybar + ;; + 'stop') + stop + update_waybar + ;; + 'toggle') + is_active && stop || start + update_waybar + ;; + 'rotate') + rotate + update_waybar + ;; + 'check') + has_wlsunset + exit $? + ;; +esac + +if is_active; then + alt="on" + tooltip="Stop/rotate wlsunset" +else + alt="off" + tooltip="Start wlsunset" +fi + +printf '{"alt":"%s","tooltip":"%s"}\n' "$alt" "$tooltip" diff --git a/private_dot_local/bin/executable_waybar-vpn b/private_dot_local/bin/executable_waybar-vpn new file mode 100644 index 0000000..02f1ec9 --- /dev/null +++ b/private_dot_local/bin/executable_waybar-vpn @@ -0,0 +1,7 @@ +#!/bin/sh + +if ip address | grep wg0 >/dev/null; then + echo "{ \"text\": \"🔒\", \"tooltip\": \"Stop vpn\" }" +else + echo "{ \"text\": \"🔓\", \"tooltip\": \"Start vpn\" }" +fi diff --git a/private_dot_local/bin/executable_wine-run-with-cd b/private_dot_local/bin/executable_wine-run-with-cd new file mode 100644 index 0000000..6bb6d49 --- /dev/null +++ b/private_dot_local/bin/executable_wine-run-with-cd @@ -0,0 +1,6 @@ +#!/bin/sh + +DIRNAME=$(dirname "$1") +BASENAME=$(basename "$1") + +cd "$DIRNAME" && exec wine "$BASENAME" -- cgit v1.3