Skip to content

Commit

Permalink
Merge pull request #3 from doekman/list-and-prompt
Browse files Browse the repository at this point in the history
List and prompt
  • Loading branch information
secretGeek authored Jul 15, 2018
2 parents 29fda9b + 1021954 commit a98cf28
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 48 deletions.
17 changes: 13 additions & 4 deletions .ok
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
## "ok" gives you .ok folder profiles for bash


💡 Tip: "." (i.e. source) the "ok" script from your profile (.bashrc), e.g:
💡 Tip: "." (i.e. source) the "ok.sh" script from your profile (.bashrc), e.g:

. ~/ok
. ~/ok.sh

See <http://secretgeek.net/ok> for description of how to use "ok"

Expand Down
42 changes: 0 additions & 42 deletions ok

This file was deleted.

155 changes: 155 additions & 0 deletions ok.sh
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
}

0 comments on commit a98cf28

Please sign in to comment.