SlideShare a Scribd company logo
1 of 8
[ -n "$BASH_VERSINFO" ] && [ $BASH_VERSINFO -ge 4 ] ||
{ echo 'This script requires bash4'; exit 1; }
name=bouncingballs
created=2013-02-19T12:39:48
modified=2013-05-11T14:51:10
version=1.0
author='Chris F.A. Johnson'
copyright="${modified%%-*} $author"
license='GNU General Public License V3.'
####################################################
#$ Variables ###
##################################################
bnum=5
topline=1
leftcol=1
rightmargin=0
bottommargin=0
char=O
boldchar=0
revchar=0
ulchar=0
silent=0
status=0
delayprompt='Enter delay in milliseconds: '
charprompt='Enter character'
CSI=$'e['
clearwindow=$'e[He[2J'
clearline=$'e[J'
hidecursor=$'e[?25l'
showcursor=$'e[?12le[?25h'
position_cursor=$'e[%d;%dH'
bold_on=$'e[1m'
bold_off=$'e[22m'
reverse_on=$'e[7m'
reverse_off=$'e[27m'
underline_on=$'e[4m'
underline_off=$'e[24m'
attr_norm=0
attr_bold=1
attr_rev=7
attr_blink=6
attr_uline=4
ON=1
OFF=0
small_increment=1
large_increment=10
readonly progname=${0##*/}
opts=(
b #@ Use bold character
c: #@ String character
d: #@ Delay in milliseconds
l: #@ Length of string
r #@ Reverse character
q #@ Do not print introduction
h #@ Help
v #@ Verbose
)
description="
${progname%-sh} $version (${modified/T/, })
Author: $author
Copyright $copyright
Released under $license; see COPYING for details
${progname%-sh} sends a string of characters flying across the
terminal (or console) window, bouncing off the sides.
OPTIONS:
b #@ Use bold character
c: #@ String character
d: #@ Delay in milliseconds
l: #@ Length of string
r #@ reverse character
q #@ Do not print introduction
h #@ help (-vh for longer help)
v #@ Show status line:
length of delay between iterations
length of string,
string character
print position
"
controls=" CONTROLS:
PageUp - Faster by 1 millisec
PageDown - Slower by 1 millisec
Home - Faster by 10 millisecs
End - Slower by 10 millisecs
The length of the string can be adjusted while running:
INS - Add one character to string
DEL - Remove one character from string
UP, DOWN, LEFT, RIGHT - Change direction
SPACE - Pause; press any key to continue
Character attributes:
b - Toggle bold
r - Toggle reverse
u - Toggle underline
[1-8] - Foreground colour
Other keys:
c - Change character to next character entered
C - Clear screen
d - Prompt for new delay value in milliseconds
h - Show control keys
q - Quit
s - Toggle display of status bar
"
press_any_key=$' e[7m Press any key to continue e[0mnn'
verbose=0
IFS=
optstr="${opts[@]}"
IFS=$' tn'
args=( )
####################################################
#$ Functions ###
##################################################
intro()
{
export LESS=eamgRXFj1i
printf "$clearwindow"
printf " %sn" "$description" | ${PAGER:-less}
read -sn1 -ep "$press_any_key"
printf "$clearwindow"
printf "nn %sn" "$controls" | ${PAGER:-less}
read -sn1 -ep $' e[7m Press any key to continue e[0mnn'
[ "$REPLY" = q ] && exit
}
status()
{
local fmt="Delay: %3dms (%.3fs) Length: %3d Character: %ce[K Row: %2d
Column: %3d"
(( status )) || { topline=1; return; }
printat 1 1 $'e[40;37;1m'
printf " $fmt" "$millisecs_delay" "$delay" "$bnum" "$char" "$y" "$x"
printf 'e[0m'
}
set_length()
{
[ $len -ge 0 ] && printat "${y[len]}" "${x[len]}" "$sp"
while [ ${#x[@]} -lt $bnum ]
do
[ $len -lt 0 ] && len=0
x+=( "${x[len]:-1}" )
y+=( "${y[len]:-1}" )
len=$(( ${#x[@]} - 1 )) ## index of last element in arrays
done
while [ ${#x[@]} -gt $bnum ]
do
if [ $len -ge 0 ]
then
unset x[len]
unset y[len]
fi
x=( "${x[@]}" )
y=( "${y[@]}" )
bnum=${#x[@]} ## number of elements in array
len=$(( $bnum - 1 )) ## index of last element in arrays
done
bnum=${#x[@]} ## number of elements in array
len=$(( $bnum - 1 )) ## index of last element in arrays
}
set_delay()
{
local arg=$1 n=9
while :
do
case $arg in
"") arg=20; break ;;
-*) arg=0; break ;; ## if less than zero, use 0
.*) arg=${arg#.} ;; ## remove leading period
[!0-9]*) arg=${arg#?} ;;
0?*) arg=${arg#0} ;; ## remove leading zero
0|[1-9]*) break ;; ## clean; continue
esac
done
millisecs_delay=${arg:-20}
if [ $millisecs_delay -le 0 ]
then
millisecs_delay=0
delay=.0001
else
printf -v delay "%d.%03d" "$(( millisecs_delay / 1000 ))" "$
(( millisecs_delay % 1000 ))"
fi
}
get_key() #@ Return ASCII represenation of keypress in variable
{ #@ USAGE: get_key varname
local CR=$'r' LF=$'n' keyvar=${1:-_KEY} tmout=.0001 TMOUT
local ctrl=( '' {A..Z} ) _n
TMOUT=$delay
IFS= read -sn1 -rd '' _key
case $_key in
"") ;;
"$LF") _key=LF ;;
"$ESC")
TMOUT=.01
while read -d '' -sn1 _k
do
_key=$_key$_k
case $_k in
[A-Za-z^~]) TMOUT=0; break ;;
esac
done
TMOUT=$tmout
_esc2key "$_key" _key
;;
*)
if [[ $_key < $ESC ]] ## CTRL-KEY pressed
then
printf -v _n %d "'$_key" ## Convert CTRL-KEY to its ASCII value
_key=^${ctrl[_n]} ## Show ^[X] where X is the letter key
fi
;;
esac
printf -v "$keyvar" %s "$_key"
}
_esc2key()
{
local _ESC2KEY=$1 var=${2:-_ESC2KEY} CSI=$'e[' ESC=$'e'
case $_ESC2KEY in
## Cursor keys
"${CSI}A" | "${CSI}OA" ) _ESC2KEY=UP ;;
"${CSI}B" | "${CSI}0B" ) _ESC2KEY=DOWN ;;
"${CSI}C" | "${CSI}OC" ) _ESC2KEY=RIGHT ;;
"${CSI}D" | "${CSI}OD" ) _ESC2KEY=LEFT ;;
## Function keys (unshifted)
"${CSI}11~" | "${CSI}["A | "${ESC}OP" ) _ESC2KEY=F1 ;;
"${CSI}12~" | "${CSI}["B | "${ESC}OQ" ) _ESC2KEY=F2 ;;
"${CSI}13~" | "${CSI}["C | "${ESC}OR" ) _ESC2KEY=F3 ;;
"${CSI}14~" | "${CSI}["D | "${ESC}OS" ) _ESC2KEY=F4 ;;
"${CSI}15~" | "${CSI}["E ) _ESC2KEY=F5 ;;
"${CSI}17~" | "${CSI}["F ) _ESC2KEY=F6 ;;
"${CSI}18~" ) _ESC2KEY=F7 ;;
"${CSI}19~" ) _ESC2KEY=F8 ;;
"${CSI}20~" ) _ESC2KEY=F9 ;;
"${CSI}21~" ) _ESC2KEY=F10 ;;
"${CSI}23~" ) _ESC2KEY=F11 ;; # SF1
"${CSI}24~" ) _ESC2KEY=F12 ;; # SF2
## Function keys (shifted)
"${CSI}11;2~" ) _ESC2KEY=SF1 ;;
"${CSI}25~" ) _ESC2KEY=SF3 ;;
"${CSI}26~" ) _ESC2KEY=SF4 ;;
"${CSI}28~" ) _ESC2KEY=SF5 ;;
"${CSI}29~" ) _ESC2KEY=SF6 ;;
"${CSI}31~" ) _ESC2KEY=SF7 ;;
"${CSI}32~" ) _ESC2KEY=SF8 ;;
"${CSI}33~" ) _ESC2KEY=SF9 ;;
"${CSI}34~" ) _ESC2KEY=SF10 ;;
## Insert, Delete, Home, End, Page Up, Page Down
"${CSI}2~" ) _ESC2KEY=INS ;;
"${CSI}2^" ) _ESC2KEY=^INS ;;
"${CSI}3~" ) _ESC2KEY=DEL ;;
"${CSI}"[17]~ | "${CSI}H" ) _ESC2KEY=HOME ;;
"${CSI}"[28]~ | "${CSI}F" ) _ESC2KEY=END ;;
"${CSI}8^" ) _ESC2KEY=^END ;;
"${CSI}5~" ) _ESC2KEY=PGUP ;;
"${CSI}5^" ) _ESC2KEY=^PGUP ;;
"${CSI}6~" ) _ESC2KEY=PGDN ;;
"${CSI}6^" ) _ESC2KEY=^PGDN ;;
"${CSI}3^" ) _ESC2KEY=^DEL ;;
"${CSI}7^" ) _ESC2KEY=^HOME ;;
"${CSI}3$" ) _ESC2KEY=S-DEL ;;
"${CSI}7$" ) _ESC2KEY=S-HOME ;;
"$ESC" ) _ESC2KEY=ESC ;;
## Everything else; add other keys before this line
*) _ESC2KEY=UNKNOWN ;;
esac
printf -v "$var" "%s" "$_ESC2KEY"
}
shove() #@ Add element to beginning of array and remove last element
{ #@ USAGE: shove arrayname val
local arrayname=${1:?} val=$2 max=$3 array n
## Copy the array, $arrayname, to local array
eval "array=( "${$arrayname[@]}" )"
n=${#array[@]}
## Add $val to beginning of array
array=( "$val" "${array[@]}" )
## Remove last element of array
unset array[n]
## Copy array back to $arrayname
eval "$arrayname=( "${array[@]}" )"
}
printat() #@ Move cursor to row/col on screen; print any remaining args
{ #@ USAGE: printat row col [arg ...]
local cursorto='e[%d;%dH'
printf "$cursorto" ${1:-1} ${2:-1}
if [ $# -gt 2 ]
then
shift 2
printf "%s" "$*"
fi
}
die() #@ Print optional error message and exit with $result
{ #@ die errnum [message]
result=$1
shift
msg=$*
[ -n "$*" ] && printf "%sn" "$msg" >&2
exit "$result"
}
usage()
{
printf 'USAGE: %s %s %sn' "$progname" ["$optstr"] "${args[*]}"
}
cleanup()
{
printf "$showcursor$na$clearwindow"
stty echo
while read -t 0; do read -sn1; done
tput rmcup
}
####################################################
#$ Parse options ###
##################################################
while getopts "$optstr" opt
do
case $opt in
b) boldchar=$ON ;;
c) char=$OPTARG ;;
d) millisecs_delay=$OPTARG ;;
l) bnum=$OPTARG ;;
q) silent=$ON ;;
h) (( verbose )) && intro || { usage; exit; } ;;
v) verbose=$(( verbose + 1 )) ;;
esac
done
shift "$(( $OPTIND - 1 ))"
####################################################
#$ Main program ###
##################################################
trap cleanup EXIT
tput smcup
(( silent )) || intro
status=$verbose
(( status )) && topline=2
set_delay "$millisecs_delay"
echo $'e[?25l' ## "$delay"; sleep 3
stty -echo
if [ -z "$COLUMNS" ]; then ## Set COLUMNS and LINES
termsize=( $(stty size) )
LINES=${termsize[0]}
COLUMNS=${termsize[1]}
fi
shopt -s SIGWINCH
rightcol=$(( COLUMNS - ${rightmargin:-0} ))
bottomline=$(( LINES - ${bottommargin:-0} ))
shopt -s checkwinsize ## adjust COLUMNS and LINES if window resized
x=( $topline $topline $topline $topline $topline $topline ) ## adjust number of
elements to taste
y=( $leftcol $leftcol $leftcol $leftcol $leftcol $leftcol ) ## adjust number of
elements to taste
len=$(( ${#x[@]} - 1 )) ## index of last element in arrays
xdir=+ ## direction of horizontal movement
ydir=- ## direction of vertical movement
printf "$clearwindow" ## clear screen
exec 2>$HOME/bb.log
#set -x
while :
do
set_length "$bnum"
status
printat "$y" "$x"
(( boldchar )) && printf "$bold_on" || printf "$bold_off"
(( revchar )) && printf "$reverse_on" || printf "$reverse_off"
(( ulchar )) && printf "$underline_on" || printf "$underline_off"
printf "$colour"
printf %c "$char"
printat "${y[len]}" "${x[len]}" $'e[0m '
[ $x -le ${leftcol:-1} ] && xdir=+
[ $y -ge ${bottomline:-$LINES} ] && ydir=-
[ $x -ge ${rightcol:-$COLUMNS} ] && xdir=-
[ $y -le ${topline:-1} ] && ydir=+
shove x "$(( x $xdir 1 ))"
shove y "$(( y $ydir 1 ))"
TMOUT=$delay
get_key k
case $k in
q) break;;
[1-8]) colour=${CSI}3${k}m ;;
## Increase/decrease speed
PGUP) (( millisecs_delay -= small_increment )) ;;
PGDN) (( millisecs_delay += small_increment )) ;;
HOME) (( millisecs_delay -= large_increment )) ;;
END) (( millisecs_delay += large_increment )) ;;
## Change length of string
INS) (( bnum++ ))
set_length
;;
DEL) (( bnum-- ))
printat "${y[len]}" "${x[len]}" ' '
set_length
;;
## Change direction
UP) ydir=- ;;
DOWN) ydir=+ ;;
LEFT) xdir=- ;;
RIGHT) xdir=+ ;;
## Character attributes: bold, reverse and underline
b) (( boldchar = boldchar==ON?OFF:ON )) ;;
r) (( revchar = revchar==ON?OFF:ON )) ;;
u) (( ulchar = ulchar==ON?OFF:ON )) ;;
c) printat "$topline" 2 $'e[0m'"$charprompt"
TMOUT=0 read -sn1 char
printf 'r%s ' "${charprompt//?/ }"
;;
C) printf %s "$clearwindow" ;;
d) printat "$topline" 2
stty echo
TMOUT=0 read -ep "$delayprompt" millisecs_delay
printf 'e[A%s ' "${delayprompt//?/ }"
stty -echo
;;
h) printf %s "$clearwindow"
printat 3 1 "$controls"
TMOUT=0 read -sn1
printf %s "$clearwindow"
;;
' ') TMOUT=0 read -sn1 ;;
s) if (( status ))
then
status=0
topline=1
printf 'e[He[K'
else
status=1
topline=2
fi
;;
$'e') printf 'a' ;;
?*) printat 1 1 "$k " ;;
*) ;;
esac
set_delay "$millisecs_delay"
# read -sn1 -t "$delay" && break
done
echo $'e[?12le[?25h'
stty echo

