clikan/clikan.sh

274 lines
6.1 KiB
Bash
Raw Normal View History

#!/bin/sh
# clikan.sh -- CLI Kanban
2020-05-11 22:31:08 +02:00
ver='2020-05-11/HB9KNS'
conf="${CLIKANCONF:-$HOME/.clikanconf}"
2017-06-21 08:15:29 +02:00
defkanban="$HOME/clikanban.md"
editor="${CLIKANEDIT:-$VISUAL}"
editor="${editor:-$EDITOR}"
editor="${editor:-ed}"
2019-12-12 13:21:26 +01:00
myshell='/bin/sh -c'
2020-05-11 22:31:08 +02:00
filtr='.'
2017-06-21 13:46:50 +02:00
tmpf=`mktemp -t clikanXXXXXX` || tmpf=${TMPDIR:-/tmp}/clikan$$`date +%S%M%d`
: >$tmpf
chmod 600 $tmpf
if test ! -f "$conf"
2017-06-21 08:15:29 +02:00
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"
2017-06-21 08:15:29 +02:00
# configuration file for $0
# (autogenerated at `date`)
# file name can be defined by env.var CLIKANCONF
#
# prompt is displayed when waiting for command
prompt |<
2017-06-21 17:30:09 +02:00
# maxshow defines the maximum number of cards/lines to be displayed
maxshow 15
2019-12-17 09:24:03 +01:00
# sortdir defines order of non-calendar kanban cards
# and can be one of up, down or none (default)
sortdir none
2017-06-21 08:15:29 +02:00
# 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
2017-06-21 08:36:38 +02:00
* learn to use clikan
- improve clikan
2017-06-21 08:15:29 +02:00
+ install clikan
2017-06-21 08:36:38 +02:00
### 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`
2017-06-21 17:30:09 +02:00
maxshow=`getlines maxshow <"$conf" | head -n 1`
maxshow=${maxshow:-22}
2019-12-17 09:24:03 +01:00
sortdir=`getlines sortdir <"$conf" | head -n 1`
sortdir=${sortdir:-none}
showprompt(){
if test "$prompt" != ""
then printf '%s ' "$prompt"
fi
}
2019-12-17 09:24:03 +01:00
# conditional sort
condsort(){
case $sortdir in
up) sort ;;
down) sort -r ;;
*) cat ;;
esac
}
# display all 'something' cards
showall(){
local f t ms
ms=$maxshow
case $1 in
d*) f='*' ;;
w*) f='-' ;;
# for archive/done, show a LOT of archived stuff
a*) f='+' ; ms=99999 ;;
*) f='' ;;
esac
echo
2020-01-09 14:08:18 +01:00
echo " $1 // `date`"
2020-05-11 22:31:08 +02:00
if test "$filtr" != "."
then echo " /$filtr/"
fi
2019-12-17 09:24:03 +01:00
if test "$f" = "*"
then t=`date +%m-%d`
2020-05-11 22:31:08 +02:00
# for "doing", sort filtered cards
grep -i "$filtr" $kbs | getlines "$f" | condsort
2019-12-17 09:24:03 +01:00
# and also display '- ...(MM-DD)...' calendar entries
cat $kbs | grep "^[*+-] .*($t)" | sed -e 's/^. //'
2020-05-11 22:31:08 +02:00
# for waiting and archive, filter but keep saved card order
else grep -i "$filtr" $kbs | getlines "$f"
2019-12-17 09:24:03 +01:00
# for all cases, select the cards and show the beginning of the list
fi | showselect "$f " | head -n $ms
}
# 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
2017-06-21 08:15:29 +02:00
($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
2017-06-21 17:30:09 +02:00
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
2019-12-11 12:39:32 +01:00
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
2020-01-03 15:08:06 +01:00
note: done/wait/do accept several arguments separated by white space
2020-05-11 22:31:08 +02:00
f F: filter cards for grep pattern F (empty='.')
ec: directly edit config file -- DANGER!
ek: directly edit kanban file -- DANGER!
2019-12-12 13:21:26 +01:00
!: execute arguments with "$myshell"
2019-12-17 15:25:44 +01:00
note: if the command does not match to any of the
internal $0 commands, and starts with a letter,
you can even omit the leading exclamation mark!
EOH
;;
esac
}
showall doing
showprompt
while read com coa1 coa2 coa3 coar
do case $com in
2020-04-23 09:11:26 +02:00
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
coar=`echo "$coa1 $coa2 $coa3 $coar" | sed -e 's/ *$/ /'`
while test "$coar" != ""
do
coa1=`getlines ${coar%% *} <$tmpf`
2019-12-18 14:32:10 +01:00
stamp=''
case $com in
2019-12-18 14:32:10 +01:00
done) coa2='+'
stamp=`date '+ // %y-%m-%d'`
;;
wait) coa2='-' ;;
*) coa2='*' ;;
esac
coa3=`echo "$coa1" | sed -e "s/^./$coa2/"`
2019-12-18 14:32:10 +01:00
repline "$coa1" "$coa3$stamp"
coar=${coar#* }
done
showall doing
;;
k) echo "$kbs" | showselect
currkan=`getselect $currkan`
showall doing
;;
2019-12-11 12:39:32 +01:00
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" != ""
# replace all tabs by spaces (otherwise issue with ed pattern in repline)
then echo '-' "$newc" | sed -e 's/ / /g' >>$currkan
2019-12-11 12:39:32 +01:00
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" ...
2019-12-12 13:32:08 +01:00
"$editor" "$currkan" ;;
2020-05-11 22:31:08 +02:00
f) filtr="${coa1:-.}"
echo "filtering for grep pattern '$filtr'" ;;
2019-12-17 15:25:44 +01:00
!*) echo
$myshell "${com#!} $coa1 $coa2 $coa3 $coar"
echo ;;
[A-Za-z]*) echo
$myshell "$com $coa1 $coa2 $coa3 $coar"
echo ;;
*) showhelp
showall doing ;;
esac
showprompt
done
echo
2017-06-22 13:42:07 +02:00
rm -f $tmpf