summaryrefslogtreecommitdiff
path: root/bin/menuscripts
diff options
context:
space:
mode:
Diffstat (limited to 'bin/menuscripts')
-rwxr-xr-xbin/menuscripts/commander313
1 files changed, 313 insertions, 0 deletions
diff --git a/bin/menuscripts/commander b/bin/menuscripts/commander
new file mode 100755
index 0000000..028e8a7
--- /dev/null
+++ b/bin/menuscripts/commander
@@ -0,0 +1,313 @@
+#!/bin/sh
+
+# An attempt to unify usage of multiple launchers.
+# MENUCMD must be set to the name of the lancher
+#
+# look at the last line to understand how it works
+
+tmp="$(mktemp -u)"
+export menuopts=""
+TOFIRC="$HOME/.config/tofi/config"
+
+options='
+horizontal
+center
+input
+instant
+dynamic
+long
+prompt
+numbered
+prefix'
+
+cleanup() { rm -f "$tmp"; }
+logn() { >&2 printf '%s\n' "$@"; }
+
+run() {
+ IFS=:
+ set -f
+ find -L $PATH -type f -printf "%f\n" 2> /dev/null | sort -u
+}
+
+help() {
+ cat <<-EOF
+ Usage: commander OPTIONS...
+
+ An attempt to regroup multiple launchers into one,
+ it detects the value of the MENUCMD variable
+
+ try:
+ MENUCMD=tofi commander < /etc/passwd
+
+ Options:
+ -h Display items horizontally
+ -c Display centered
+ -i Take an input and return it to stdout
+ -d Adjust size and style dynamically
+ -p ARG Prompt user with the specified argument
+ -l Display in long list format
+ -n Output the number of matches
+ -r Select an executable from PATH
+ -s Invert instant select on single match
+ -x Invert prefix matching
+ EOF
+}
+
+add_option() { menuopts="$menuopts $*"; }
+get_prop() { awk -F '=' "/$1 *=*/ {print \$2}" "$TOFIRC"; }
+
+
+trap cleanup EXIT
+
+# Helper functions
+case "$MENUCMD" in
+ "tofi")
+ # $1: items count
+ get_height()
+ {
+ font_size="$(get_prop "font-size")"
+ padding_top="$(get_prop "padding-top")"
+ padding_bottom="$(get_prop "padding-bottom")"
+
+ printf "%s" "$((
+ font_size*2 + padding_top + padding_bottom + 2 +
+ ($1)*(font_size*2 - 2)
+ ))"
+
+ }
+ # $1: items length
+ get_width()
+ {
+ font_size="$(get_prop "font-size")"
+ padding_left="$(get_prop "padding-left")"
+ padding_right="$(get_prop "padding-right")"
+ printf "%s" "$(($1*(font_size-2) + 2 + padding_left + padding_right))"
+ } ;;
+ "dmenu") ;;
+ *) ;;
+esac
+
+
+main()
+{
+ # shellcheck disable=SC2317
+ case "$MENUCMD" in
+ "tofi")
+ center() { add_option "--anchor=center --width=20%"; }
+
+ horizontal() {
+ add_option "--horizontal=true --height=32"
+ add_option "--result-spacing=12"
+ add_option "--selection-background=#88c0d0"
+ add_option "--selection-background-padding=6,4"
+ add_option "--padding-top=0 --padding-bottom=0"
+ add_option "--margin-top=4"
+ }
+
+ dynamic() {
+ pre_cmd()
+ {
+ max_height="$(get_height 8)"
+ max_width="$(get_width 48)"
+
+ tee "$tmp"
+
+ items_count="$(wc -l < "$tmp")"
+ items_length="$(wc -L < "$tmp")"
+
+ if [ "$long" -ne 1 ]
+ then
+ height="$(get_height "$items_count")"
+ [ "$height" -gt "$max_height" ] && height="$max_height"
+ add_option "--height=$height"
+ fi
+
+ width="$(get_width "$items_length")"
+ [ "$width" -gt "$max_width" ] && width="$max_width"
+
+
+ if [ "$prompt" -eq 1 ]
+ then
+ prompt_width="$(printf "%s" "$prompt_arg" | wc -c)"
+ width="$((width + $(get_width "$prompt_width")))"
+ fi
+
+ add_option "--width=$width"
+ }
+ }
+
+ long() { add_option "--width=100% --height=$(get_height 20)"; }
+
+ input() {
+ add_option "--height=$(get_height 0) --width=$(get_width 24)"
+ pre_filter() { cat /dev/null; }
+ }
+
+ prefix() { add_option '--matching-algorithm=normal'; }
+
+ instant() { add_option "--auto-accept-single=false"; }
+
+ prompt() { add_option '--prompt-text' "$prompt_arg"; }
+
+ numbered() {
+ pre_filter() { awk '{print NR, $0}'; }
+ post_filter() { awk '{print $1}'; }
+ }
+
+ menucmd() { tofi "$@"; }
+ ;;
+
+ "dmenu")
+ horizontal() { add_option "-l 0"; }
+
+ center() { add_option "-c"; }
+
+ long() { add_option "-l 20 -g 1"; }
+
+ input() {
+ pre_filter() { cat /dev/null; }
+ }
+
+ dynamic() {
+ pre_cmd()
+ {
+ tee "$tmp"
+ items_count="$(wc -l < "$tmp")"
+ number="$items_count"
+
+ for i in $(seq $((number/2)))
+ do [ "$((number%i))" -eq 0 ] && factors="$i $factors"
+ done
+
+ min_diff=9999999999
+ for factor in $factors
+ do
+ quotient="$((number/factor))"
+ diff=$((quotient - factor))
+ if [ "$diff" -ge 0 ] && [ "$diff" -lt "$min_diff" ]
+ then
+ columns="$factor"
+ rows="$quotient"
+ min_diff="$diff"
+ fi
+ done
+
+ add_option "-g $columns"
+ add_option "-l $rows"
+ }
+ }
+
+ instant() { add_option "-n"; }
+
+ prefix() { add_option '-x'; }
+
+ prompt() { add_option '-p' "$prompt_arg"; }
+
+ numbered() { add_option "-px"; }
+
+ menucmd() { dmenu "$@"; }
+ ;;
+
+ *)
+ center() { :; }
+
+ horizontal() { :; }
+
+ dynamic() { :; }
+
+ long() { :; }
+
+ input() {
+ pre_filter() { cat /dev/null; }
+ add_option '--print-query'
+ }
+
+ prefix() { :; }
+
+ prompt() { add_option "--prompt" "$prompt_arg"; }
+
+ numbered() {
+ pre_filter() { awk '{print NR, $0}'; }
+ add_option '--with-nth' '2..'
+ post_filter() { awk '{print $1}'; }
+ }
+
+ menucmd() { fzf "$@"; }
+ ;;
+ esac
+
+ for option in $options
+ do eval "$option=0"
+ done
+
+ while getopts ":cdhilop:nrsx" opt
+ do
+ # shellcheck disable=SC2034
+ case $opt in
+
+ # display horizontal
+ h) horizontal=1 ;;
+ # display centered
+ c) center=1 ;;
+ # take an input and return it on stdout
+ i) input=1 ;;
+ # adjust size and style dynamically
+ d) dynamic=1 ;;
+ p) prompt=1; prompt_arg="$OPTARG";;
+ # long list format
+ l) long=1 ;;
+ # output number of match
+ n) numbered=1 ;;
+ # select an executable from PATH
+ r) shift
+ run | $0 "$@"
+ exit ;;
+ # invert instant select on single match
+ s) instant=1 ;;
+ # invert prefix matching
+ x) prefix=1 ;;
+
+ :)
+ logn "Option '-$OPTARG' requires an argument"
+ help
+ exit 1 ;;
+ ?)
+ logn "Invalid option: -$OPTARG"
+ help
+ exit 1 ;;
+ esac
+ done
+
+
+ # conflicts
+ [ "$input" -eq 1 ] && [ "$dynamic" -eq 1 ] && logn "conflicting options." && help && exit 1
+
+ # quit if stdin is empty
+ [ -t 0 ] && [ "$input" -eq 0 ] && logn "Stdin is empty." && help && exit 1
+
+ # call options
+ for option in $options
+ do eval "test \"\$$option\" -eq 1" && $option
+ done
+
+ command -v pre_filter > /dev/null || pre_filter() { cat; }
+ command -v post_filter > /dev/null || post_filter() { cat; }
+
+ which "${MENUCMD:-fzf}" > /dev/null || exit 1
+
+
+
+ if command -v pre_cmd > /dev/null
+ then
+ pre_cmd > "$tmp"
+ >&2 printf "menuopts: %s\n" "$menuopts"
+ # shellcheck disable=SC2086
+ pre_filter < "$tmp" | menucmd $menuopts | post_filter
+ else
+ >&2 printf "menuopts: %s\n" "$menuopts"
+ # shellcheck disable=SC2086
+ pre_filter | menucmd $menuopts | post_filter
+ fi
+}
+
+main "$@"