More Related Content

What's hot

What's hot (19)

Perspec sys tokenization paper_a4
Perspec sys tokenization paper_a4Perspec sys tokenization paper_a4
Perspec sys tokenization paper_a4
 
Symfony2 - extending the console component
Symfony2 - extending the console componentSymfony2 - extending the console component
Symfony2 - extending the console component
 
Nop2
Nop2Nop2
Nop2
 
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
WordPress Security: Be a Superhero - WordCamp Raleigh - May 2011
 
DOS
DOSDOS
DOS
 
Session8
Session8Session8
Session8
 
Extbase and Beyond
Extbase and BeyondExtbase and Beyond
Extbase and Beyond
 
London XQuery Meetup: Querying the World (Web Scraping)
London XQuery Meetup: Querying the World (Web Scraping)London XQuery Meetup: Querying the World (Web Scraping)
London XQuery Meetup: Querying the World (Web Scraping)
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smart
 
Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
distill
distilldistill
distill
 
Writing Maintainable Perl
Writing Maintainable PerlWriting Maintainable Perl
Writing Maintainable Perl
 
March 2012-Marketing Roundtable- Dee Davey
March 2012-Marketing Roundtable- Dee DaveyMarch 2012-Marketing Roundtable- Dee Davey
March 2012-Marketing Roundtable- Dee Davey
 
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
PHP Tips & Tricks
PHP Tips & TricksPHP Tips & Tricks
PHP Tips & Tricks
 
