diff --git a/sx-open b/sx-open index 886922b..6647981 100755 --- a/sx-open +++ b/sx-open @@ -13,13 +13,83 @@ usage() { } act() { - (( verbose )) && printf 'CMD: %s\n' "$*" >&2 - (( dry_run )) || { "$@"; return $?; } + cfg verbose && printf 'CMD: %s\n' "$*" >&2 + cfg dryrun || { "$@"; return $?; } return 0 } +# cfg foo bool = [true|1] +# cfg foo [string] = 'bar' +# cfg foo +cfg() { + declare s_name=$1; shift + declare -n \ + _s="cfg[$s_name]" \ + _s_type="cfg[${s_name}_type]" + + if (( $# )); then + while (( $# )); do + case $1 in + (bool|str) _s_type="$1";; + + (true|false|0|1) + _s_type='bool' + _s="$1" + + break + ;; + + (=) + [[ $_s_type ]] || _s_type='string' + + [[ $_s_type == 'bool' ]] && { + case $2 in + (true|false|0|1) true;; + (*) + error "On line $LINENO, in $FUNCNAME: Invalid value for '$s_name' type 'bool': '$2'" + return 11 + ;; + esac + } + + _s="$2" + + break + ;; + + (*) + error "On line $LINENO, in $FUNCNAME: Syntax error: “cfg $s_name $*”" + exit 115 + ;; + esac + shift + done + else + [[ -n $_s ]] || { + error "On line $LINENO, in $FUNCNAME: invalid option: '$s_name'" + return 13 + } + + case $_s_type in + (bool) + case $_s in + (true|1) return 0;; + (false|0) return 1;; + esac + ;; + + (*) + printf '%s\n' "$_s" + return 0 + ;; + esac + fi +} + notify() { + cfg notify || return 7 # disabled + [[ $DISPLAY ]] || return 3 [[ $notifier ]] || return 5 @@ -111,17 +181,26 @@ is_uri() [[ $1 =~ ^[a-zA-Z][a-zA-Z0-9\+\.\-]+:.+ ]] main() { declare cmd_result target + declare -gA cfg + cfg verbose bool = false + cfg dryrun bool = false + cfg notify bool = true + # Source the config file. cfg_file="$HOME/.config/sx-open.cfg" [[ -f "$cfg_file" ]] && { source "$cfg_file"; } while (( $# )); do case $1 in - (-d) dry_run=1; verbose=1;; - (-v) verbose=1;; - (-h) usage; return 0;; + (-d) + cfg dryrun = true + cfg verbose = true + ;; - (-n) notify() { true; };; # disable desktop notifications + (-v) cfg verbose = true;; + (-n) cfg notify = false;; # disable desktop notifications + + (-h) usage; return 0;; (--) shift; break;; (*) break;; @@ -132,7 +211,10 @@ main() { target=$1; [[ "$target" ]] || { usage; exit; } - (( dry_run )) && printf 'Dry run: not actually running the handler\n' >&2 + cfg dryrun && { + printf 'Dry run: not actually running the handler\n' >&2 + cfg verbose true + } # Treat file:// as local paths. [[ "$target" =~ ^file:(//)?(/.+) ]] && target=${BASH_REMATCH[2]} diff --git a/sx-open.cfg b/sx-open.cfg index fddeecd..9f1d545 100644 --- a/sx-open.cfg +++ b/sx-open.cfg @@ -2,6 +2,15 @@ # Configuration file for sx-open # Note that as sx-open checks the regexes in order, they should be placed in order from specific to less so. +# Disable desktop notifications +#cfg notify false + +# Enable verbose mode +#cfg verbose true + +# Enable dry run mode (implies verbose) +#cfg dryrun true + # macros: # %target% — The first argument to this script. # If not found, target is appended to the end of