Compare commits
12 Commits
Author | SHA1 | Date |
---|---|---|
|
d51e7f3e87 | |
|
6b13675289 | |
|
815089d968 | |
|
1806be55e7 | |
|
32593202c6 | |
|
b77c674962 | |
|
3d01d93246 | |
|
0e70a1b471 | |
|
39fa88375f | |
|
589f30327a | |
|
0ab6c359b1 | |
|
0da6d1dfeb |
34
README.md
34
README.md
|
@ -1,5 +1,11 @@
|
||||||
# Bash Template Command
|
# Bash Template Command
|
||||||
|
|
||||||
|
*I no longer use this using [Bonzai][] instead. But it does have some good bash tricks to keep around including self-completion.*
|
||||||
|
|
||||||
|
[Bonzai]: <https://github.com/rwxrob/bonzai>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
*This `README.md` is autogenerated.*
|
*This `README.md` is autogenerated.*
|
||||||
|
|
||||||
This is a GitHub template repo that will be copied instead of forked to
|
This is a GitHub template repo that will be copied instead of forked to
|
||||||
|
@ -16,8 +22,8 @@ This `cmd` inside can then be renamed and finished.
|
||||||
* Name repos containing single bash commands with `cmd-`
|
* Name repos containing single bash commands with `cmd-`
|
||||||
* Name template repos beginning with `template-`
|
* Name template repos beginning with `template-`
|
||||||
* Start command functions with `x.` to be completed
|
* Start command functions with `x.` to be completed
|
||||||
* Name `CONFIG` accessors with `x.` and full path
|
* Name `CONF` accessors with `x.` and full path
|
||||||
* Use dot (`.`) pathing in `CONFIG` key names
|
* Use dot (`.`) pathing in `CONF` key names
|
||||||
|
|
||||||
Think of `x` as in "executable" command.
|
Think of `x` as in "executable" command.
|
||||||
|
|
||||||
|
@ -41,7 +47,21 @@ or want.
|
||||||
|
|
||||||
The `_initialize` function is meant to contain initialization code and
|
The `_initialize` function is meant to contain initialization code and
|
||||||
be placed at the beginning of the script to be found easily even though
|
be placed at the beginning of the script to be found easily even though
|
||||||
it is called at the bottom of the script (as bash requires).
|
it is called at the bottom of the script (as bash requires). It is
|
||||||
|
passed the arguments that are passed to the script itself. This function can be omitted.
|
||||||
|
|
||||||
|
### `_alternatives`
|
||||||
|
|
||||||
|
The `_alternatives` function (usually placed after `_initialize`
|
||||||
|
provides a hook for dealing with alternative arguments to those that
|
||||||
|
identify commands (`x.*`). If the first argument to the script does not
|
||||||
|
match a command function then this function will be called before the
|
||||||
|
default `x.usage` command allowing shortcuts and other argument
|
||||||
|
alternatives and intelligent sensing of what command function is wanted
|
||||||
|
by simply examining the argument list. This can be useful when you wish
|
||||||
|
to provide shortcuts for longer commands but do not want to clutter the
|
||||||
|
command usage and completion list. For example, `zet dex.titles` could
|
||||||
|
be trapped in `_alternatives` to call `zet titles`.
|
||||||
|
|
||||||
### `_have`
|
### `_have`
|
||||||
|
|
||||||
|
@ -131,6 +151,12 @@ more powerful, safer, flexible, and performant than POSIX shell or Zsh.
|
||||||
|
|
||||||
[`shellcheck`]: <https://www.shellcheck.net>
|
[`shellcheck`]: <https://www.shellcheck.net>
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
This script is expected to be installed for a specific user and only
|
||||||
|
ever run by that user. No additional security vetting for running as an
|
||||||
|
untrusted user has been done.
|
||||||
|
|
||||||
## Legal
|
## Legal
|
||||||
|
|
||||||
Copyright 2021 Rob Muhlestein <rob@rwx.gg>
|
Copyright 2021 Rob Muhlestein <rob@rwx.gg>
|
||||||
|
@ -252,5 +278,5 @@ Displays a summary of usage.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
*Autogenerated Tue Aug 31 10:37:57 PM EDT 2021*
|
*Autogenerated Sat Dec 18 11:13:17 AM EST 2021*
|
||||||
|
|
||||||
|
|
233
cmd
233
cmd
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
set -e
|
set -e
|
||||||
# export PATH="/bin:/usr/bin:/usr/local/bin" # safer, if you can
|
# export PATH="/bin:/usr/bin:/usr/local/bin" # safer, if you can
|
||||||
|
@ -11,12 +11,29 @@ set -e
|
||||||
: "${EXE:="${0##*/}"}"
|
: "${EXE:="${0##*/}"}"
|
||||||
|
|
||||||
declare -A HELP
|
declare -A HELP
|
||||||
declare -A CONFIG
|
declare -A CONF
|
||||||
|
|
||||||
|
# declare black=$'\e[30m'
|
||||||
|
# declare red=$'\e[31m'
|
||||||
|
# declare green=$'\e[32m'
|
||||||
|
# declare yellow=$'\e[33m'
|
||||||
|
# declare blue=$'\e[34m'
|
||||||
|
# declare magenta=$'\e[35m'
|
||||||
|
# declare cyan=$'\e[36m'
|
||||||
|
# declare white=$'\e[37m'
|
||||||
|
# declare reset=$'\e[0m'
|
||||||
|
|
||||||
_initialize() {
|
_initialize() {
|
||||||
: # put initialization code here
|
: # put initialization code here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_alternatives() {
|
||||||
|
# put alternative argument possibilities here
|
||||||
|
if [[ $CMD = f ]];then
|
||||||
|
x.foo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
HELP[main]='
|
HELP[main]='
|
||||||
# Bash Template Command
|
# Bash Template Command
|
||||||
|
|
||||||
|
@ -36,8 +53,8 @@ This `cmd` inside can then be renamed and finished.
|
||||||
* Name repos containing single bash commands with `cmd-`
|
* Name repos containing single bash commands with `cmd-`
|
||||||
* Name template repos beginning with `template-`
|
* Name template repos beginning with `template-`
|
||||||
* Start command functions with `x.` to be completed
|
* Start command functions with `x.` to be completed
|
||||||
* Name `CONFIG` accessors with `x.` and full path
|
* Name `CONF` accessors with `x.` and full path
|
||||||
* Use dot (`.`) pathing in `CONFIG` key names
|
* Use dot (`.`) pathing in `CONF` key names
|
||||||
|
|
||||||
Think of `x` as in "executable" command.
|
Think of `x` as in "executable" command.
|
||||||
|
|
||||||
|
@ -61,7 +78,21 @@ or want.
|
||||||
|
|
||||||
The `_initialize` function is meant to contain initialization code and
|
The `_initialize` function is meant to contain initialization code and
|
||||||
be placed at the beginning of the script to be found easily even though
|
be placed at the beginning of the script to be found easily even though
|
||||||
it is called at the bottom of the script (as bash requires).
|
it is called at the bottom of the script (as bash requires). It is
|
||||||
|
passed the arguments that are passed to the script itself. This function can be omitted.
|
||||||
|
|
||||||
|
### `_alternatives`
|
||||||
|
|
||||||
|
The `_alternatives` function (usually placed after `_initialize`
|
||||||
|
provides a hook for dealing with alternative arguments to those that
|
||||||
|
identify commands (`x.*`). If the first argument to the script does not
|
||||||
|
match a command function then this function will be called before the
|
||||||
|
default `x.usage` command allowing shortcuts and other argument
|
||||||
|
alternatives and intelligent sensing of what command function is wanted
|
||||||
|
by simply examining the argument list. This can be useful when you wish
|
||||||
|
to provide shortcuts for longer commands but do not want to clutter the
|
||||||
|
command usage and completion list. For example, `zet dex.titles` could
|
||||||
|
be trapped in `_alternatives` to call `zet titles`.
|
||||||
|
|
||||||
### `_have`
|
### `_have`
|
||||||
|
|
||||||
|
@ -151,6 +182,12 @@ more powerful, safer, flexible, and performant than POSIX shell or Zsh.
|
||||||
|
|
||||||
[`shellcheck`]: <https://www.shellcheck.net>
|
[`shellcheck`]: <https://www.shellcheck.net>
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
This script is expected to be installed for a specific user and only
|
||||||
|
ever run by that user. No additional security vetting for running as an
|
||||||
|
untrusted user has been done.
|
||||||
|
|
||||||
## Legal
|
## Legal
|
||||||
|
|
||||||
Copyright 2021 Rob Muhlestein <rob@rwx.gg>
|
Copyright 2021 Rob Muhlestein <rob@rwx.gg>
|
||||||
|
@ -187,9 +224,16 @@ x.some.config.setting() {
|
||||||
## Everything from here to the end of file can be snipped and updated
|
## Everything from here to the end of file can be snipped and updated
|
||||||
## with latest from https://github.com/rwxrob/template-bash-command.
|
## with latest from https://github.com/rwxrob/template-bash-command.
|
||||||
|
|
||||||
# -------------------------- utility command -------------------------
|
# ------------------------------- usage ------------------------------
|
||||||
|
|
||||||
HELP[usage]='Displays a summary of usage.'
|
HELP[usage]='
|
||||||
|
|
||||||
|
```
|
||||||
|
'"$EXE"' usage
|
||||||
|
```
|
||||||
|
|
||||||
|
Display all possible commands. Note that this is usually easier by
|
||||||
|
simply using tab completion instead.'
|
||||||
|
|
||||||
x.usage() {
|
x.usage() {
|
||||||
local -a cmds
|
local -a cmds
|
||||||
|
@ -201,7 +245,7 @@ x.usage() {
|
||||||
printf "usage: %s (%s)\n" "$EXE" "${cmds[*]}"
|
printf "usage: %s (%s)\n" "$EXE" "${cmds[*]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# --------------------------- help command ---------------------------
|
# ------------------------------- help -------------------------------
|
||||||
|
|
||||||
HELP[help]='
|
HELP[help]='
|
||||||
|
|
||||||
|
@ -221,17 +265,19 @@ Also see `readme` and `usage` commands.
|
||||||
'
|
'
|
||||||
|
|
||||||
x.help() {
|
x.help() {
|
||||||
local name="${1:-main}" title body
|
local name="${1:-main}" title body file
|
||||||
title=$(_help_title "$name") || true
|
title=$(_help_title "$name") || true
|
||||||
if [[ -z "$title" ]]; then
|
if [[ -z "$title" ]]; then
|
||||||
body="${HELP[$name]}"
|
|
||||||
title="$EXE $name"
|
title="$EXE $name"
|
||||||
[[ $name = main ]] && title="$EXE"
|
[[ $name == main ]] && title="$EXE"
|
||||||
|
fi
|
||||||
|
if [[ $name == main ]]; then
|
||||||
|
body=$(x.readme)
|
||||||
|
body=${body#*$title}
|
||||||
else
|
else
|
||||||
body="${HELP[$name]}"
|
body="${HELP[$name]}"
|
||||||
body=${body#*$title}
|
|
||||||
fi
|
fi
|
||||||
local file="/tmp/help-$EXE-$name.html"
|
file="/tmp/help-$EXE-$name.html"
|
||||||
if _have pandoc ; then
|
if _have pandoc ; then
|
||||||
if _have "$HELP_BROWSER" && [[ -t 1 ]] ;then
|
if _have "$HELP_BROWSER" && [[ -t 1 ]] ;then
|
||||||
pandoc -f gfm -s --metadata title="$title" \
|
pandoc -f gfm -s --metadata title="$title" \
|
||||||
|
@ -256,7 +302,7 @@ _help_title() {
|
||||||
done <<< "${HELP[$name]}"
|
done <<< "${HELP[$name]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# -------------------------- readme command --------------------------
|
# ------------------------------ readme ------------------------------
|
||||||
|
|
||||||
HELP[readme]='
|
HELP[readme]='
|
||||||
## Generate `README.md` File
|
## Generate `README.md` File
|
||||||
|
@ -281,44 +327,46 @@ x.readme() {
|
||||||
echo -e "----\n\n*Autogenerated $(date)*\n"
|
echo -e "----\n\n*Autogenerated $(date)*\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# x.json() { _jsonstr "$@"; }
|
# ------------------------------ config ------------------------------
|
||||||
# x.urlencode() { _urlencode "$@"; }
|
|
||||||
|
|
||||||
# -------------------------- config command --------------------------
|
|
||||||
|
|
||||||
HELP[config]='
|
HELP[config]='
|
||||||
|
|
||||||
```
|
```
|
||||||
'"$EXE"' config
|
'"$EXE"' config
|
||||||
'"$EXE"' config KEY
|
'"$EXE"' config KEY
|
||||||
'"$EXE"' config KEY VALUE
|
'"$EXE"' config.set KEY VALUE
|
||||||
'"$EXE"' config KEY ""
|
'"$EXE"' config.set KEY ""
|
||||||
'"$EXE"' config keys
|
'"$EXE"' config.keys
|
||||||
'"$EXE"' config val[ues]
|
'"$EXE"' config.values
|
||||||
'"$EXE"' config dir[ectory]
|
'"$EXE"' config.directory
|
||||||
'"$EXE"' config path [file]
|
'"$EXE"' config.path [file]
|
||||||
'"$EXE"' config edit [file]
|
'"$EXE"' config.edit [file]
|
||||||
'"$EXE"' config del[ete]
|
'"$EXE"' config.delete
|
||||||
|
'"$EXE"' config.read
|
||||||
|
'"$EXE"' config.write
|
||||||
|
'"$EXE"' config.dump
|
||||||
```
|
```
|
||||||
|
|
||||||
The `config` command is for reading, writing, and displaying standard
|
The `config` command is for reading, writing, and displaying standard
|
||||||
open desktop configuration properties. Pass an empty string to delete
|
open desktop configuration properties.
|
||||||
a property.
|
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
With no arguments outputs all the currently cached configuration
|
With no arguments calls `dump` and outputs all the currently cached
|
||||||
settings.
|
configuration settings.
|
||||||
|
|
||||||
With a single KEY argument fetches the value for that key and outputs
|
With a single KEY argument fetches the value for that key and outputs
|
||||||
it unless it is one of the following special (reserved) key names:
|
it unless it is one of the following special (reserved) key names:
|
||||||
|
|
||||||
* `dir*` full path to config directory
|
* `directory` full path to config directory
|
||||||
* `path` full path to specific config file (default: `values`)
|
* `path` full path to specific config file (default: `values`)
|
||||||
* `edit` opens config file in editor (default: `editor` or `$EDITOR)
|
* `edit` opens config file in editor (default: `editor` or `$EDITOR)
|
||||||
* `keys` output the configuration keys, one per line
|
* `keys` output the configuration keys, one per line
|
||||||
* `val*` output the configuration values, one per line
|
* `values` output the configuration values, one per line
|
||||||
* `del*` if key argument then delete a specific key, otherwise prompt
|
* `delete` if key argument then delete a specific key, otherwise prompt
|
||||||
|
* `read` reads the configuration file into CONF associative array
|
||||||
|
* `write` write the CONF associative array to the configuration file
|
||||||
|
* `dump` write the flattened CONF associative array to standard output
|
||||||
|
|
||||||
With more than one argument the remaining arguments after the KEY will
|
With more than one argument the remaining arguments after the KEY will
|
||||||
be combined into the VALUE and written to a `values` file in the
|
be combined into the VALUE and written to a `values` file in the
|
||||||
|
@ -349,98 +397,94 @@ existing tools (and no `jq` dependency).
|
||||||
* KEYs may be anything but the equal sign (`=`)
|
* KEYs may be anything but the equal sign (`=`)
|
||||||
* VALUEs may be anything but line returns must be escaped
|
* VALUEs may be anything but line returns must be escaped
|
||||||
|
|
||||||
Note that this is *not* the same as Java properties and other similar
|
Note that, although similar, this is *not* the same as Java properties
|
||||||
format. It is designed for ultimate simplicity, efficiency, and
|
and other similar format. It is designed for ultimate simplicity,
|
||||||
portability.'
|
efficiency, and portability.'
|
||||||
|
|
||||||
x.config() {
|
x.config() {
|
||||||
case $1 in
|
|
||||||
dir*) shift; _config_dir "$@"; return $? ;;
|
|
||||||
path) shift; _config_path "$@"; return $? ;;
|
|
||||||
edit) shift; _config_edit "$@"; return $? ;;
|
|
||||||
del*) shift; _config_del "$@"; return $? ;;
|
|
||||||
keys) shift; _config_keys "$@"; return $? ;;
|
|
||||||
val*) shift; _config_vals "$@"; return $? ;;
|
|
||||||
esac
|
|
||||||
case $# in
|
case $# in
|
||||||
0) _config_dump ;;
|
0) x.config.dump ;;
|
||||||
1) _config_get "$@" ;;
|
1) x.config.get "$@" ;;
|
||||||
*) _config_set "$@" ;;
|
*) x.config.set "$@" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_edit() {
|
x.config.edit() {
|
||||||
: "${CONFIG[editor]:="${EDITOR:=vi}"}"
|
: "${CONF[editor]:="${EDITOR:=vi}"}"
|
||||||
exec "${CONFIG[editor]}" "$(_config_path "${1:-values}")"
|
exec "${CONF[editor]}" "$(x.config.path "${1:-values}")"
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_del() {
|
x.config.delete() {
|
||||||
if [[ -z "$1" ]];then
|
if [[ -z "$1" ]];then
|
||||||
select key in "${!CONFIG[@]}"; do
|
select key in "${!CONF[@]}"; do
|
||||||
_config_del "$key"
|
x.config.delete "$key"
|
||||||
return $?
|
return $?
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
_config_set "$1" ''
|
x.config.set "$1" ''
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_keys() { printf "%s\n" "${!CONFIG[@]}"; }
|
x.config.keys() { printf "%s\n" "${!CONF[@]}"; }
|
||||||
|
|
||||||
_config_vals() { printf "%s\n" "${CONFIG[@]}"; }
|
x.config.values() { printf "%s\n" "${CONF[@]}"; }
|
||||||
|
|
||||||
_config_dir() {
|
x.config.dir() {
|
||||||
local dir="$HOME/.config/$EXE"
|
local dir="$HOME/.config/$EXE"
|
||||||
[[ -n "$XDG_CONFIG_HOME" ]] && dir="$XDG_CONFIG_HOME/$EXE"
|
[[ -n "$XDG_CONFIG_HOME" ]] && dir="$XDG_CONFIG_HOME/$EXE"
|
||||||
[[ -n "$CONFIG_DIR" ]] && dir="$CONFIG_DIR"
|
[[ -n "$CONFIG_DIR" ]] && dir="$CONFIG_DIR"
|
||||||
[[ -n "$1" ]] && echo "$dir/$1" && return 0
|
[[ -n "$1" ]] && echo "$dir/$1" && return 0
|
||||||
printf "%s" "$dir"
|
printf "%s" "$dir"
|
||||||
[[ -t 1 ]] && echo
|
[[ -t 1 ]] && echo
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_path() {
|
x.config.path() {
|
||||||
local file=${1:-values}
|
local file=${1:-values}
|
||||||
printf "%s/%s" "$(_config_dir)" "$file"
|
printf "%s/%s" "$(x.config.dir)" "$file"
|
||||||
[[ -t 1 ]] && echo
|
[[ -t 1 ]] && echo
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_set() {
|
x.config.set() {
|
||||||
local key="$1"; shift; local val="$*"
|
local key="$1"; shift; local val="$*"
|
||||||
val="${val//$'\n'/\\n}"
|
val="${val//$'\n'/\\n}"
|
||||||
CONFIG["$key"]="$val"
|
CONF["$key"]="$val"
|
||||||
_config_write
|
x.config.write
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_get() {
|
x.config.get() {
|
||||||
printf "${CONFIG[$1]}"
|
printf "%s" "${CONF[$1]}"
|
||||||
[[ -t 1 ]] && echo
|
[[ -t 1 ]] && echo
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_read() {
|
x.config.read() {
|
||||||
local values="$(_config_path)"
|
local values="$(x.config.path)"
|
||||||
[[ -r "$values" ]] || return 0
|
[[ -r "$values" ]] || return 0
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
[[ $line =~ ^([^=]+)=(.+)$ ]] || continue
|
[[ $line =~ ^([^=]+)=(.+)$ ]] || continue
|
||||||
CONFIG["${BASH_REMATCH[1]}"]="${BASH_REMATCH[2]}"
|
CONF["${BASH_REMATCH[1]}"]="${BASH_REMATCH[2]}"
|
||||||
done < "$values"
|
done < "$values"
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_write() {
|
x.config.write() {
|
||||||
local dir="$(_config_dir)"
|
local dir="$(x.config.dir)"
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir"
|
||||||
_config_dump > "$dir/values"
|
x.config.dump > "$dir/values"
|
||||||
}
|
}
|
||||||
|
|
||||||
_config_dump() {
|
x.config.dump() {
|
||||||
(( ${#CONFIG[@]} == 0 )) && return 0
|
(( ${#CONF[@]} == 0 )) && return 0
|
||||||
paste -d=\
|
paste -d=\
|
||||||
<(printf "%s\n" "${!CONFIG[@]}") \
|
<(printf "%s\n" "${!CONF[@]}") \
|
||||||
<(printf "%s\n" "${CONFIG[@]}")
|
<(printf "%s\n" "${CONF[@]}") \
|
||||||
|
| sort
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----------------------------- utilities ----------------------------
|
# ----------------------------- utilities ----------------------------
|
||||||
|
|
||||||
_jsonstr() {
|
_jsonstr() {
|
||||||
_checkdep jq
|
_checkdep jq || return $?
|
||||||
_buffer "$@" && return $?
|
_buffer "$@" && return $?
|
||||||
jq -MRsc <<< "$1"
|
jq -MRsc <<< "$1"
|
||||||
}
|
}
|
||||||
|
@ -471,7 +515,7 @@ _reduce() {
|
||||||
|
|
||||||
_newest() {
|
_newest() {
|
||||||
IFS=$'\n'
|
IFS=$'\n'
|
||||||
local -a f=($(ls -1 --color=never -trd ${1:-.}/* 2>/dev/null))
|
mapfile -t f < <(ls -1 --color=never -trd "${1:-.}"/* 2>/dev/null)
|
||||||
[[ ${#f} > 0 ]] && echo "${f[-1]}"
|
[[ ${#f} > 0 ]] && echo "${f[-1]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,6 +524,8 @@ _trim() {
|
||||||
echo -e "${it%"${it##*[![:space:]]}"}"
|
echo -e "${it%"${it##*[![:space:]]}"}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_join() { local IFS="$1"; shift; echo "$*"; }
|
||||||
|
|
||||||
_have(){ type "$1" &>/dev/null; }
|
_have(){ type "$1" &>/dev/null; }
|
||||||
|
|
||||||
_checkdep() {
|
_checkdep() {
|
||||||
|
@ -500,9 +546,29 @@ _buffer() {
|
||||||
"${FUNCNAME[1]}" "$(</dev/stdin)"
|
"${FUNCNAME[1]}" "$(</dev/stdin)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_prompt() {
|
||||||
|
local key="$1" def="$2" regx="$3" value first=yes
|
||||||
|
shift 3
|
||||||
|
local text="${*:-Enter value for %s [%s]: }"
|
||||||
|
[[ -z "$key" ]] && echo "Missing prompt key" >&2 && return 1
|
||||||
|
[[ -z "$regx" ]] && echo "Missing valid regx" >&2 && return 1
|
||||||
|
while [[ ! $value =~ $regx ]];do
|
||||||
|
printf "$text" "$key" "$def" >&2
|
||||||
|
IFS= read -r value
|
||||||
|
[[ -z "$value" ]] && value="$def"
|
||||||
|
[[ $value =~ ^\ +$ ]] && value=""
|
||||||
|
[[ -n "$first" ]] && unset first && continue
|
||||||
|
echo "Must match /$regx/" >&2
|
||||||
|
done
|
||||||
|
_trim "$value"
|
||||||
|
}
|
||||||
|
|
||||||
# --------------------- completion and delegation --------------------
|
# --------------------- completion and delegation --------------------
|
||||||
# `complete -C foo foo` > `source <(foo bloated_completion)`
|
# `complete -C foo foo` > `source <(foo bloated_completion)`
|
||||||
|
|
||||||
|
x.config.read
|
||||||
|
_have _initialize && _initialize "$@"
|
||||||
|
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
[[ $line =~ ^declare\ -f\ x\. ]] || continue
|
[[ $line =~ ^declare\ -f\ x\. ]] || continue
|
||||||
COMMANDS+=( "${line##declare -f x.}" )
|
COMMANDS+=( "${line##declare -f x.}" )
|
||||||
|
@ -518,9 +584,6 @@ if [[ -n $COMP_LINE ]]; then
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_config_read
|
|
||||||
_initialize
|
|
||||||
|
|
||||||
for c in "${COMMANDS[@]}"; do
|
for c in "${COMMANDS[@]}"; do
|
||||||
if [[ $c == "$EXE" ]]; then
|
if [[ $c == "$EXE" ]]; then
|
||||||
"x.$EXE" "$@"
|
"x.$EXE" "$@"
|
||||||
|
@ -529,13 +592,19 @@ for c in "${COMMANDS[@]}"; do
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -n "$1" ]]; then
|
if [[ -n "$1" ]]; then
|
||||||
declare cmd="$1"; shift
|
declare CMD="$1"; shift
|
||||||
for c in "${COMMANDS[@]}"; do
|
for c in "${COMMANDS[@]}"; do
|
||||||
if [[ $c == "$cmd" ]]; then
|
declare cmd=$(command -v "x.$c")
|
||||||
"x.$cmd" "$@"
|
if [[ $c == "$CMD" && -n "$cmd" ]]; then
|
||||||
|
"x.$CMD" "$@"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if _have _alternatives; then
|
||||||
|
_alternatives "$@"
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
x.usage "$@"
|
x.usage "$@"
|
||||||
|
|
Loading…
Reference in New Issue