"Internationalisation with PHP and Intl" source code
"Internationalisation with PHP and Intl" source code"Internationalisation with PHP and Intl" source code
"Internationalisation with PHP and Intl" source code
 

Viewers also liked

Analysis of the Performance of Sea Level Stations at Haiti
Analysis of the Performance of Sea Level Stations at HaitiAnalysis of the Performance of Sea Level Stations at Haiti
Analysis of the Performance of Sea Level Stations at HaitiKaruska Matos-Horta
 
Mkscript sh
Mkscript shMkscript sh
Mkscript shBen Pope
 
Logrotate sh
Logrotate shLogrotate sh
Logrotate shBen Pope
 
Getfilestruct zbksh
Getfilestruct zbkshGetfilestruct zbksh
Getfilestruct zbkshBen Pope
 
Presentatie installatie werk_jvd_20170124
Presentatie installatie werk_jvd_20170124Presentatie installatie werk_jvd_20170124
Presentatie installatie werk_jvd_20170124Johan van Dijk
 
The Record_2017 issue 1
The Record_2017 issue 1The Record_2017 issue 1
The Record_2017 issue 1Billy Wong
 
An a z index of the bash commands
An a z index of the bash commandsAn a z index of the bash commands
An a z index of the bash commandsBen Pope
 
Applecmdlista zs
Applecmdlista zsApplecmdlista zs
Applecmdlista zsBen Pope
 
Xz file-format-1.0.4
Xz file-format-1.0.4Xz file-format-1.0.4
Xz file-format-1.0.4Ben Pope
 
Compound var
Compound varCompound var
Compound varBen Pope
 

Viewers also liked (19)

