diff --git a/snowblocks/taskwarrior/README.md b/snowblocks/taskwarrior/README.md new file mode 100644 index 0000000..bbdf61a --- /dev/null +++ b/snowblocks/taskwarrior/README.md @@ -0,0 +1,45 @@ +# Taskwarrior + +> Taskwarrior is a flexible, fast, and unobtrusive CLI tool to manage your TODOs that does its job and gets out of your way. + +## Extensions + +### taskopen + +The [taskopen][] extension allows to take notes and open URLs with attached to Taskwarrior tasks. + +Next to the `task` binary itself, this Perl script depends on the `JSON` module which can be installed on Arch Linux via the [perl-json][arch-perl-json] package. + +## Troubleshooting + +### taskopen workaround for macOS + +The management of installed [Perl modules][cpan-doc-modules] on macOS is not as simple and well thought through like with package managers on Linux systems, e.g. via [pacman][archw-pacman] on [Arch Linux][archlinux]. There are problems when is comes to configuring the runtime path the modules have been installed to even when using the most popular module manager called [cpanminus][]. +This causes the [Taskwarrior][] plugin [taskopen][] fail to load because the Perl core module `JSON` can't be found and loaded. + +As a workaround a custom script can be implemented to create and open an attached task note: + +1. Use the [`_get`][tw-doc-api-_get] function of the [Taskwarrior DOM API][tw-doc-dom-api] to extract any stored piece of information of an task. This allows to receive the [UUID of an task][tw-doc-ids]. +2. Create a custom `on` (open note) [Taskwarrior alias][tw-doc-alias] to run the implemented custom script via the `execute` command. + +The logic of the script follows the same like taskopen uses for default notes: + +* Use the [UUID of an task][tw-doc-ids] as the note filename. +* Simply pass the file to an editor (in this case [Atom][]) which will… + * …create a new file if it doesn't exist yet. + * …open the file if it already exists. + +Note that **this script is not limited to macOS** but can also be used for any other Linux host! + +[archlinux]: https://archlinux.org +[arch-perl-json]: https://www.archlinux.org/packages/community/any/perl-json +[archw-pacman]: https://wiki.archlinux.org/index.php/Pacman +[atom]: https://atom.io +[cpanminus]: https://github.com/miyagawa/cpanminus +[cpan-doc-modules]: http://www.cpan.org/modules +[taskopen]: https://github.com/ValiValpas/taskopen +[taskwarrior]: https://taskwarrior.org +[tw-doc-alias]: https://taskwarrior.org/docs/terminology.html#alias +[tw-doc-api-_get]: https://taskwarrior.org/docs/commands/_get.html +[tw-doc-dom-api]: https://taskwarrior.org/docs/dom.html +[tw-doc-ids]: https://taskwarrior.org/docs/ids.html diff --git a/snowblocks/taskwarrior/scripts/open-note.sh b/snowblocks/taskwarrior/scripts/open-note.sh new file mode 100755 index 0000000..ce03f11 --- /dev/null +++ b/snowblocks/taskwarrior/scripts/open-note.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# Copyright (C) 2016-present Arctic Ice Studio +# Copyright (C) 2016-present Sven Greb + +# Project: igloo +# Repository: https://github.com/arcticicestudio/igloo +# License: MIT +# References: +# https://taskwarrior.org/docs +# https://taskwarrior.org/docs/terminology.html#regex +# taskrc(5) +# task(1) +# https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions + +set -e + +cleanup() { + unset -f log_error validate_parameter get_task_uuid open_notes +} + +log_error() { + printf "\e[31m%s\e[0m\n" "✖ $*" 1>&2 +} + +validate_parameter() { + if [ $# -eq 0 ]; then + log_error "No task IDs specified!" + exit 1 + fi + + local VALID_NUMBER_REGEX="^[0-9]+$" + if ! [[ $1 =~ $VALID_NUMBER_REGEX ]]; then + log_error "Invalid parameter '$1': parameters must be of type number!" + exit 1 + fi +} + +get_task_uuid() { + local task_id=$1 + local uuid="$(task _get $task_id.uuid)" + if [ -z $uuid ]; then + log_error "No task found with for specified ID '$task_id'!" + exit 1 + fi + printf "$uuid" +} + +open_notes() { + declare -a local task_uuids + local task_uuid + local note_path="~/.task/notes" + local editor_cmd="atom -a" + local note_file_ext="md" + + for task_id in $@; do + validate_parameter $task_id + task_uuid="$(get_task_uuid $task_id)" + if ! [ -z $task_uuid ]; then + $editor_cmd "$note_path/$task_uuid.$note_file_ext" + fi + done +} + +trap 'printf "User aborted.\n" && exit 1' SIGINT SIGTERM +trap cleanup EXIT + +open_notes $@ +exit 0 diff --git a/snowblocks/taskwarrior/snowblock.json b/snowblocks/taskwarrior/snowblock.json index e6ec4f8..c8e34c9 100644 --- a/snowblocks/taskwarrior/snowblock.json +++ b/snowblocks/taskwarrior/snowblock.json @@ -38,6 +38,11 @@ "create": true, "force": true, "path": "hooks/on-modify-track-total-active-time.py" + }, + "~/.task/scripts/open-note.sh": { + "create": true, + "force": true, + "path": "scripts/open-note.sh" } } } diff --git a/snowblocks/taskwarrior/taskrc b/snowblocks/taskwarrior/taskrc index d1edb48..2578c21 100644 --- a/snowblocks/taskwarrior/taskrc +++ b/snowblocks/taskwarrior/taskrc @@ -88,3 +88,4 @@ alias.e=edit alias.ls=list alias.mod=modify alias.o=execute taskopen +alias.on=execute "$HOME/.task/scripts/open-note.sh"