diff --git a/lib/composure.sh b/lib/composure.sh index 1bbf400d..8ca66d66 100644 --- a/lib/composure.sh +++ b/lib/composure.sh @@ -1,191 +1,27 @@ # composure - by erichs -# light-hearted shell functions for intuitive shell programming +# light-hearted functions for intuitive shell programming # install: source this script in your ~/.profile or ~/.${SHELL}rc script # latest source available at http://git.io/composure # known to work on bash, zsh, and ksh93 -# define default metadata keywords: -about () { :; } -group () { :; } -param () { :; } -author () { :; } -example () { :; } +# 'plumbing' functions -cite () +composure_keywords () { - about creates a new meta keyword for use in your functions - param 1: keyword - example $ cite url - example $ url http://somewhere.com - group composure - - # this is the storage half of the 'metadata' system: - # we create dynamic metadata keywords with function wrappers around - # the NOP command, ':' - - # anything following a keyword will get parsed as a positional - # parameter, but stay resident in the ENV. As opposed to shell - # comments, '#', which do not get parsed, thus are not available - # at runtime. - - # a BIG caveat--your metadata must be roughly parsable: do not use - # contractions, and consider single or double quoting if it contains - # non-alphanumeric characters - - typeset keyword - for keyword in $*; do - eval "function $keyword { :; }" - done -} - -draft () -{ - about wraps last command into a new function - param 1: name to give function - example $ ls - example $ draft list - example $ list - group composure - - typeset func=$1 - eval 'function ' $func ' { ' $(fc -ln -1) '; }' - typeset file=$(mktemp /tmp/draft.XXXX) - typeset -f $func > $file - transcribe $func $file draft - rm $file 2>/dev/null -} - -glossary () -{ - about displays help summary for all functions, or summary for a group of functions - param 1: optional, group name - example $ glossary - example $ glossary misc - group composure - - typeset targetgroup=${1:-} - - for func in $(listfunctions); do - typeset about="$(metafor $func about)" - if [ -n "$targetgroup" ]; then - typeset group="$(metafor $func group)" - if [ "$group" != "$targetgroup" ]; then - continue # skip non-matching groups, if specified - fi - fi - letterpress "$about" $func - done + echo "about author example group param version" } letterpress () { - typeset metadata=$1 leftcol=${2:- } rightcol + typeset rightcol="$1" leftcol="${2:- }" - if [ -z "$metadata" ]; then + if [ -z "$rightcol" ]; then return fi - OLD=$IFS; IFS=$'\n' - for rightcol in $metadata; do - printf "%-20s%s\n" $leftcol $rightcol - done - IFS=$OLD -} - -listfunctions () -{ - # unfortunately, there does not seem to be a easy, portable way to list just the - # names of the defined shell functions... - - # here's a hack I modified from a StackOverflow post: - # we loop over the ps listing for the current process ($$), and print the last column (CMD) - # stripping any leading hyphens bash sometimes throws in there - - typeset x ans - typeset this=$(for x in $(ps -p $$); do ans=$x; done; printf "%s\n" $ans | sed 's/^-*//') - case "$this" in - bash) - typeset -F | awk '{print $3}' - ;; - *) - # trim everything following '()' in ksh - typeset +f | sed 's/().*$//' - ;; - esac -} - -metafor () -{ - about prints function metadata associated with keyword - param 1: function name - param 2: meta keyword - example $ metafor glossary example - group composure - typeset func=$1 keyword=$2 - - # this sed-fu is the retrieval half of the 'metadata' system: - # first 'cat' the function definition, - # then 'grep' for the metadata keyword, and - # then parse and massage the matching line - typeset -f $func | sed -n "s/;$//;s/^[ ]*$keyword \([^([].*\)*$/\1/p" -} - -reference () -{ - about displays apidoc help for a specific function - param 1: function name - example $ reference revise - group composure - - typeset func=$1 - - typeset about="$(metafor $func about)" - letterpress "$about" $func - - typeset params="$(metafor $func param)" - if [ -n "$params" ]; then - printf "parameters:\n" - letterpress "$params" - fi - - typeset examples="$(metafor $func example)" - if [ -n "$examples" ]; then - printf "examples:\n" - letterpress "$examples" - fi -} - -revise () -{ - about loads function into editor for revision - param 1: name of function - example $ revise myfunction - group composure - - typeset func=$1 - typeset temp=$(mktemp /tmp/revise.XXXX) - - # populate tempfile... - if [ -f ~/.composure/$func.inc ]; then - # ...with contents of latest git revision... - cat ~/.composure/$func.inc >> $temp - else - # ...or from ENV if not previously versioned - typeset -f $func >> $temp - fi - - if [ -z "$EDITOR" ] - then - typeset EDITOR=vi - fi - - $EDITOR $temp - source $temp - - transcribe $func $temp revise - rm $temp + printf "%-20s%s\n" "$leftcol" "$rightcol" } transcribe () @@ -246,6 +82,332 @@ transcribe () fi } +transcribe () +{ + typeset func=$1 + typeset file=$2 + typeset operation="$3" + + if git --version >/dev/null 2>&1; then + if [ -d ~/.composure ]; then + ( + cd ~/.composure + if git rev-parse 2>/dev/null; then + if [ ! -f $file ]; then + printf "%s\n" "Oops! Couldn't find $file to version it for you..." + return + fi + cp $file ~/.composure/$func.inc + git add --all . + git commit -m "$operation $func" + fi + ) + else + if [ "$USE_COMPOSURE_REPO" = "0" ]; then + return # if you say so... + fi + printf "%s\n" "I see you don't have a ~/.composure repo..." + typeset input + typeset valid=0 + while [ $valid != 1 ]; do + printf "\n%s" 'would you like to create one? y/n: ' + read input + case $input in + y|yes|Y|Yes|YES) + ( + echo 'creating git repository for your functions...' + mkdir ~/.composure + cd ~/.composure + git init + echo "composure stores your function definitions here" > README.txt + git add README.txt + git commit -m 'initial commit' + ) + # if at first you don't succeed... + transcribe "$func" "$file" "$operation" + valid=1 + ;; + n|no|N|No|NO) + printf "%s\n" "ok. add 'export USE_COMPOSURE_REPO=0' to your startup script to disable this message." + valid=1 + ;; + *) + printf "%s\n" "sorry, didn't get that..." + ;; + esac + done + fi + fi +} + +typeset_functions () +{ + # unfortunately, there does not seem to be a easy, portable way to list just the + # names of the defined shell functions... + + # here's a hack I modified from a StackOverflow post: + # we loop over the ps listing for the current process ($$), and print the last column (CMD) + # stripping any leading hyphens bash sometimes throws in there + + typeset x ans + typeset this=$(for x in $(ps -p $$); do ans=$x; done; printf "%s\n" $ans | sed 's/^-*//') + typeset shell=$(basename $this) # e.g. /bin/bash => bash + case "$shell" in + bash) + typeset -F | awk '{print $3}' + ;; + *) + # trim everything following '()' in ksh + typeset +f | sed 's/().*$//' + ;; + esac +} + + +# bootstrap metadata keywords for porcelain functions +for f in $(composure_keywords) +do + eval "$f() { :; }" +done +unset f + + +# 'porcelain' functions + +cite () +{ + about creates one or more meta keywords for use in your functions + param one or more keywords + example '$ cite url username' + example '$ url http://somewhere.com' + example '$ username alice' + group composure + + # this is the storage half of the 'metadata' system: + # we create dynamic metadata keywords with function wrappers around + # the NOP command, ':' + + # anything following a keyword will get parsed as a positional + # parameter, but stay resident in the ENV. As opposed to shell + # comments, '#', which do not get parsed and are not available + # at runtime. + + # a BIG caveat--your metadata must be roughly parsable: do not use + # contractions, and consider single or double quoting if it contains + # non-alphanumeric characters + + if [ -z "$1" ]; then + printf '%s\n' 'missing parameter(s)' + reference cite + return + fi + + typeset keyword + for keyword in $*; do + eval "$keyword() { :; }" + done +} + +draft () +{ + about wraps command from history into a new function, default is last command + param 1: name to give function + param 2: optional history line number + example '$ ls' + example '$ draft list' + example '$ draft newfunc 1120 # wraps command at history line 1120 in newfunc()' + group composure + + typeset func=$1 + typeset num=$2 + typeset cmd + + if [ -z "$func" ]; then + printf '%s\n' 'missing parameter(s)' + reference draft + return + fi + + # aliases bind tighter than function names, disallow them + if [ -n "$(type -a $func | grep 'is.*alias')" ]; then + printf '%s\n' "sorry, $(type -a $func). please choose another name." + return + fi + + if [ -z "$num" ]; then + # parse last command from fc output + # some versions of 'fix command, fc' need corrective lenses... + typeset myopic=$(fc -ln -1 | grep draft) + typeset lines=1 + if [ -n "$myopic" ]; then + lines=2 + fi + cmd=$(fc -ln -$lines | head -1 | sed 's/^[[:blank:]]*//') + else + # parse command from history line number + cmd=$(eval "history | grep '^[[:blank:]]*$num' | head -1" | sed 's/^[[:blank:][:digit:]]*//') + fi + eval "$func() { $cmd; }" + typeset file=$(mktemp /tmp/draft.XXXX) + typeset -f $func > $file + transcribe $func $file draft + rm $file 2>/dev/null +} + +glossary () +{ + about displays help summary for all functions, or summary for a group of functions + param 1: optional, group name + example '$ glossary' + example '$ glossary misc' + group composure + + typeset targetgroup=${1:-} + + for func in $(typeset_functions); do + if [ -n "$targetgroup" ]; then + typeset group="$(typeset -f $func | metafor group)" + if [ "$group" != "$targetgroup" ]; then + continue # skip non-matching groups, if specified + fi + fi + typeset about="$(typeset -f $func | metafor about)" + letterpress "$about" $func + done +} + +metafor () +{ + about prints function metadata associated with keyword + param 1: meta keyword + example '$ typeset -f glossary | metafor example' + group composure + + typeset keyword=$1 + + if [ -z "$keyword" ]; then + printf '%s\n' 'missing parameter(s)' + reference metafor + return + fi + + # this sed-fu is the retrieval half of the 'metadata' system: + # 'grep' for the metadata keyword, and then parse/filter the matching line + + # grep keyword # strip trailing '|"|; # ignore thru keyword and leading '|" + sed -n "/$keyword / s/['\";]*$//;s/^[ ]*$keyword ['\"]*\([^([].*\)*$/\1/p" +} + +reference () +{ + about displays apidoc help for a specific function + param 1: function name + example '$ reference revise' + group composure + + typeset func=$1 + if [ -z "$func" ]; then + printf '%s\n' 'missing parameter(s)' + reference reference + return + fi + + typeset line + + typeset about="$(typeset -f $func | metafor about)" + letterpress "$about" $func + + typeset author="$(typeset -f $func | metafor author)" + if [ -n "$author" ]; then + letterpress "$author" 'author:' + fi + + typeset version="$(typeset -f $func | metafor version)" + if [ -n "$version" ]; then + letterpress "$version" 'version:' + fi + + if [ -n "$(typeset -f $func | metafor param)" ]; then + printf "parameters:\n" + typeset -f $func | metafor param | while read line + do + letterpress "$line" + done + fi + + if [ -n "$(typeset -f $func | metafor example)" ]; then + printf "examples:\n" + typeset -f $func | metafor example | while read line + do + letterpress "$line" + done + fi +} + +revise () +{ + about loads function into editor for revision + param 1: name of function + example '$ revise myfunction' + group composure + + typeset func=$1 + typeset temp=$(mktemp /tmp/revise.XXXX) + + if [ -z "$func" ]; then + printf '%s\n' 'missing parameter(s)' + reference revise + return + fi + + # populate tempfile... + if [ -f ~/.composure/$func.inc ]; then + # ...with contents of latest git revision... + cat ~/.composure/$func.inc >> $temp + else + # ...or from ENV if not previously versioned + typeset -f $func >> $temp + fi + + if [ -z "$EDITOR" ] + then + typeset EDITOR=vi + fi + + $EDITOR $temp + . $temp # source edited file + + transcribe $func $temp revise + rm $temp +} + +write () +{ + about writes one or more composed function definitions to stdout + param one or more function names + example '$ write finddown foo' + example '$ write finddown' + group composure + + if [ -z "$1" ]; then + printf '%s\n' 'missing parameter(s)' + reference write + return + fi + +# bootstrap metadata +cat <]*>//g' } myip () { about displays your ip address, as seen by the Internet + group base res=$(curl -s checkip.dyndns.org | grep -Eo '[0-9\.]+') echo -e "Your public IP is: ${echo_bold_green} $res ${echo_normal}" } @@ -29,6 +33,7 @@ pickfrom () about picks random line from file param 1: filename example '$ pickfrom /usr/share/dict/words' + group base local file=$1 [ -z "$file" ] && reference $FUNCNAME && return length=$(cat $file | wc -l) @@ -43,6 +48,7 @@ pass () param if unset, defaults to 4 example '$ pass' example '$ pass 6' + group base local i pass length=${1:-4} pass=$(echo $(for i in $(eval echo "{1..$length}"); do pickfrom /usr/share/dict/words; done)) echo "With spaces (easier to memorize): $pass" @@ -54,6 +60,7 @@ pmdown () about preview markdown file in a browser param 1: markdown file example '$ pmdown README.md' + group base if command -v markdown &>/dev/null then markdown $1 | browser @@ -68,6 +75,7 @@ mkcd () param path to create example '$ mkcd foo' example '$ mkcd /tmp/img/photos/large' + group base mkdir -p "$*" cd "$*" } @@ -75,6 +83,7 @@ mkcd () lsgrep () { about search through directory contents with grep + group base ls | grep "$*" } @@ -84,6 +93,7 @@ pman () about view man documentation in Preview param 1: man page to view example '$ pman bash' + group base man -t "${1}" | open -f -a $PREVIEW } @@ -93,6 +103,7 @@ pcurl () about download file and Preview it param 1: download URL example '$ pcurl http://www.irs.gov/pub/irs-pdf/fw4.pdf' + group base curl "${1}" | open -f -a $PREVIEW } @@ -101,17 +112,21 @@ pri () about display information about Ruby classes, modules, or methods, in Preview param 1: Ruby method, module, or class example '$ pri Array' + group base ri -T "${1}" | open -f -a $PREVIEW } quiet () { + about 'what *does* this do?' + group base $* &> /dev/null & } banish-cookies () { about redirect .adobe and .macromedia files to /dev/null + group base rm -r ~/.macromedia ~/.adobe ln -s /dev/null ~/.adobe ln -s /dev/null ~/.macromedia @@ -121,6 +136,7 @@ usage () { about disk usage per directory, in Mac OS X and Linux param 1: directory name + group base if [ $(uname) = "Darwin" ]; then if [ -n $1 ]; then du -hd $1 @@ -142,6 +158,7 @@ t () about one thing todo param if not set, display todo item param 1: todo text + group base if [[ "$*" == "" ]] ; then cat ~/.t else @@ -154,25 +171,23 @@ command_exists () about checks for existence of a command param 1: command to check example '$ command_exists ls && echo exists' + group base type "$1" &> /dev/null ; } plugins-help () { about list all plugins and functions defined by bash-it - echo "bash-it Plugins Help-Message" - echo - - set | grep "()" \ - | sed -e "/^_/d" | grep -v "BASH_ARGC=()" \ - | sed -e "/^\s/d" | grep -v "BASH_LINENO=()" \ - | grep -v "BASH_ARGV=()" \ - | grep -v "BASH_SOURCE=()" \ - | grep -v "DIRSTACK=()" \ - | grep -v "GROUPS=()" \ - | grep -v "BASH_CMDS=()" \ - | grep -v "BASH_ALIASES=()" \ - | grep -v "COMPREPLY=()" | sed -e "s/()//" + group base + printf '%s\n' "bash-it plugins help" + printf '\n' + typeset group + for group in $(all_groups) + do + printf '%s\n' "group: $group" + glossary $group + printf '\n' + done } # useful for administrators and configs @@ -180,7 +195,34 @@ buf () { about back up file with timestamp param filename + group base local filename=$1 local filetime=$(date +%Y%m%d_%H%M%S) cp ${filename} ${filename}_${filetime} } + +all_groups () +{ + about displays all unique metadata groups + group base + typeset func + typeset file=$(mktemp /tmp/composure.XXXX) + for func in $(typeset_functions) + do + typeset -f $func | metafor group >> $file + done + cat $file | sort | uniq + rm $file +} + +available_plugins () +{ + about summarizes available bash_it plugins + group base + + typeset f + for f in $BASH_IT/plugins/available/*.bash + do + letterpress "$(cat $f | metafor about-plugin)" "$(basename $f | cut -d'.' -f1)" + done +} diff --git a/plugins/available/battery.plugin.bash b/plugins/available/battery.plugin.bash old mode 100644 new mode 100755 index 4b9d4b98..4c0e3803 --- a/plugins/available/battery.plugin.bash +++ b/plugins/available/battery.plugin.bash @@ -1,11 +1,17 @@ #!/usr/bin/env bash +cite about-plugin +about-plugin query and display info about your battery charge level + battery_percentage(){ + about 'displays battery charge as a percentage of full (100%)' + group battery + if command_exists acpi; then local ACPI_OUTPUT=$(acpi -b) case $ACPI_OUTPUT in - *" Unknown"*) + *" Unknown"*) local PERC_OUTPUT=$(echo $ACPI_OUTPUT | head -c 22 | tail -c 2) case $PERC_OUTPUT in *%) @@ -16,7 +22,7 @@ battery_percentage(){ ;; esac ;; - *" Discharging"*) + *" Discharging"*) local PERC_OUTPUT=$(echo $ACPI_OUTPUT | head -c 26 | tail -c 2) case $PERC_OUTPUT in *%) @@ -27,7 +33,7 @@ battery_percentage(){ ;; esac ;; - *" Charging"*) + *" Charging"*) local PERC_OUTPUT=$(echo $ACPI_OUTPUT | head -c 23 | tail -c 2) case $PERC_OUTPUT in *%) @@ -38,7 +44,7 @@ battery_percentage(){ ;; esac ;; - *" Full"*) + *" Full"*) echo '99' ;; *) @@ -52,7 +58,7 @@ battery_percentage(){ #local IOREG_OUTPUT_10_5=$(ioreg -l | grep -i capacity | grep -v Legacy| tr '\n' ' | ' | awk '{printf("%.2f%%", $14/$7 * 100)}') local IOREG_OUTPUT=$(ioreg -n AppleSmartBattery -r | awk '$1~/Capacity/{c[$1]=$3} END{OFMT="%.2f%%"; max=c["\"MaxCapacity\""]; print (max>0? 100*c["\"CurrentCapacity\""]/max: "?")}') case $IOREG_OUTPUT in - 100*) + 100*) echo '99' ;; *) @@ -65,6 +71,9 @@ battery_percentage(){ } battery_charge(){ + about graphical display of your battery charge + group battery + # Full char local F_C='▸' # Depleted char diff --git a/plugins/available/browser.plugin.bash b/plugins/available/browser.plugin.bash index fdfba4f6..7ad2f4be 100644 --- a/plugins/available/browser.plugin.bash +++ b/plugins/available/browser.plugin.bash @@ -1,42 +1,34 @@ # based on https://gist.github.com/318247 -# Usage: browser -# pipe html to a browser -# e.g. -# $ echo "

hi mom!

" | browser -# $ ron -5 man/rip.5.ron | browser +cite about-plugin +about-plugin 'render commandline output in your browser' function browser() { + about pipe html to a browser + example '$ echo "

hi mom!

" | browser' + example '$ ron -5 man/rip.5.ron | browser' + group browser + if [ -t 0 ]; then if [ -n "$1" ]; then open $1 else - cat <hi mom!' | browser -$ ron -5 man/rip.5.ron | browser -usage - - fi + reference browser + fi else f="/tmp/browser.$RANDOM.html" cat /dev/stdin > $f - open $f + open $f fi } -# pipe hot spicy interwebs into textmate and cleanup! -# -# Usage: wmate -# wget into a pipe into TextMate and force Tidy (you can undo in textmate) -# e.g. -# $ wmate google.com - function wmate() { + about 'pipe hot spicy interwebs into textmate and cleanup!' + example '$ wmate google.com' + group browser + if [ -t 0 ]; then if [ -n "$1" ]; then wget -qO- $1 | /usr/bin/mate @@ -64,34 +56,21 @@ end tell EOT` else - cat <