Analysis of the Performance of Sea Level Stations at Haiti
Analysis of the Performance of Sea Level Stations at HaitiAnalysis of the Performance of Sea Level Stations at Haiti
Analysis of the Performance of Sea Level Stations at Haiti
 
Mkscript sh
Mkscript shMkscript sh
Mkscript sh
 
Firewall
FirewallFirewall
Firewall
 
Logrotate sh
Logrotate shLogrotate sh
Logrotate sh
 
Getfilestruct zbksh
Getfilestruct zbkshGetfilestruct zbksh
Getfilestruct zbksh
 
Presentación1
Presentación1Presentación1
Presentación1
 
Wendy y suuu
Wendy y suuuWendy y suuu
Wendy y suuu
 
Gbi 1
Gbi 1Gbi 1
Gbi 1
 
Presentatie installatie werk_jvd_20170124
Presentatie installatie werk_jvd_20170124Presentatie installatie werk_jvd_20170124
Presentatie installatie werk_jvd_20170124
 
07
0707
07
 
Academic
AcademicAcademic
Academic
 
The Record_2017 issue 1
The Record_2017 issue 1The Record_2017 issue 1
The Record_2017 issue 1
 
Slowinski_Portfolio
Slowinski_PortfolioSlowinski_Portfolio
Slowinski_Portfolio
 
Diplom
DiplomDiplom
Diplom
 
An a z index of the bash commands
An a z index of the bash commandsAn a z index of the bash commands
An a z index of the bash commands
 
Applecmdlista zs
Applecmdlista zsApplecmdlista zs
Applecmdlista zs
 
Stefanie Lopez Angel - PPP Final
Stefanie Lopez Angel - PPP FinalStefanie Lopez Angel - PPP Final
Stefanie Lopez Angel - PPP Final
 
Xz file-format-1.0.4
Xz file-format-1.0.4Xz file-format-1.0.4
Xz file-format-1.0.4
 
Compound var
Compound varCompound var
Compound var
 

Similar to Bouncingballs sh

Creating a compiler in Perl 6
Creating a compiler in Perl 6Creating a compiler in Perl 6
Creating a compiler in Perl 6Andrew Shitov
 
Oneal perl-code-to-extract-from-voyager
Oneal perl-code-to-extract-from-voyagerOneal perl-code-to-extract-from-voyager
Oneal perl-code-to-extract-from-voyagerENUG
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
32 shell-programming
32 shell-programming32 shell-programming
32 shell-programmingkayalkarnan
 
Perl使いの国のRubyist
Perl使いの国のRubyistPerl使いの国のRubyist
Perl使いの国のRubyistTakafumi ONAKA
 
Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)James Titcumb
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2ady36
 
Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)
Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)
Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)James Titcumb
 
Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)James Titcumb
 
Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)James Titcumb
 
Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)James Titcumb
 

Similar to Bouncingballs sh (20)

Creating a compiler in Perl 6
Creating a compiler in Perl 6Creating a compiler in Perl 6
Creating a compiler in Perl 6
 
Barcelona.pm Curs1211 sess01
Barcelona.pm Curs1211 sess01Barcelona.pm Curs1211 sess01
Barcelona.pm Curs1211 sess01
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
Php functions
Php functionsPhp functions
Php functions
 
Dades i operadors
Dades i operadorsDades i operadors
Dades i operadors
 
Oneal perl-code-to-extract-from-voyager
Oneal perl-code-to-extract-from-voyagerOneal perl-code-to-extract-from-voyager
Oneal perl-code-to-extract-from-voyager
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
32 shell-programming
32 shell-programming32 shell-programming
32 shell-programming
 
perl-pocket
perl-pocketperl-pocket
perl-pocket
 
perl-pocket
perl-pocketperl-pocket
perl-pocket
 
perl-pocket
perl-pocketperl-pocket
perl-pocket
 
perl-pocket
perl-pocketperl-pocket
perl-pocket
 
Perl使いの国のRubyist
Perl使いの国のRubyistPerl使いの国のRubyist
Perl使いの国のRubyist
 
Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2
 
Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)
Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)
Climbing the Abstract Syntax Tree (CodeiD PHP Odessa 2017)
 
Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)
 
Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)
 
Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)
 

More from Ben Pope

An a z index of windows power shell commandss
An a z index of windows power shell commandssAn a z index of windows power shell commandss
An a z index of windows power shell commandssBen Pope
 
Programming collaborative-ref
Programming collaborative-refProgramming collaborative-ref
Programming collaborative-refBen Pope
 
Popstat1 sh
Popstat1 shPopstat1 sh
Popstat1 shBen Pope
 
Pop3stat sh
Pop3stat shPop3stat sh
Pop3stat shBen Pope
 
Menu func-sh
Menu func-shMenu func-sh
Menu func-shBen Pope
 
Menu func-sh(1)
Menu func-sh(1)Menu func-sh(1)
Menu func-sh(1)Ben Pope
 

More from Ben Pope (10)

An a z index of windows power shell commandss
An a z index of windows power shell commandssAn a z index of windows power shell commandss
An a z index of windows power shell commandss
 
Programming collaborative-ref
Programming collaborative-refProgramming collaborative-ref
Programming collaborative-ref
 
Popstat1 sh
Popstat1 shPopstat1 sh
Popstat1 sh
 
Pop3stat sh
Pop3stat shPop3stat sh
Pop3stat sh
 
Phadd sh
Phadd shPhadd sh
Phadd sh
 
Phdel sh
Phdel shPhdel sh
Phdel sh
 
Menu func-sh
Menu func-shMenu func-sh
Menu func-sh
 
Menu func-sh(1)
Menu func-sh(1)Menu func-sh(1)
Menu func-sh(1)
 
Luhn sh
Luhn shLuhn sh
Luhn sh
 
Cpsh sh
Cpsh shCpsh sh
Cpsh sh
 

Recently uploaded

Islamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad Escorts
Islamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad EscortsIslamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad Escorts
Islamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad Escortswdefrd
 
Akola Call Girls #9907093804 Contact Number Escorts Service Akola
Akola Call Girls #9907093804 Contact Number Escorts Service AkolaAkola Call Girls #9907093804 Contact Number Escorts Service Akola
Akola Call Girls #9907093804 Contact Number Escorts Service Akolasrsj9000
 
Olivia Cox. intertextual references.pptx
Olivia Cox. intertextual references.pptxOlivia Cox. intertextual references.pptx
Olivia Cox. intertextual references.pptxLauraFagan6
 
FULL ENJOY - 9953040155 Call Girls in Noida | Delhi
FULL ENJOY - 9953040155 Call Girls in Noida | DelhiFULL ENJOY - 9953040155 Call Girls in Noida | Delhi
FULL ENJOY - 9953040155 Call Girls in Noida | DelhiMalviyaNagarCallGirl
 
Call Girl Service in Karachi +923081633338 Karachi Call Girls
Call Girl Service in Karachi +923081633338 Karachi Call GirlsCall Girl Service in Karachi +923081633338 Karachi Call Girls
Call Girl Service in Karachi +923081633338 Karachi Call GirlsAyesha Khan
 
Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...
Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...
Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...anilsa9823
 
Jagat Puri Call Girls : ☎ 8527673949, Low rate Call Girls
Jagat Puri Call Girls : ☎ 8527673949, Low rate Call GirlsJagat Puri Call Girls : ☎ 8527673949, Low rate Call Girls
Jagat Puri Call Girls : ☎ 8527673949, Low rate Call Girlsashishs7044
 
Russian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts Service
Russian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts ServiceRussian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts Service
Russian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts Servicedoor45step
 
Retail Store Scavanger Hunt - Foundation College Park
Retail Store Scavanger Hunt - Foundation College ParkRetail Store Scavanger Hunt - Foundation College Park
Retail Store Scavanger Hunt - Foundation College Parkjosebenzaquen
 
Strip Zagor Extra 322 - Dva ortaka.pdf
Strip   Zagor Extra 322 - Dva ortaka.pdfStrip   Zagor Extra 322 - Dva ortaka.pdf
Strip Zagor Extra 322 - Dva ortaka.pdfStripovizijacom
 
Bridge Fight Board by Daniel Johnson dtjohnsonart.com
Bridge Fight Board by Daniel Johnson dtjohnsonart.comBridge Fight Board by Daniel Johnson dtjohnsonart.com
Bridge Fight Board by Daniel Johnson dtjohnsonart.comthephillipta
 
FULL ENJOY - 9953040155 Call Girls in Uttam Nagar | Delhi
FULL ENJOY - 9953040155 Call Girls in Uttam Nagar | DelhiFULL ENJOY - 9953040155 Call Girls in Uttam Nagar | Delhi
FULL ENJOY - 9953040155 Call Girls in Uttam Nagar | DelhiMalviyaNagarCallGirl
 
Delhi Room Call Girls : ☎ 8527673949, Low rate Call girl service
Delhi Room Call Girls : ☎ 8527673949, Low rate Call girl serviceDelhi Room Call Girls : ☎ 8527673949, Low rate Call girl service
Delhi Room Call Girls : ☎ 8527673949, Low rate Call girl serviceashishs7044
 
SHIVNA SAHITYIKI APRIL JUNE 2024 Magazine
SHIVNA SAHITYIKI APRIL JUNE 2024 MagazineSHIVNA SAHITYIKI APRIL JUNE 2024 Magazine
SHIVNA SAHITYIKI APRIL JUNE 2024 MagazineShivna Prakashan
 
How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?
How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?
How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?kexey39068
 
Call Girls in Islamabad | 03274100048 | Call Girl Service
Call Girls in Islamabad | 03274100048 | Call Girl ServiceCall Girls in Islamabad | 03274100048 | Call Girl Service
Call Girls in Islamabad | 03274100048 | Call Girl ServiceAyesha Khan
 
FULL ENJOY - 9953040155 Call Girls in Mahipalpur | Delhi
FULL ENJOY - 9953040155 Call Girls in Mahipalpur | DelhiFULL ENJOY - 9953040155 Call Girls in Mahipalpur | Delhi
FULL ENJOY - 9953040155 Call Girls in Mahipalpur | DelhiMalviyaNagarCallGirl
 
Zagor VČ OP 055 - Oluja nad Haitijem.pdf
Zagor VČ OP 055 - Oluja nad Haitijem.pdfZagor VČ OP 055 - Oluja nad Haitijem.pdf
Zagor VČ OP 055 - Oluja nad Haitijem.pdfStripovizijacom
 
FULL ENJOY - 9953040155 Call Girls in Dwarka Mor | Delhi
FULL ENJOY - 9953040155 Call Girls in Dwarka Mor | DelhiFULL ENJOY - 9953040155 Call Girls in Dwarka Mor | Delhi
FULL ENJOY - 9953040155 Call Girls in Dwarka Mor | DelhiMalviyaNagarCallGirl
 

Recently uploaded (20)

Islamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad Escorts
Islamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad EscortsIslamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad Escorts
Islamabad Call Girls # 03091665556 # Call Girls in Islamabad | Islamabad Escorts
 
Akola Call Girls #9907093804 Contact Number Escorts Service Akola
Akola Call Girls #9907093804 Contact Number Escorts Service AkolaAkola Call Girls #9907093804 Contact Number Escorts Service Akola
Akola Call Girls #9907093804 Contact Number Escorts Service Akola
 
Olivia Cox. intertextual references.pptx
Olivia Cox. intertextual references.pptxOlivia Cox. intertextual references.pptx
Olivia Cox. intertextual references.pptx
 
FULL ENJOY - 9953040155 Call Girls in Noida | Delhi
FULL ENJOY - 9953040155 Call Girls in Noida | DelhiFULL ENJOY - 9953040155 Call Girls in Noida | Delhi
FULL ENJOY - 9953040155 Call Girls in Noida | Delhi
 
Call Girl Service in Karachi +923081633338 Karachi Call Girls
Call Girl Service in Karachi +923081633338 Karachi Call GirlsCall Girl Service in Karachi +923081633338 Karachi Call Girls
Call Girl Service in Karachi +923081633338 Karachi Call Girls
 
Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...
Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...
Lucknow 💋 Virgin Call Girls Lucknow | Book 8923113531 Extreme Naughty Call Gi...
 
