Skip to content

Instantly share code, notes, and snippets.

@kennycason
Last active June 25, 2020 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kennycason/cf606d23a5cb812a13f842da043fedcb to your computer and use it in GitHub Desktop.
Save kennycason/cf606d23a5cb812a13f842da043fedcb to your computer and use it in GitHub Desktop.
TODO.sh
# settings to get working in zsh
autoload bashcompinit
bashcompinit
setopt localoptions rmstarsilent
setopt +o nomatch
source ~/todo.sh

todo.sh (v2)

I made this version for my own usage. I merged todo and fin commands and added some more functionality.

Usage:

todo feed dog, create a todo item for feed dog, to mark as resolved simply type todo feed dog again. (Auto correct also works. todo clear, clear all the todo/done done items. todo clear-todo, clear only the todo items. todo clear-done, clear only the done items.

todo.sh (v1)

I made misc updates to your script to get it working and made a few minor improvements.

OLD NOTES

Instead of making the user create the ~/TODO/ and ~/TODO/outstanding_tasks and ~/TODO/completed_tasks folders, your script could do that automatically for the user.

mkdir -p command will make directory if not exist.

mkdir -p ~/TODO/outstanding_tasks
mkdir -p ~/TODO/completed_tasks

I noticed your two soft link examples the operands were not consisent. Inconsistency is the main thing I noticed, so I know one of them is wrong. I believe you want them to be like the below, but confirm ordering. ln -s ~/TODO ~/Google\ Drive/TODO ln -s ~/TODO ~/Dropbox/TODO

ref: https://www.computerhope.com/unix/uln.htm

Note the "fin" command: dope~: fin write\ medium\ post

Then notice the "todo" command: dope~: todo write medium post

You see how the "todo" command did not require you to put in the "\ " for space? It would be nice if that was not required like with todo command. I think the reason it may not have worked for you was a small bug in the fin function. Specifcally when you are identifying the file path name for the todo list item you correctly use this ${TASKS_DIR}"${*}". However, in the fin function you wrote this: mv ${TASKS_DIR}"$1" ${COMPLETED_DIR}, to move the item, but $1 is not what you want to use, it needs to be: mv ${TASKS_DIR}"$*" ${COMPLETED_DIR}. If you do that, I think you can then avoid using "\ " in the fin command.

I suspect that this may also mean you then won't need the COMPREPLY=( "${tmp[@]// /\ }" ) transform in the _fin function.

This final thought is more of a design thought. But I want to be clear, i really love your implmentation and it's simplifcity. So consider this below as just an extra thought and just for fun.

I just realized an even easier way to handle "fin" function. What if when you print TODOs you add numbers like this:

— — — — — — — — — — — TODO — — — — — — — — — — — — 
  1. [] write medium post
  2. [] publish medium post
— — — — — — — — — — — — — — — — — — — — — — — — —

and then you can just type: fin 1 to mark the first item as finished. This may make it easier to use. The code would be a bit more complex though as you'd want to name files something like TODO/outstanding/1_pick_up_trash, TODO/outstanding/2_take_shower. Note the number at the beginning of the file name to help with deleting since mv command could just be something like mv TODO/outstanding/1_* TODO/complete/

#!/bin/sh
BOLD_AND_UNDERLINED="\e[1;4m"
GREEN="\e[32m"
STANDARD="\e[0m"
TODO_LIST_LABEL="\n — — — — — — — — — — — -TODO — — — — — — — — — — — — -\n"
TODO_LIST_END=" — — — — — — — — — — — — — — — — — — — — — — — — — — \n\n"
TASKS_DIR=~/TODO/outstanding_tasks/
COMPLETED_DIR=~/TODO/completed_tasks/
function todo {
if [ -z "$1" ]
then
printf "${TODO_LIST_LABEL}"
find ${TASKS_DIR} -not -path '*/\.*' -type f -execdir echo '{}' ';' | nl -s '[] ' -b n
printf "${TODO_LIST_END}"
else
touch ${TASKS_DIR}"${*}"
todo
fi
}
_fin () {
IFS=$'\n' tmp=( $(compgen -W "$(ls "${TASKS_DIR}")" — "${COMP_WORDS[$COMP_CWORD]}" ))
COMPREPLY=( "${tmp[@]// /\ }" )
IFS=$' '
}
function fin {
if ! [ -z "$1" ]
then
if [ -f ${TASKS_DIR}"${*}" ]
then
mv ${TASKS_DIR}"${*}" ${COMPLETED_DIR}
todo
printf " ${GREEN}DONE ${STANDARD}with ${BOLD_AND_UNDERLINED}"${*}"${STANDARD}\n\n"
else
echo -e "\ntodo item ["${*}"] not found."
todo
fi
else
echo -e "\nusage: fin [existing task to complete]\n"
fi
}
complete -o default -F _fin fin
#!/bin/sh
BOLD_AND_UNDERLINED="\e[1;4m"
GREEN="\e[32m"
STANDARD="\e[0m"
TODO_LIST_LABEL="— — — — — — — — — —TODO — — — — — — — — — — — — — —\n"
DONE_LIST_LABEL="— — — — — — — — — —DONE — — — — — — — — — — — — — —\n"
TODO_LIST_END="— — — — — — — — — — — — — — — — — — — — — — — — — — \n"
APP_DIR=~/todo/
TASKS_DIR=${APP_DIR}todo/
COMPLETED_DIR=${APP_DIR}done/
mkdir -p ${TASKS_DIR}
mkdir -p ${COMPLETED_DIR}
# delete done items that are over 7 days
find "${COMPLETED_DIR}" -name "*" -type f -mtime +7 -exec rm {} \;
function print_todo_and_done {
printf "${TODO_LIST_LABEL}"
find ${TASKS_DIR} -not -path '*/\.*' -type f -execdir echo '{}' ';' | nl -s '[ ] ' -b n
printf "${DONE_LIST_LABEL}"
find ${COMPLETED_DIR} -not -path '*/\.*' -type f -execdir echo '{}' ';' | nl -s '[✔] ' -b n
printf "${TODO_LIST_END}"
}
function print_todo {
printf "${TODO_LIST_LABEL}"
find ${TASKS_DIR} -not -path '*/\.*' -type f -execdir echo '{}' ';' | nl -s '[ ] ' -b n
printf "${TODO_LIST_END}"
}
function print_done {
printf "${DONE_LIST_LABEL}"
find ${COMPLETED_DIR} -not -path '*/\.*' -type f -execdir echo '{}' ';' | nl -s '[✔] ' -b n
printf "${TODO_LIST_END}"
}
function todo {
if [ -z "$1" ]
then
print_todo
else
if [ $1 = "clear-all" ]
then
rm -f "${TASKS_DIR}"*
rm -f "${COMPLETED_DIR}"*
print_todo
elif [ $1 = "clear-todo" ]
then
rm -f "${TASKS_DIR}"*
print_todo
elif [ $1 = "clear-done" ]
then
rm -f "${COMPLETED_DIR}"*
print_todo_and_done
elif [ $1 = "do-all" ]
then
mv ${TASKS_DIR}"*" ${COMPLETED_DIR}
print_todo_and_done
elif [ $1 = "done" ]
then
print_done
else
TASK="${*}"
if [ -f ${TASKS_DIR}${TASK} ]
then
mv ${TASKS_DIR}${TASK} ${COMPLETED_DIR}
printf "Marking [${BOLD_AND_UNDERLINED}${TASK}${STANDARD}] as ${GREEN}DONE${STANDARD}\n"
print_todo
elif [ -f ${COMPLETED_DIR}${TASK} ]
then
mv ${COMPLETED_DIR}${TASK} ${TASKS_DIR}
printf "Marking [${TASK}] as TODO\n"
print_todo
else
touch ${TASKS_DIR}${TASK}
print_todo
fi
fi
fi
return 0
}
_todo () {
IFS=$'\n' tmp=( $(compgen -W "$(ls "${TASKS_DIR}")" — "${COMP_WORDS[$COMP_CWORD]}" ))
COMPREPLY=( "${tmp[@]// /\ }" )
IFS=$' '
}
complete -o default -F _todo todo
todo
@kennycason
Copy link
Author

image

text:

➜  ~ todo refactor code

 — — — — — — — — — — — -TODO — — — — — — — — — — — — -
      [] refactor code
      [] do 10 backflips
      [] clean yard
      [] build ant farm
 — — — — — — — — — — — — — — — — — — — — — — — — — —

➜  ~ fin clean someone elses yard

todo item [clean someone elses yard] not found.

 — — — — — — — — — — — -TODO — — — — — — — — — — — — -
      [] refactor code
      [] do 10 backflips
      [] clean yard
      [] build ant farm
 — — — — — — — — — — — — — — — — — — — — — — — — — —

➜  ~ fin clean yard

 — — — — — — — — — — — -TODO — — — — — — — — — — — — -
      [] refactor code
      [] do 10 backflips
      [] build ant farm
 — — — — — — — — — — — — — — — — — — — — — — — — — —

 DONE with clean yard

➜  ~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment