-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from doekman/list-and-prompt
List and prompt
- Loading branch information
Showing
4 changed files
with
170 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,13 @@ | ||
# Manipulate customizations (colors) | ||
unset _OK_C_HEADING;unset _OK_C_NUMBER;unset _OK_C_COMMENT;unset _OK_C_COMMAND;unset _OK_C_PROMPT #Reset colors to defaults | ||
_OK_C_HEADING="[h]";_OK_C_NUMBER="[n]";_OK_C_COMMENT="[--]";_OK_C_COMMAND="[C]";_OK_C_PROMPT="[p]" #Change colors to text markers for debugging | ||
_OK_C_HEADING=$'\033[1;30;45m';_OK_C_NUMBER=$'\033[1;33;44m';_OK_C_COMMENT=$'\033[1;34;46m';_OK_C_COMMAND=$'\033[1;37;44m' #Custom color scheme | ||
# Manipulate customizations (colors) | ||
unset _OK_C_HEADING;unset _OK_C_NUMBER;unset _OK_C_COMMENT;unset _OK_C_COMMAND;unset _OK_C_PROMPT #Reset colors to defaults | ||
_OK_C_HEADING="[h]";_OK_C_NUMBER="[n]";_OK_C_COMMENT="[--]";_OK_C_COMMAND="[C]";_OK_C_PROMPT="[p]" #Change colors to text markers for debugging | ||
_OK_C_HEADING=$'\033[1;30;45m';_OK_C_NUMBER=$'\033[1;33;44m ';_OK_C_COMMENT=$'\033[1;34;46m';_OK_C_COMMAND=$'\033[1;37;44m' #Custom color scheme | ||
# Other customizations | ||
unset _OK_PROMPT; unset _OK_VERBOSE # Reset to defaults | ||
_OK_PROMPT="-=> "; _OK_VERBOSE=2 # Show a "nice" prompt, and give all the feedback ok can provide for | ||
_OK_PROMPT="% "; _OK_VERBOSE=0 # Show ancient prompt, and only say the most necessary (don't even show executed command) | ||
|
||
# Tests arguments passing (you can pass arguments after <number>, both at the bash-prompt and the ok-prompt) | ||
echo "Passed arguments: 1:[$1], 2:[$2], 3:[$3], 4+:[${@:4}] (nr args: $#)" # Comment-color starts too early; clearly a bug (so better | ||
echo "All passed arguments: [$@]" # not to use a number sign in a command for now)... | ||
ok help --verbose # Show help page of 🆗, including environment variables |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
#!/usr/bin/env bash | ||
|
||
# tip: "." (i.e. source) this file from your profile (.bashrc), e.g. ". ~/path/to/ok-bash/ok.sh" | ||
|
||
ok() { | ||
function _ok_cmd_usage { | ||
unset -f _ok_cmd_usage #emulate a "local" function | ||
echo -e "Usage: ok [options] <number> [script-arguments..] | ||
ok command [options] | ||
command (use one): | ||
<number> Run the <number>th command from the '.ok' file. | ||
l, list Show the list from the '.ok' file. | ||
L, list-once Same as list, but only show when pwd is different from when the list was last shown. | ||
p, list-prompt Show the list and wait for input at the ok-prompt (like --list and <number> in one command). Default command. | ||
h, help Show this usage page. | ||
options: | ||
-v, --verbose Show more output, most of the time to stderr. | ||
-q, --quiet Only show really necessary output. | ||
script-arguments: | ||
... These are passed through, when a line is executed (you can enter these too at the ok-prompt)\n" | ||
|
||
if [[ $verbose -ge 2 ]]; then | ||
if [ -z ${_OK_PROMPT+x} ]; then local p="unset"; else local p="'$_OK_PROMPT'"; fi | ||
if [ -z ${_OK_VERBOSE+x} ]; then local v="unset"; else local v="'$_OK_VERBOSE'"; fi | ||
echo -e "environment variables (used for colored output; current colors are shown): | ||
_OK_C_HEADING ${_OK_C_HEADING}Color-code${C_NC} for lines starting with a comment (heading). Defaults to red. | ||
_OK_C_NUMBER ${_OK_C_NUMBER}Color-code${C_NC} for numbering. Defaults to cyan. | ||
_OK_C_COMMENT ${_OK_C_COMMENT}Color-code${C_NC} for comments after commands. Defaults to blue. | ||
_OK_C_COMMAND ${_OK_C_COMMAND}Color-code${C_NC} for commands. Defaults to color-reset. | ||
_OK_C_PROMPT ${_OK_C_PROMPT}Color-code${C_NC} for prompt (both input as command confirmation). Defaults to color for numbering. | ||
environment variables (other): | ||
_OK_PROMPT String ($p) used as prompt (both input as command confirmation). Defaults to '$ '. | ||
_OK_VERBOSE Level ($v) of feedback ok provides. 0=quiet, 1=normal, 2=verbose. Defaults to 1. Can be overriden with --verbose or --quiet.\n" | ||
fi | ||
if [[ -n $1 ]]; then | ||
echo -e "$1\n" | ||
return 1 | ||
fi | ||
} | ||
|
||
function _ok_cmd_run { | ||
unset -f _ok_cmd_run | ||
# save and remove argument. Remaining arguments are passwed to eval automatically | ||
local LINE_NR=$1 #LINE_NR is guaranteed to be 1 or more | ||
shift | ||
# get the line to be executed | ||
local LINE_TEXT=$( cat .ok | grep -vE "^(#|$)" | sed ${LINE_NR}'!d' ) | ||
if [[ -n $LINE_TEXT ]]; then | ||
if [[ $verbose -ge 1 ]]; then | ||
# output the command first | ||
echo -e "${C_PROMPT}${PROMPT}${C_COMMAND}${LINE_TEXT}${C_NC}" | sed -E "s/(#.*)\$/${C_COMMENT}\1/1" | ||
fi | ||
# finally execute the line | ||
eval $LINE_TEXT | ||
else | ||
if [[ $verbose -ge 2 ]]; then | ||
>&2 echo "ERROR: entered line number '$LINE_NR' does not exist" | ||
fi | ||
return 1 | ||
fi | ||
} | ||
|
||
function _ok_cmd_list { | ||
unset -f _ok_cmd_list | ||
# list the content of the file, with a number (1-based) before each line, | ||
# except lines starting with a "#", those are printed red without a number) as headers | ||
cat .ok | awk -v h="$C_HEADING" -v n="$C_NUMBER" -v c="$C_COMMENT" -v m="$C_COMMAND" -v x="$C_NC" $' | ||
$0 ~ /^(#|$)/ { | ||
#print the (sub-)headings and/or empty lines | ||
print x h $0 x; | ||
} | ||
$0 ~ /^[^#]/ { | ||
#print the commands | ||
sub(/#/,c "#"); | ||
print x n "" ++i "." m " " $0 x; | ||
}' | ||
} | ||
|
||
# used for colored output (see: https://stackoverflow.com/a/20983251/56) | ||
local C_NC=$(tput sgr 0) | ||
if [ -z ${_OK_C_HEADING+x} ]; then local C_HEADING=$(tput setaf 1); else local C_HEADING=$_OK_C_HEADING; fi #HEADING defaults to RED | ||
if [ -z ${_OK_C_NUMBER+x} ]; then local C_NUMBER=$(tput setaf 6); else local C_NUMBER=$_OK_C_NUMBER; fi #NUMBER defaults to CYAN | ||
if [ -z ${_OK_C_COMMENT+x} ]; then local C_COMMENT=$(tput setaf 4); else local C_COMMENT=$_OK_C_COMMENT; fi #COMMENT defaults to BLUE | ||
if [ -z ${_OK_C_COMMAND+x} ]; then local C_COMMAND=$C_NC; else local C_COMMAND=$_OK_C_COMMAND; fi #COMMAND defaults to NO COLOR | ||
if [ -z ${_OK_C_PROMPT+x} ]; then local C_PROMPT=$C_NUMBER; else local C_PROMPT=$_OK_C_PROMPT; fi #PROMPT defaults to same color as NUMBER | ||
# other customizations (some environment variables can be overridden by arguments) | ||
if [ -z ${_OK_PROMPT+x} ]; then local PROMPT="$ "; else local PROMPT=$_OK_PROMPT; fi | ||
if [ -z ${_OK_VERBOSE+x} ]; then local verbose=1; else local verbose=$_OK_VERBOSE; fi | ||
|
||
# handle command line arguments first | ||
local re_is_num='^[1-9][0-9]*$' #numbers starting with "0" would be octal, and nobody knows those (also: sed on Linux complains about line "0")... | ||
local cmd=list | ||
local line_nr=0 | ||
local once_check=0 | ||
local show_prompt=1 | ||
local usage_error= | ||
local loop_args=1 #the Pascal-way to break loops | ||
while (( $# > 0 && $loop_args == 1 )) ; do | ||
# if the user provided a parameter, $1, which contains a number... | ||
if [[ $1 =~ $re_is_num ]]; then | ||
cmd=run | ||
line_nr=$1 | ||
loop_args=0 | ||
else | ||
case $1 in | ||
#commands | ||
l | list) cmd=list; show_prompt=0; once_check=0;; | ||
L | list-once) cmd=list; show_prompt=0; once_check=1;; | ||
p | list-prompt) cmd=list; show_prompt=1; once_check=0;; | ||
h | help) cmd=usage;; | ||
#options | ||
-\? | -h | --help) cmd=usage;; | ||
-v | --verbose) verbose=2;; | ||
-q | --quiet) verbose=0;; | ||
*) cmd=usage; usage_error="Unknown command/option '$1'";; | ||
esac | ||
fi | ||
shift | ||
done | ||
|
||
# if there is a file called .ok... | ||
if [ -f .ok ]; then | ||
if [[ $cmd == run ]]; then | ||
_ok_cmd_run $line_nr "$@" || return $? | ||
elif [[ $cmd == list ]]; then | ||
if [[ $once_check == 0 || ($once_check == 1 && $_OK_LAST_PWD != $(pwd)) ]]; then | ||
_ok_cmd_list || return $? | ||
if [[ $show_prompt == 1 ]]; then | ||
local prompt_input | ||
local re_num_begin='^[1-9][0-9]*($| )' # You can enter arguments at the ok-prompt too, hence different regex | ||
read -p "${C_PROMPT}${PROMPT}${C_NC}" prompt_input | ||
if [[ $prompt_input =~ $re_num_begin ]]; then | ||
eval _ok_cmd_run $prompt_input || return $? | ||
else | ||
if [[ $verbose -ge 2 ]]; then | ||
>&2 echo "ERROR: input '$prompt_input' does not start with a number" | ||
fi | ||
return 1 | ||
fi | ||
fi | ||
fi | ||
if [[ $verbose -ge 2 && $once_check == 1 && $_OK_LAST_PWD == $(pwd) ]]; then | ||
echo "The listing for this folder has already been shown" | ||
fi | ||
export _OK_LAST_PWD=$(pwd) | ||
elif [[ $cmd == usage ]]; then | ||
_ok_cmd_usage "$usage_error" || return $? | ||
fi | ||
else | ||
if [[ $verbose -ge 2 ]]; then | ||
echo "Nothing to do: this folder doesn't have an '.ok' file" | ||
fi | ||
fi | ||
} |