Jagat Puri Call Girls : ☎ 8527673949, Low rate Call Girls
Jagat Puri Call Girls : ☎ 8527673949, Low rate Call GirlsJagat Puri Call Girls : ☎ 8527673949, Low rate Call Girls
Jagat Puri Call Girls : ☎ 8527673949, Low rate Call Girls
 
Russian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts Service
Russian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts ServiceRussian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts Service
Russian⚡ Call Girls In Sector 104 Noida✨8375860717⚡Escorts Service
 
Retail Store Scavanger Hunt - Foundation College Park
Retail Store Scavanger Hunt - Foundation College ParkRetail Store Scavanger Hunt - Foundation College Park
Retail Store Scavanger Hunt - Foundation College Park
 
Strip Zagor Extra 322 - Dva ortaka.pdf
Strip   Zagor Extra 322 - Dva ortaka.pdfStrip   Zagor Extra 322 - Dva ortaka.pdf
Strip Zagor Extra 322 - Dva ortaka.pdf
 
Bridge Fight Board by Daniel Johnson dtjohnsonart.com
Bridge Fight Board by Daniel Johnson dtjohnsonart.comBridge Fight Board by Daniel Johnson dtjohnsonart.com
Bridge Fight Board by Daniel Johnson dtjohnsonart.com
 
FULL ENJOY - 9953040155 Call Girls in Uttam Nagar | Delhi
FULL ENJOY - 9953040155 Call Girls in Uttam Nagar | DelhiFULL ENJOY - 9953040155 Call Girls in Uttam Nagar | Delhi
FULL ENJOY - 9953040155 Call Girls in Uttam Nagar | Delhi
 
Delhi Room Call Girls : ☎ 8527673949, Low rate Call girl service
Delhi Room Call Girls : ☎ 8527673949, Low rate Call girl serviceDelhi Room Call Girls : ☎ 8527673949, Low rate Call girl service
Delhi Room Call Girls : ☎ 8527673949, Low rate Call girl service
 
SHIVNA SAHITYIKI APRIL JUNE 2024 Magazine
SHIVNA SAHITYIKI APRIL JUNE 2024 MagazineSHIVNA SAHITYIKI APRIL JUNE 2024 Magazine
SHIVNA SAHITYIKI APRIL JUNE 2024 Magazine
 
How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?
How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?
How Can You Get Dubai Call Girls +971564860409 Call Girls Dubai?
 
Call Girls in Islamabad | 03274100048 | Call Girl Service
Call Girls in Islamabad | 03274100048 | Call Girl ServiceCall Girls in Islamabad | 03274100048 | Call Girl Service
Call Girls in Islamabad | 03274100048 | Call Girl Service
 
Dxb Call Girls # +971529501107 # Call Girls In Dxb Dubai || (UAE)
Dxb Call Girls # +971529501107 # Call Girls In Dxb Dubai || (UAE)Dxb Call Girls # +971529501107 # Call Girls In Dxb Dubai || (UAE)
Dxb Call Girls # +971529501107 # Call Girls In Dxb Dubai || (UAE)
 
FULL ENJOY - 9953040155 Call Girls in Mahipalpur | Delhi
FULL ENJOY - 9953040155 Call Girls in Mahipalpur | DelhiFULL ENJOY - 9953040155 Call Girls in Mahipalpur | Delhi
FULL ENJOY - 9953040155 Call Girls in Mahipalpur | Delhi
 
Zagor VČ OP 055 - Oluja nad Haitijem.pdf
Zagor VČ OP 055 - Oluja nad Haitijem.pdfZagor VČ OP 055 - Oluja nad Haitijem.pdf
Zagor VČ OP 055 - Oluja nad Haitijem.pdf
 
FULL ENJOY - 9953040155 Call Girls in Dwarka Mor | Delhi
FULL ENJOY - 9953040155 Call Girls in Dwarka Mor | DelhiFULL ENJOY - 9953040155 Call Girls in Dwarka Mor | Delhi
FULL ENJOY - 9953040155 Call Girls in Dwarka Mor | Delhi
 

