235 lines
4.9 KiB
Bash
Executable file
235 lines
4.9 KiB
Bash
Executable file
#!/bin/sh
|
|
# clikan.sh -- CLI Kanban
|
|
ver='2019-12-11/HB9KNS'
|
|
|
|
conf="${CLIKANCONF:-$HOME/.clikanconf}"
|
|
defkanban="$HOME/clikanban.md"
|
|
editor="${CLIKANEDIT:-$VISUAL}"
|
|
editor="${editor:-$EDITOR}"
|
|
editor="${editor:-ed}"
|
|
|
|
tmpf=`mktemp -t clikanXXXXXX` || tmpf=${TMPDIR:-/tmp}/clikan$$`date +%S%M%d`
|
|
: >$tmpf
|
|
chmod 600 $tmpf
|
|
|
|
if test ! -f "$conf"
|
|
then cat <<EOT
|
|
no config found, generating default config file $conf
|
|
and default kanban file $defkanban
|
|
(this should happen only once at first use)
|
|
EOT
|
|
cat <<EOT >"$conf"
|
|
# configuration file for $0
|
|
# (autogenerated at `date`)
|
|
# file name can be defined by env.var CLIKANCONF
|
|
#
|
|
# prompt is displayed when waiting for command
|
|
prompt |<
|
|
# maxshow defines the maximum number of cards/lines to be displayed
|
|
maxshow 15
|
|
# kanban defines a kanban file, may be given several times
|
|
# kanban /some/path/to/jobkanban.txt
|
|
# kanban /another/path/to/privatekanban.md
|
|
kanban $defkanban
|
|
EOT
|
|
if test -f "$defkanban"
|
|
then cp "$defkanban" "$defkanban.bak"
|
|
echo found existing $defkanban,
|
|
echo saved as backup $defkanban.bak
|
|
fi
|
|
cat <<EOT >"$defkanban"
|
|
# my kanban file
|
|
|
|
* learn to use clikan
|
|
- improve clikan
|
|
+ install clikan
|
|
|
|
### titles work as comments
|
|
# might be a future card you don't yet want in waiting
|
|
EOT
|
|
fi
|
|
|
|
# get lines beginning with a value, and remove that column
|
|
# note SPC&TAB in patterns: make sure there is a SPC,
|
|
# and that the value is complete
|
|
getlines(){
|
|
sed -e 's/$/ /' | grep "^$1[ ]" | { while read _ values
|
|
# remove trailing added TAB
|
|
do echo "${values% }"
|
|
done
|
|
}
|
|
}
|
|
|
|
# display selection, and put selection list in tempfile,
|
|
# input through stdin, with lines prepended with index number, TAB and arg1
|
|
showselect(){
|
|
local i
|
|
i=1
|
|
: >$tmpf
|
|
while read l
|
|
do echo $i: $l
|
|
echo "$i $1$l" >>$tmpf
|
|
i=$(( $i+1 ))
|
|
done
|
|
}
|
|
|
|
# get input from selection (showselect must be called before)
|
|
getselect(){
|
|
if test "$1" != ""
|
|
then echo "choice? (default: $1)" >&2
|
|
else echo "choice?" >&2
|
|
fi
|
|
read i
|
|
if test "$i" = ""
|
|
then echo "$1"
|
|
else getlines $i <$tmpf
|
|
fi
|
|
}
|
|
|
|
kbs="`getlines kanban <"$conf"`"
|
|
currkan="`echo "$kbs" | head -n 1`"
|
|
prompt=`getlines prompt <"$conf" | head -n 1`
|
|
maxshow=`getlines maxshow <"$conf" | head -n 1`
|
|
maxshow=${maxshow:-22}
|
|
#echo conf=$conf
|
|
#echo kbs=$kbs
|
|
#echo currkan=$currkan
|
|
|
|
showprompt(){
|
|
if test "$prompt" != ""
|
|
then printf '%s ' "$prompt"
|
|
fi
|
|
}
|
|
|
|
# display all 'something' cards
|
|
showall(){
|
|
local f t
|
|
case $1 in
|
|
d*) f='*' ;;
|
|
w*) f='-' ;;
|
|
a*) f='+' ;;
|
|
*) f='' ;;
|
|
esac
|
|
echo
|
|
echo " $1"
|
|
{ cat $kbs | getlines "$f"
|
|
if test "$f" = "*"
|
|
# for "doing", also display '- ...(MM-DD)...' calendar entries
|
|
then t=`date +%m-%d`
|
|
cat $kbs | grep "^[*+-] .*($t)" | sed -e 's/^. //'
|
|
fi
|
|
} | showselect "$f " | head -n $maxshow
|
|
}
|
|
|
|
# replace lines (in any kanban) containing some ed pattern
|
|
# arg.1=pattern, remainder=new line contents
|
|
repline(){
|
|
local patt newl
|
|
patt="$1"
|
|
shift
|
|
newl="$*"
|
|
for ff in $kbs
|
|
do cat <<EOC | ed "$ff" >/dev/null 2>&1
|
|
%g/$patt/c\\
|
|
$newl\\
|
|
.
|
|
w
|
|
q
|
|
EOC
|
|
done
|
|
}
|
|
|
|
showhelp(){ cat <<EOH
|
|
$0 : command line kanban
|
|
($ver)
|
|
configuration file: $conf
|
|
for help about commands, just hit RETURN
|
|
to show configuration, enter 'c'
|
|
EOH
|
|
read k
|
|
case $k in
|
|
c*) cat <<EOT
|
|
CLIKANCONF=$CLIKANCONF
|
|
configfile=$conf
|
|
editor=$editor
|
|
maxshow=$maxshow
|
|
configfile contents:
|
|
EOT
|
|
sed -e 's/^/ /' $conf
|
|
;;
|
|
*) cat <<EOH
|
|
command keys:
|
|
q: quit
|
|
d/w/a: show 'doing/waiting(todo)/archive(done)' cards
|
|
k: select target kanban for entry of new cards
|
|
n: add new card to target kanban, separated by whitespace
|
|
(e.g "n buy present!")
|
|
done N: archive card N as done
|
|
wait N: put card N back to waiting/todo state
|
|
do N: put card N into doing state
|
|
ec: directly edit config file -- DANGER!
|
|
ek: directly edit kanban file -- DANGER!
|
|
EOH
|
|
;;
|
|
esac
|
|
}
|
|
|
|
showall doing
|
|
showprompt
|
|
|
|
while read com coa1 coa2 coa3 coar
|
|
do case $com in
|
|
q*) break ;;
|
|
d) showall doing ;;
|
|
w) showall waiting/todo/backlog ;;
|
|
a) showall archived/done ;;
|
|
do|wait|done) if test "$coa1" = ""
|
|
then echo "card number?"
|
|
read coa1
|
|
fi
|
|
if test "$coa1" != ""
|
|
then coa1=`getlines $coa1 <$tmpf`
|
|
case $com in
|
|
done) coa2='+' ;;
|
|
wait) coa2='-' ;;
|
|
*) coa2='*' ;;
|
|
esac
|
|
coa3=`echo "$coa1" | sed -e "s/^./$coa2/"`
|
|
#echo coa1=$coa1
|
|
#echo coa2=$coa2
|
|
#echo coa3=$coa3
|
|
repline "$coa1" "$coa3"
|
|
fi
|
|
showall doing
|
|
;;
|
|
k) echo "$kbs" | showselect
|
|
currkan=`getselect $currkan`
|
|
showall doing
|
|
;;
|
|
n) newc=`echo "$coa1 $coa2 $coa3 $coar" | sed -e 's/ *$//'`
|
|
if test "$newc" = ""
|
|
then
|
|
echo enter new card for target $currkan :
|
|
read newc
|
|
else echo adding card for target $currkan
|
|
fi
|
|
if test "$newc" != ""
|
|
then echo '-' "$newc" >>$currkan
|
|
else echo no content found, nothing added
|
|
fi
|
|
showall doing
|
|
;;
|
|
ec) echo calling "$editor $conf" ...
|
|
"$editor" "$conf"
|
|
echo please quit and restart to reload config ;;
|
|
ek) echo calling "$editor $currkan" ...
|
|
"$editor" "$currkan"
|
|
echo welcome back ;;
|
|
*) showhelp
|
|
showall doing ;;
|
|
esac
|
|
showprompt
|
|
done
|
|
|
|
echo
|
|
rm -f $tmpf
|