Erich Smith | a8fcf9f | 2012-04-27 15:07:04 -0400 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # Composure - don't fear the UNIX chainsaw... |
| 3 | # by erichs, 2012 |
| 4 | |
| 5 | # these are a set of light-hearted shell functions that aim to make |
| 6 | # programming the shell easier and more intuitive |
| 7 | |
| 8 | # latest source available at http://git.io/composure |
| 9 | |
| 10 | source_composure () |
| 11 | { |
| 12 | if [ -z "$EDITOR" ] |
| 13 | then |
| 14 | export EDITOR=vi |
| 15 | fi |
| 16 | |
| 17 | if $(tty -s) # is this a TTY? |
| 18 | then |
| 19 | bind '"\C-j": edit-and-execute-command' |
| 20 | fi |
| 21 | |
| 22 | cite () |
| 23 | { |
| 24 | about () { :; } |
| 25 | about creates a new meta keyword for use in your functions |
| 26 | local keyword=$1 |
| 27 | for keyword in $*; do |
| 28 | eval "function $keyword { :; }" |
| 29 | done |
| 30 | } |
| 31 | |
| 32 | cite about param example |
| 33 | |
| 34 | draft () |
| 35 | { |
| 36 | about wraps last command into a new function |
| 37 | param 1: name to give function |
| 38 | example $ ls |
| 39 | example $ draft list |
| 40 | example $ list |
| 41 | local name=$1 |
| 42 | eval 'function ' $name ' { ' $(fc -ln -1) '; }' |
| 43 | } |
| 44 | |
| 45 | write () |
| 46 | { |
| 47 | about prints function declaration to stdout |
| 48 | param name of function or functions, separated by spaces |
| 49 | example $ write myfunction |
| 50 | example $ write func1 func2 func3 > ~/funcs.sh |
| 51 | local func |
| 52 | for func in $* |
| 53 | do |
| 54 | # trim trailing semicolons generated by declare -f |
| 55 | declare -f $func | sed "s/^\(.*\);$/\1/" |
| 56 | echo |
| 57 | done |
| 58 | } |
| 59 | |
| 60 | revise () |
| 61 | { |
| 62 | about loads function into editor for revision |
| 63 | param name of function or functions, separated by spaces |
| 64 | example $ revise myfunction |
| 65 | example $ revise func1 func2 func3 |
| 66 | local temp=$(mktemp /tmp/revise.XXXX) |
| 67 | write $* > $temp |
| 68 | $EDITOR $temp |
| 69 | eval "$(cat $temp)" |
| 70 | rm $temp |
| 71 | } |
| 72 | |
| 73 | metafor () |
| 74 | { |
| 75 | about prints function metadata associated with keyword |
| 76 | param 1: function name |
| 77 | param 2: meta keyword |
| 78 | example $ metafor reference example |
| 79 | local func=$1 keyword=$2 |
| 80 | write $func | sed -n "s/^ *$keyword \([^([].*\)$/\1/p" |
| 81 | } |
| 82 | |
| 83 | reference () |
| 84 | { |
| 85 | about displays help summary for all functions, or help for specific function |
| 86 | param 1: optional, function name |
| 87 | example $ reference |
| 88 | example $ reference metafor |
| 89 | |
| 90 | printline () |
| 91 | { |
| 92 | local metadata=$1 lhs=${2:- } |
| 93 | |
| 94 | if [[ -z "$metadata" ]] |
| 95 | then |
| 96 | return |
| 97 | fi |
| 98 | |
| 99 | OLD=$IFS; IFS=$'\n' |
| 100 | local line |
| 101 | for line in $metadata |
| 102 | do |
| 103 | printf "%-20s%s\n" $lhs $line |
| 104 | done |
| 105 | IFS=$OLD |
| 106 | } |
| 107 | |
| 108 | help () |
| 109 | { |
| 110 | local func=$1 |
| 111 | |
| 112 | local about="$(metafor $func about)" |
| 113 | printline "$about" $func |
| 114 | |
| 115 | local params="$(metafor $func param)" |
| 116 | if [[ -n "$params" ]] |
| 117 | then |
| 118 | echo "parameters:" |
| 119 | printline "$params" |
| 120 | fi |
| 121 | |
| 122 | local examples="$(metafor $func example)" |
| 123 | if [[ -n "$examples" ]] |
| 124 | then |
| 125 | echo "examples:" |
| 126 | printline "$examples" |
| 127 | fi |
| 128 | |
| 129 | unset printline |
| 130 | } |
| 131 | |
| 132 | if [[ -n "$1" ]] |
| 133 | then |
| 134 | help $1 |
| 135 | else |
| 136 | for func in $(compgen -A function); do |
| 137 | local about="$(metafor $func about)" |
| 138 | printline "$about" $func |
| 139 | done |
| 140 | fi |
| 141 | |
| 142 | unset help printline |
| 143 | } |
| 144 | |
| 145 | } |
| 146 | |
| 147 | install_composure () |
| 148 | { |
| 149 | echo 'stay calm. installing composure elements...' |
| 150 | |
| 151 | # find our absolute PATH |
| 152 | SOURCE="${BASH_SOURCE[0]}" |
| 153 | while [ -h "$SOURCE" ] |
| 154 | do |
| 155 | SOURCE="$(readlink "$SOURCE")" |
| 156 | done |
| 157 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" |
| 158 | |
| 159 | # vim: automatically chmod +x scripts with #! lines |
| 160 | done_previously () { [ ! -z "$(grep BufWritePost | grep bin | grep chmod)" ]; } |
| 161 | |
| 162 | if [ -f ~/.vimrc ] && ! $(<~/.vimrc done_previously) |
| 163 | then |
| 164 | echo 'vimrc: adding automatic chmod+x for files with shebang (#!) lines...' |
| 165 | echo 'au BufWritePost * if getline(1) =~ "^#!" | if getline(1) =~ "/bin/" | silent execute "!chmod a+x <afile>" | endif | endif' >> ~/.vimrc |
| 166 | fi |
| 167 | |
| 168 | # source this file in your startup: .bashrc, or .bash_profile |
| 169 | local done=0 |
| 170 | done_previously () { [ ! -z "$(grep source | grep $DIR | grep composure)" ]; } |
| 171 | |
| 172 | [ -f ~/.bashrc ] && $(<~/.bashrc done_previously) && done=1 |
| 173 | ! (($done)) && [ -f ~/.bash_profile ] && $(<~/.bash_profile done_previously) && done=1 |
| 174 | |
| 175 | if ! (($done)) |
| 176 | then |
| 177 | echo 'sourcing composure from .bashrc...' |
| 178 | echo "source $DIR/$(basename $0)" >> ~/.bashrc |
| 179 | fi |
| 180 | |
| 181 | echo 'composure installed.' |
| 182 | } |
| 183 | |
| 184 | if [[ "$BASH_SOURCE" == "$0" ]] |
| 185 | then |
| 186 | install_composure |
| 187 | else |
| 188 | source_composure |
| 189 | unset install_composure source_composure |
| 190 | fi |
| 191 | |
| 192 | : <<EOF |
| 193 | License: The MIT License |
| 194 | |
| 195 | Copyright © 2012 Erich Smith |
| 196 | |
| 197 | Permission is hereby granted, free of charge, to any person obtaining a copy of this |
| 198 | software and associated documentation files (the "Software"), to deal in the Software |
| 199 | without restriction, including without limitation the rights to use, copy, modify, |
| 200 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to |
| 201 | permit persons to whom the Software is furnished to do so, subject to the following |
| 202 | conditions: |
| 203 | |
| 204 | The above copyright notice and this permission notice shall be included in all copies |
| 205 | or substantial portions of the Software. |
| 206 | |
| 207 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
| 208 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
| 209 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| 210 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
| 211 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE |
| 212 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 213 | EOF |