Bouncingballs sh

  • 1. [ -n "$BASH_VERSINFO" ] && [ $BASH_VERSINFO -ge 4 ] || { echo 'This script requires bash4'; exit 1; } name=bouncingballs created=2013-02-19T12:39:48 modified=2013-05-11T14:51:10 version=1.0 author='Chris F.A. Johnson' copyright="${modified%%-*} $author" license='GNU General Public License V3.' #################################################### #$ Variables ### ################################################## bnum=5 topline=1 leftcol=1 rightmargin=0 bottommargin=0 char=O boldchar=0 revchar=0 ulchar=0 silent=0 status=0 delayprompt='Enter delay in milliseconds: ' charprompt='Enter character' CSI=$'e[' clearwindow=$'e[He[2J' clearline=$'e[J' hidecursor=$'e[?25l' showcursor=$'e[?12le[?25h' position_cursor=$'e[%d;%dH' bold_on=$'e[1m' bold_off=$'e[22m' reverse_on=$'e[7m' reverse_off=$'e[27m' underline_on=$'e[4m' underline_off=$'e[24m' attr_norm=0 attr_bold=1 attr_rev=7 attr_blink=6 attr_uline=4 ON=1 OFF=0 small_increment=1 large_increment=10 readonly progname=${0##*/} opts=( b #@ Use bold character c: #@ String character d: #@ Delay in milliseconds l: #@ Length of string
  • 2. r #@ Reverse character q #@ Do not print introduction h #@ Help v #@ Verbose ) description=" ${progname%-sh} $version (${modified/T/, }) Author: $author Copyright $copyright Released under $license; see COPYING for details ${progname%-sh} sends a string of characters flying across the terminal (or console) window, bouncing off the sides. OPTIONS: b #@ Use bold character c: #@ String character d: #@ Delay in milliseconds l: #@ Length of string r #@ reverse character q #@ Do not print introduction h #@ help (-vh for longer help) v #@ Show status line: length of delay between iterations length of string, string character print position " controls=" CONTROLS: PageUp - Faster by 1 millisec PageDown - Slower by 1 millisec Home - Faster by 10 millisecs End - Slower by 10 millisecs The length of the string can be adjusted while running: INS - Add one character to string DEL - Remove one character from string UP, DOWN, LEFT, RIGHT - Change direction SPACE - Pause; press any key to continue Character attributes: b - Toggle bold r - Toggle reverse u - Toggle underline [1-8] - Foreground colour Other keys: c - Change character to next character entered C - Clear screen d - Prompt for new delay value in milliseconds h - Show control keys q - Quit s - Toggle display of status bar
  • 3. " press_any_key=$' e[7m Press any key to continue e[0mnn' verbose=0 IFS= optstr="${opts[@]}" IFS=$' tn' args=( ) #################################################### #$ Functions ### ################################################## intro() { export LESS=eamgRXFj1i printf "$clearwindow" printf " %sn" "$description" | ${PAGER:-less} read -sn1 -ep "$press_any_key" printf "$clearwindow" printf "nn %sn" "$controls" | ${PAGER:-less} read -sn1 -ep $' e[7m Press any key to continue e[0mnn' [ "$REPLY" = q ] && exit } status() { local fmt="Delay: %3dms (%.3fs) Length: %3d Character: %ce[K Row: %2d Column: %3d" (( status )) || { topline=1; return; } printat 1 1 $'e[40;37;1m' printf " $fmt" "$millisecs_delay" "$delay" "$bnum" "$char" "$y" "$x" printf 'e[0m' } set_length() { [ $len -ge 0 ] && printat "${y[len]}" "${x[len]}" "$sp" while [ ${#x[@]} -lt $bnum ] do [ $len -lt 0 ] && len=0 x+=( "${x[len]:-1}" ) y+=( "${y[len]:-1}" ) len=$(( ${#x[@]} - 1 )) ## index of last element in arrays done while [ ${#x[@]} -gt $bnum ] do if [ $len -ge 0 ] then unset x[len] unset y[len] fi x=( "${x[@]}" ) y=( "${y[@]}" ) bnum=${#x[@]} ## number of elements in array len=$(( $bnum - 1 )) ## index of last element in arrays done bnum=${#x[@]} ## number of elements in array len=$(( $bnum - 1 )) ## index of last element in arrays } set_delay()
  • 4. { local arg=$1 n=9 while : do case $arg in "") arg=20; break ;; -*) arg=0; break ;; ## if less than zero, use 0 .*) arg=${arg#.} ;; ## remove leading period [!0-9]*) arg=${arg#?} ;; 0?*) arg=${arg#0} ;; ## remove leading zero 0|[1-9]*) break ;; ## clean; continue esac done millisecs_delay=${arg:-20} if [ $millisecs_delay -le 0 ] then millisecs_delay=0 delay=.0001 else printf -v delay "%d.%03d" "$(( millisecs_delay / 1000 ))" "$ (( millisecs_delay % 1000 ))" fi } get_key() #@ Return ASCII represenation of keypress in variable { #@ USAGE: get_key varname local CR=$'r' LF=$'n' keyvar=${1:-_KEY} tmout=.0001 TMOUT local ctrl=( '' {A..Z} ) _n TMOUT=$delay IFS= read -sn1 -rd '' _key case $_key in "") ;; "$LF") _key=LF ;; "$ESC") TMOUT=.01 while read -d '' -sn1 _k do _key=$_key$_k case $_k in [A-Za-z^~]) TMOUT=0; break ;; esac done TMOUT=$tmout _esc2key "$_key" _key ;; *) if [[ $_key < $ESC ]] ## CTRL-KEY pressed then printf -v _n %d "'$_key" ## Convert CTRL-KEY to its ASCII value _key=^${ctrl[_n]} ## Show ^[X] where X is the letter key fi ;; esac printf -v "$keyvar" %s "$_key" } _esc2key() { local _ESC2KEY=$1 var=${2:-_ESC2KEY} CSI=$'e[' ESC=$'e' case $_ESC2KEY in ## Cursor keys "${CSI}A" | "${CSI}OA" ) _ESC2KEY=UP ;;
  • 5. "${CSI}B" | "${CSI}0B" ) _ESC2KEY=DOWN ;; "${CSI}C" | "${CSI}OC" ) _ESC2KEY=RIGHT ;; "${CSI}D" | "${CSI}OD" ) _ESC2KEY=LEFT ;; ## Function keys (unshifted) "${CSI}11~" | "${CSI}["A | "${ESC}OP" ) _ESC2KEY=F1 ;; "${CSI}12~" | "${CSI}["B | "${ESC}OQ" ) _ESC2KEY=F2 ;; "${CSI}13~" | "${CSI}["C | "${ESC}OR" ) _ESC2KEY=F3 ;; "${CSI}14~" | "${CSI}["D | "${ESC}OS" ) _ESC2KEY=F4 ;; "${CSI}15~" | "${CSI}["E ) _ESC2KEY=F5 ;; "${CSI}17~" | "${CSI}["F ) _ESC2KEY=F6 ;; "${CSI}18~" ) _ESC2KEY=F7 ;; "${CSI}19~" ) _ESC2KEY=F8 ;; "${CSI}20~" ) _ESC2KEY=F9 ;; "${CSI}21~" ) _ESC2KEY=F10 ;; "${CSI}23~" ) _ESC2KEY=F11 ;; # SF1 "${CSI}24~" ) _ESC2KEY=F12 ;; # SF2 ## Function keys (shifted) "${CSI}11;2~" ) _ESC2KEY=SF1 ;; "${CSI}25~" ) _ESC2KEY=SF3 ;; "${CSI}26~" ) _ESC2KEY=SF4 ;; "${CSI}28~" ) _ESC2KEY=SF5 ;; "${CSI}29~" ) _ESC2KEY=SF6 ;; "${CSI}31~" ) _ESC2KEY=SF7 ;; "${CSI}32~" ) _ESC2KEY=SF8 ;; "${CSI}33~" ) _ESC2KEY=SF9 ;; "${CSI}34~" ) _ESC2KEY=SF10 ;; ## Insert, Delete, Home, End, Page Up, Page Down "${CSI}2~" ) _ESC2KEY=INS ;; "${CSI}2^" ) _ESC2KEY=^INS ;; "${CSI}3~" ) _ESC2KEY=DEL ;; "${CSI}"[17]~ | "${CSI}H" ) _ESC2KEY=HOME ;; "${CSI}"[28]~ | "${CSI}F" ) _ESC2KEY=END ;; "${CSI}8^" ) _ESC2KEY=^END ;; "${CSI}5~" ) _ESC2KEY=PGUP ;; "${CSI}5^" ) _ESC2KEY=^PGUP ;; "${CSI}6~" ) _ESC2KEY=PGDN ;; "${CSI}6^" ) _ESC2KEY=^PGDN ;; "${CSI}3^" ) _ESC2KEY=^DEL ;; "${CSI}7^" ) _ESC2KEY=^HOME ;; "${CSI}3$" ) _ESC2KEY=S-DEL ;; "${CSI}7$" ) _ESC2KEY=S-HOME ;; "$ESC" ) _ESC2KEY=ESC ;; ## Everything else; add other keys before this line *) _ESC2KEY=UNKNOWN ;; esac printf -v "$var" "%s" "$_ESC2KEY" } shove() #@ Add element to beginning of array and remove last element { #@ USAGE: shove arrayname val local arrayname=${1:?} val=$2 max=$3 array n ## Copy the array, $arrayname, to local array eval "array=( "${$arrayname[@]}" )" n=${#array[@]} ## Add $val to beginning of array array=( "$val" "${array[@]}" ) ## Remove last element of array unset array[n] ## Copy array back to $arrayname
  • 6. eval "$arrayname=( "${array[@]}" )" } printat() #@ Move cursor to row/col on screen; print any remaining args { #@ USAGE: printat row col [arg ...] local cursorto='e[%d;%dH' printf "$cursorto" ${1:-1} ${2:-1} if [ $# -gt 2 ] then shift 2 printf "%s" "$*" fi } die() #@ Print optional error message and exit with $result { #@ die errnum [message] result=$1 shift msg=$* [ -n "$*" ] && printf "%sn" "$msg" >&2 exit "$result" } usage() { printf 'USAGE: %s %s %sn' "$progname" ["$optstr"] "${args[*]}" } cleanup() { printf "$showcursor$na$clearwindow" stty echo while read -t 0; do read -sn1; done tput rmcup } #################################################### #$ Parse options ### ################################################## while getopts "$optstr" opt do case $opt in b) boldchar=$ON ;; c) char=$OPTARG ;; d) millisecs_delay=$OPTARG ;; l) bnum=$OPTARG ;; q) silent=$ON ;; h) (( verbose )) && intro || { usage; exit; } ;; v) verbose=$(( verbose + 1 )) ;; esac done shift "$(( $OPTIND - 1 ))" #################################################### #$ Main program ### ################################################## trap cleanup EXIT tput smcup (( silent )) || intro status=$verbose (( status )) && topline=2
  • 7. set_delay "$millisecs_delay" echo $'e[?25l' ## "$delay"; sleep 3 stty -echo if [ -z "$COLUMNS" ]; then ## Set COLUMNS and LINES termsize=( $(stty size) ) LINES=${termsize[0]} COLUMNS=${termsize[1]} fi shopt -s SIGWINCH rightcol=$(( COLUMNS - ${rightmargin:-0} )) bottomline=$(( LINES - ${bottommargin:-0} )) shopt -s checkwinsize ## adjust COLUMNS and LINES if window resized x=( $topline $topline $topline $topline $topline $topline ) ## adjust number of elements to taste y=( $leftcol $leftcol $leftcol $leftcol $leftcol $leftcol ) ## adjust number of elements to taste len=$(( ${#x[@]} - 1 )) ## index of last element in arrays xdir=+ ## direction of horizontal movement ydir=- ## direction of vertical movement printf "$clearwindow" ## clear screen exec 2>$HOME/bb.log #set -x while : do set_length "$bnum" status printat "$y" "$x" (( boldchar )) && printf "$bold_on" || printf "$bold_off" (( revchar )) && printf "$reverse_on" || printf "$reverse_off" (( ulchar )) && printf "$underline_on" || printf "$underline_off" printf "$colour" printf %c "$char" printat "${y[len]}" "${x[len]}" $'e[0m ' [ $x -le ${leftcol:-1} ] && xdir=+ [ $y -ge ${bottomline:-$LINES} ] && ydir=- [ $x -ge ${rightcol:-$COLUMNS} ] && xdir=- [ $y -le ${topline:-1} ] && ydir=+ shove x "$(( x $xdir 1 ))" shove y "$(( y $ydir 1 ))" TMOUT=$delay get_key k case $k in q) break;; [1-8]) colour=${CSI}3${k}m ;; ## Increase/decrease speed PGUP) (( millisecs_delay -= small_increment )) ;; PGDN) (( millisecs_delay += small_increment )) ;; HOME) (( millisecs_delay -= large_increment )) ;; END) (( millisecs_delay += large_increment )) ;;
  • 8. ## Change length of string INS) (( bnum++ )) set_length ;; DEL) (( bnum-- )) printat "${y[len]}" "${x[len]}" ' ' set_length ;; ## Change direction UP) ydir=- ;; DOWN) ydir=+ ;; LEFT) xdir=- ;; RIGHT) xdir=+ ;; ## Character attributes: bold, reverse and underline b) (( boldchar = boldchar==ON?OFF:ON )) ;; r) (( revchar = revchar==ON?OFF:ON )) ;; u) (( ulchar = ulchar==ON?OFF:ON )) ;; c) printat "$topline" 2 $'e[0m'"$charprompt" TMOUT=0 read -sn1 char printf 'r%s ' "${charprompt//?/ }" ;; C) printf %s "$clearwindow" ;; d) printat "$topline" 2 stty echo TMOUT=0 read -ep "$delayprompt" millisecs_delay printf 'e[A%s ' "${delayprompt//?/ }" stty -echo ;; h) printf %s "$clearwindow" printat 3 1 "$controls" TMOUT=0 read -sn1 printf %s "$clearwindow" ;; ' ') TMOUT=0 read -sn1 ;; s) if (( status )) then status=0 topline=1 printf 'e[He[K' else status=1 topline=2 fi ;; $'e') printf 'a' ;; ?*) printat 1 1 "$k " ;; *) ;; esac set_delay "$millisecs_delay" # read -sn1 -t "$delay" && break done echo $'e[?12le[?25h' stty echo