コマンドラインToDoツール、TaskWarrior

タグ: タスク管理  

WebサービスとしてToDoは作りやすく、利用者も見込めるため、数多くのサービスが存在しています。私はGoogleのInboxのリマインダーをToDo管理にこの1年利用しています。

しかし、リマインダーとToDoではやはり求めているものが違います。そこで新しいものがないかと、WebサービスやGUIなどを探しましたがピンと来ませんでした。OSとして利用しているopenSUSEのソフトウェアリポジトリに登録されているものも全て試しました。

最終的に残ったのが、TaskWarriorです。コマンドラインのツールです。「ツール」と呼ぶ拡張機能で、GUIで利用したり、vimを使って管理したり、GitリポジトリサービスのIssueと連携したり、いろいろできるようです。(ただ正直、そこまで行いたいのであれば、Web上のサービスのほうが便利です。)

データはテキストファイルとして、管理用のディレクトリ下に保存されます。ローカルだけでなく、他の端末などで利用したいのであれば、このディレクトリをDropboxサービスのような自動同期ディレクトリに設定したり、開発者に馴染みのある方法としては、Gitでソース管理し、GitHubなどのリポジトリサービスにpushして多端末間で利用できます。シンプルですから、工夫はいろいろできます。後ほど、その一例を紹介します。

なお、内容はバージョン2.5.1で確認しています。開発が続いていますので、動作が過去や将来のバージョンで変更される可能性があります。

インストール

メジャーどころのOSであれば、ダウンロードページに入手コマンドが説明されています。

私の利用しているopenSUSEの場合、リポジトリのバージョンが古く、公式ドキュメントの内容と合わなかったため、ソースを入手してコンパイルしました。ダウンロードページの"Quick Setup"のセクションに記述されているとおりで、さほど手間がかかりません。

簡単な利用方法

利用方法は簡単です。ちょっといじってみれば習得できます。

インストールするとtaksコマンドラインツールが用意されます。基本的にはtask subcommandのように、サブコマンドを付けて利用します。

task helpでサブコマンドと、利用するために便利な情報が表示されます。

登録済みのタスクの確認

task

コマンド名のみで起動すると、タスクの一覧が表示されます。後述しますが、TaskWarriorでは優先順位などいろいろな属性をタスクに指定できます。そうした属性に合わせ、表示形式が自動的に切り替わります。例えば、最もシンプルなタスクだけであれば、

$  task
[/usr/bin/task next]

ID Age Description  Urg
1 2s  富士山へ登る    0

1 task

タスクに、期限とプライオリティとタグを付けると、次のように変わります。

 $ task
[/usr/bin/task next]

ID Age P Tag   Due Description    Urg
1 9s  H hobby 6d  富士山から下山 12.7

1 task

サブコマンドを省略したtasktask nextと同じ動作です。このコマンドは、TaksWarriorが決めた重要度に基づいてタスクを順番に表示してくれます。重要度は各タスクの右端、Urg欄で表示されます。

タスクのIDを1つだけ指定すると、そのタスクの詳細が表示されます。これは保存されるJSON形式の情報をわかりやすく表示したものです。

$ task 2
No command specified - assuming 'information'.

Name          Value
ID            2
Description   1月の仕事短縮
Status        Pending
Entered       2018-04-25 16:39:01 (4min)
Due           2019-01-01 00:00:00
Last modified 2018-04-25 16:39:01 (4min)
Virtual tags  PENDING READY UNBLOCKED LATEST
UUID          cfcf5ebb-450f-43bc-bc4f-e7cdb0636386
Urgency        2.4

    due    0.2 *   12 =    2.4
                        ------
                        2.4

表示されているように、informationサブコマンドが省略されています。

タスクの登録

addサブコマンドを使い、タスクを新規登録します。

$ task add 顔を洗う

よく使用するだろうプライオリティと期限を付ける方法です。

$ task add 顔を洗う prio:L due:2018-04-25

プライオリティはデフォルトで、HML、未指定の順番で高くなります。設定で使用する文字列や順番を変えることが可能です。例えば、H、未指定、Lの順番のほうが、馴染み深いかと思います。

カテゴライズするために任意のアルファベットのタグを好きな数付けることもできます。

$ task add 歯を磨く +life +clean

もう一つのカテゴライズ方法は、タスクをプロジェクトに分ける方法です。

$task add カテゴリー未指定
$task add カテゴリー指定 pro:web-app
$task

ID Age  Project Description      Urg
2 6s   web-app カテゴリー指定      1
1 1min         カテゴリー未指定    0

タスクをプロジェクトに分けると、プロジェクトごとの達成率をtask summaryで表示したりでき、きちんとした管理がやりやすくなります。

もちろんプロジェクトとタグを組み合わせることもできます。ただ、複雑な利用方法をするのであれば、Webサービスなどのほうが便利でしょう。多少のタグを使用するか、もしくはタグも使用しないごくシンプルな使用方法のほうが、コマンドラインでToDoを管理するのであれば良いかと思います。

特定のタグやプロジェクトに属しているタスクだけを表示できます。

$ task +hobby
$ task +hobby list
$ task pro:web-app next

タブに関しては、そのタブを持っていないタスクを表示することもできます。

$ task -hobby

プロジェクト名をピリオドで区切り、階層をもたせることができます。ただ、そこまでやるのであれば…

$ task add pro:hobby.drawing ドローイングの練習
$ task add pro:hobby.dev.php PHPプログラムの開発
$ task count pro:hobby
2
$ task count pro:hobby.dev
1

taskの開始、完了、削除

基本的にはタスク操作は一つづつ行うはずです。ですからtaskを実行し、リストを表示し、そこで表示されるID番号を指定して、操作することが多いでしょう。

タスクを開始するにはstartです。「現在取り掛かり中である」というフラグを立てる意味合いです。

$ task 1 start

一度始めたタスクを停止するのは、stopです。

$ task 1 stop

タスクを完了するにはdoneを利用します。タスクを開始していなくても、完了可能です。startすると表示が多少変化します。現在取り掛かり中である目安になりますが、必須ではありません。面倒であれば、startを使用する必要はないでしょう。

$ task 1 done

完了したタスクはリストの表示から消えます。完了、削除したタスクをすべて表示したい場合はallコマンドを使用します。

$ task all

場合により、タスクを実行せずにリストから削除したい場合もあります。その場合はdeleteか、エイリアスのrmを使用します。

$ task 1 delete

taskのコマンド形式

上記リンク先ページで説明されています。

task [フィルター] [サブコマンド] [修飾子|その他]

修飾子とは、期日のduo:やプライオリティのpri:、タグの+hobbyなどを指します。修飾子はフィルターとしても利用されます。

フィルターはサブコマンドの適用を限定するために使用します。直前のセクションで説明した通り、プロジェクトを指定したり、タグで絞り込んだりできます。その他に例えば、数値のIDも指定できます。以下の例では、指定したIDのタスクのみリストで表示されます。

$ task 1 list
$ task 1-5 list
$ task 2,4,6 list

サブコマンドとフィルター、修飾子は、識別できる限り短く指定できます。例えばプロジェクトのpro:は、正式にはproject:です。プライオリティは、priority:です。

日時の指定フォーマット

期日やフィルターにはISO-8601形式が利用できます。しかし、期日と時間を同時に指定する場合以外で、この形式を直接利用することは少ないでしょう。

$task add 日時と時間を指定する場合 due:2018-04-26T12:00

とはいえ、馴染み深いyyyy-mm-ddyyyy-mmの日付形式、hh:mm:sshh:mmの時間形式も含まれているため、利用可能です。

設定により、ISO-8601形式以外の期日フォーマットを変更可能です。デフォルトは、yyyy-mm-ddです。

$ task add 明日の予定 due:2018-04-26
$ task add 20時の予定 due:20:00
$ task add 明日の朝の予定 due:06:00

yy-mm-dd形式で期日を指定した場合、時間は00:00:00が指定されます。

hh:mm形式で時間を指定した場合、コマンドを入力した時点でその時間が過ぎていれば明日の期日、指定時間になっていない場合は今日の期日として登録されます。

日本語では無理ですが、英語の曜日や月名を指定し、日時の指定も可能です。増減も指定可能です。(バグがありsun+12h30mは増分が無視される。sun+12h+30mは最初の12hのみ有効)

$ task add 月曜日の仕事 due:monday
$ task add 月曜の短縮形 due:mon
$ task add 土曜日の仕事 due:satuday
$ task add 短縮形は頭3文字 due:sat
$ task add 日曜日の仕事 due:sun
$ task add 日曜お昼までの仕事 due:sun+12h
$ task add 日曜12:30までの仕事 due:sun+12.5h
$ task add 1月の仕事 due:january
$ task add 短縮形は頭3文字 due:jan
$ task add 12月の仕事 due:decenber
$ task add 12月15日までの仕事 due:dec+15d

この場合も、時間を指定したときと同様に、現在の曜日や月を考慮し、適切な日時を設定してくれます。月名で指定した場合は、月初の00:00:00が指定されます。そのため、due:dec+15dは16日の00:00:00を指すため、厳密に指定したい場合はdue:dec+15d-1sを付けます。もしくはdue:dec+14dです。目的により異なりますね。(繰り返しますが、あまり厳密にやるよりは、ざっくりと利用しましょう。期日が近づくにつれ、見直す機会があるでしょうから、その時に指定し直すのが実用的でしょう。)

日付だけを英語の序数で指定することもできます。適宜、今月か来月のその日付が指定されます。他の期日の指定方法と同様に、時間としては00:00:00が指定されます。残念ながら、増減は指定できません。

$ task add 15日までに仕上げる仕事 due:15th

その他、nowtodaytomorrowyesterdayなども用意されています。日数や時間の増減を指定できるため、単語としてはnowtodayを覚えておけば、事足ります。

$ task add 明後日終日までの仕事 due:today+3d-1s
$ task add 2週間後までの仕事 due:today+2w
$ task add 3ヶ月後までの仕事 due:today+3m
$ task add 今から8時間後までの仕事 due:now+8h

ただし、nowは省略可能です。そのため、上記の最後のタスク登録例は、次のように短く書けます。

$ task add 今から8時間後までの仕事 due:8h

「3日後締め切り」の場合、意味合いとしては「3日後の0:00に締め切り」、「3日後の23:59:59に締め切り」、「今の時点から3日間(24時間×3日)」のように解釈できます。これでよくトラブルが起きます。これらを正確に登録してみましょう。

$ task add 3日後の0:00 due:today+3d
$ task add 3日後の23:59:59 due:today+4d-1s
$ task add 3日後の現時分 due:3d

初めと終わりを示す短縮形も用意されています。so...は"start of ..."、eo...は"end of ..."です。それぞれ、適当な日付や時間が設定されます。eo...形式の短縮形では、その日の23:59:59がきちんと指定されます。

$ task add 年末 due:soy
$ task add 年末 due:eoy
$ task add 月初 due:som
$ task add 月末 due:eom
$ task add 週初め due:sow
$ task add 週末 due:eow
$ task add 日の初め due:sod
$ task add 日の終わり due:eod

丸暗記と言うより、理解により覚えられる範囲を紹介しました。

繰り返しと日時のバリエーション

繰り返しのタスクも登録できます。ただし、現在のバージョンで正確に動作するのは週単位までです。月や年は決まった日数を足し込む実装になっており、例えば一月ごとの繰り返しを指定すると、30日間隔になります。利用は週単位までにしましょう。

$ task add 毎日のタスク due:07:00 recur:daily
$ task add 2日おきに水やり due:08:00 recur:2d
$ task add 月曜日8:00時の掃除 due:mon+8h recur:weekly

年単位の繰り返しの実装が正確であれば、誕生日や記念日を忘れないように登録しておくのは役に立ちます。将来的には、正確に繰り返せるように実装されることを期待し、指定可能な日時修飾子のバリエーションを紹介します。この内容はドキュメントのUsing Dates Effectivelyページで紹介されています。

$ task add 大切な人の誕生日 due:2018-07-04 scheduled:due-4d wait:due-1m until:due+2d

dueが示すのが誕生日です。

waitは、たとえばtaskと入力した時に、そのタスクがリストにいつから表示開始されるかを指定します。かなり先のタスクが毎回リストに表示されるとリスト自体が長くなりますし、目障りになります。これ防ぐために、リストに乗り始める日時を指定します。もちろんwaitを指定していても、例えばtask waitingtask allで表示できます。

untilは、その指定時間が過ぎたら自動的にタスクを削除するために指定します。「忙しくて誕生日を祝えなかった」などの理由でタスクが実行できなくても、untilで指定したタイミングで自動的に削除してくれます。

scheduledを理解するには、TaskWarriorのタスクの状態を理解する必要があります。タスクを細かく管理する人のために、scheduledは用意されています。taskで表示されるのはPENDING状態のタスクリストです。つまり、実行保留状態のタスクです。

後述しますが、タスクには依存関係が指定できます。「パンケーキを焼く」には、その前に「卵を購入する」必要があるならば、「パンケーキを焼く」タスクは、「卵を購入する」タスクへ依存しています。「卵を購入」するまでは、「パンケーキを焼く」ことはできません。

そこで、今すぐ実行できるかどうかを表すREADY状態が用意されています。上記の依存関係では、「卵を購入する」タスクはREADYですが、「パンケーキを焼く」タスクはREADYでありません。

scheduledの指定は、いつREADYにするかを指定します。いつから取り掛かる予定なのかを表す日時です。

tasktask listでは、PENDING状態のタスクが表示されます。その中でもREADY状態である、つまり今すぐ取り掛かれる状態のタスクのみを絞り込んで表示するには、task readyを使います。

まとめると全部制定するのであれば、現在 < wait < scheduled < due < until < 遠い将来 になります。もちろん、全部指定する必要なく、自分の管理スタイルに合わせて使用してください。通常のタスク管理では付けるとしても、せいぜいdue:だけでしょう。

状態変化は、タスクに付ける仮想タグで管理されています。仮想タグとはTaskWarriorが自動的に付けたり、消したりするタグです。その変化の様子を観察するには、短い時間で変化するタスクを登録して、確かめるのが手っ取り早いでしょう。

$ task add タスク遷移状態の観察 due:15s scheduled:due-5s wait:due-10s until:due+5s

5秒毎に変化します。tasktask IDを使い、変化を観察しましょう。登録後5秒間はPENDINGタグがついておらず、taskでは表示されません。5から10秒はREADYタグが付きません。10秒過ぎるとREADYタグがつきます。20秒後に自動的に削除されます。(タスクの削除はリスト系のコマンドで実行されるようです。そのため、task IDだけを実行しても、いつまでもタスクは削除されません。)

タスクの編集

一度登録したタスクを編集するには2つの方法があります。コマンドで直接変更する方法と、vimなどのエディターにより変更する方法です。エディターを使用して編集する方法は、あるタスクの複数の指定を一度に変数するのに便利です。

$ task 1 edit
$ task 2-4 edit

複数のタスクを指定すると、順番に処理されます。最初のタスクのためにエディターが起動し、それを終了すると次のタスクのためにエディターが開きます。編集内容は以下のようになります。

# The 'task <id> edit' command allows you to modify all aspects of a task
# using a text editor.  Below is a representation of all the task details.
# Modify what you wish, and when you save and quit your editor,
# Taskwarrior will read this file, determine what changed, and apply
# those changes.  If you exit your editor without saving or making
# modifications, Taskwarrior will do nothing.
#
# Lines that begin with # represent data you cannot change, like ID.
# If you get too creative with your editing, Taskwarrior will send you
# back to the editor to try again.
#
# Should you find yourself in an endless loop, re-editing the same file,
# just quit the editor without making any changes.  Taskwarrior will
# notice this and stop the editing.
#
# Name               Editable details
# -----------------  ----------------------------------------------------
# ID:                1
# UUID:              b5c51bfa-b60b-457a-bd0b-f934b01bf7a9
# Status:            Pending
# Mask:
# iMask:
  Project:
# Separate the tags with spaces, like this: tag1 tag2
  Tags:
  Description:       朝飯を作る
  Created:           2018-04-26 10:04:12
  Started:
  Ended:
  Scheduled:
  Due:               2018-04-28 23:59:59
  Until:
  Recur:
  Wait until:
# Modified:          2018-04-26 10:04:12
  Parent:
# Annotations look like this: <date> -- <text> and there can be any number of them.
# The ' -- ' separator between the date and text field should not be removed.
# A "blank slot" for adding an annotation follows for your convenience.
  Annotation:        2018-04-26 10:13:40 --
# Dependencies should be a comma-separated list of task IDs/UUIDs or ID ranges, with no spaces.
  Dependencies:
# User Defined Attributes
  UDA priority:
# End

通常はコマンドラインで、既存タスクの内容を変更することが多いでしょう。

$ task add 夕飯の準備
Created task 3.
$ task 3 mod due:30min
$ task 3 mod due:1h
$ task 3 mod 夕飯の買い出し
$ task 3 mod due:

タスクを作成し、modサブコマンドで、まず完了目標を30分後に指定しました。しかし、30分じゃ短すぎると考え直し、1時間に指定しなおしました。ところが、作るのが面倒になったので、弁当でも買いに行くことにし、タスクの説明を変更しました。時間の指定は必要なくなったので、due:だけを指定して、キャンセルしました。

タスクの登録では、そのタスクの内容の「説明」と必要であれば修飾子を指定します。タスクをmodifyサブコマンド、短くすればmodmoで変更する場合は、変更・追加・削除したい内容だけを指定できます。例では、due:のみ最初に追加し、その後変更し、最後に削除しました。説明として「夕飯の買い出し」を指定することで、最初に登録した「夕飯の準備」は上書きされます。

もちろん、複数項目をまとめて変更することも可能です。

$ task add テストを沖縄
Created task 11.
$ task 11 mod テストを行う due:15:00 prio:H

コマンドラインでは、後述のフィルタリングを利用して、複数のタスクをまとめて変更できます。

$ task add プラモデル作る due:1w +hobby
$ task add ボードゲーム購入 due:3d +hobby
$ task
ID Age Tag   Due Description      Urg
2 2s  hobby 2d  ボードゲーム購入 8.23
1 9s  hobby 6d  プラモデル作る    6.4

ここで、忙しくなったため、趣味は予定を1週間ずつ伸ばすことにしましょう。

$ task +hobby mod due:due+1w
  - Due will be changed from '2018-05-03' to '2018-05-10'.
Modify task 1 'プラモデル作る'? (yes/no/all/quit) y
Modifying task 1 'プラモデル作る'.

  - Due will be changed from '2018-04-29' to '2018-05-06'.
Modify task 2 'ボードゲーム購入'? (yes/no/all/quit) a
Modifying task 2 'ボードゲーム購入'.
...

プロンプトで修正するかどうかを尋ねられます。同じmodサブコマンドを使用した変更でも、タスクIDを指定する場合は、プロンプトは出さない仕様のようです。問答無用で変更されます。

もう一つ重要なのが、説明文の一部を修正したい場合です。

$ task add テストを沖縄
Created task 30.
$ task 30 mod /沖縄/おこなう/
$ task 30 mod /沖縄/行う/g

スラッシュで囲む正規表現的な指定で、置換が行なえます。最後にgを付けると、全置換です。つけない場合は、最初の一つが置換されます。

依存タスクの指定

タスクには実行順序がある場合もあります。「パンケーキを焼く」と「卵を購入する」の例を行ってみましょう。

$ task add パンケーキを焼く
$ task add 卵を購入する
$ task
ID Age Description      Urg
1 9s  パンケーキを焼く    0
2 2s  卵を購入する        0
$ task 1 mod depen:2
ID Age  Deps Description      Urg
2 54s       卵を購入する        8
1 1min 2    パンケーキを焼く   -5

依存関係のあるタスクを登録する時、タスクを列挙し、それから順番を決めることが多いでしょう。それをコマンドラインで行うのであれば、思いつくタスクをaddで登録し、後から依存を追加するのが自然なワークフローになるかと思います。もちろん、頭の中で整理がついているのであれば、タスク登録時にdepen:を指定しても構いません。

タスクに依存関係を付けると、先に実行するべきタスクの重要度(Urgency:Urg)が上がります。

フィルタリング

ほとんどのタスクはフィルターを指定し、対象範囲を絞り込めます。しかし、確認のため頻繁に表示する項目はサブコマンドに用意されています。

  • task all 削除済みも含め、すべてのタスクの表示。
  • task active task startで実行したタスクの表示。
  • task blocked 依存関係の指定で、「頼っている」タスク。つまり、他のタスクよりも「後」に実行するタスクの表示。
  • task blocking 依存関係の指定で、「頼られている」タスク。つまり、他のタスクよりも「前」に実行するタスクの表示。
  • task newest タスクを新しい順に表示。
  • task oldest タスクを古い順に表示。
  • task ready 現時点で取り掛かることができるタスクの表示。
  • task recurring 繰り返すタスクを表示。
  • task waiting waitの指定により、listなどでは表示されないタスクの表示。
  • task duetoday 期日が今日のタスクの表示。
  • task overdue 期限切れタスクの表示。

他にも、以下のコマンドは頻用するでしょう。

  • task projects 使用しているプロジェクト名の表示。
  • task tags 使用しているタグの表示。

コマンド全部については書ききれませんので、ドキュメントとtask helpの表示を参照してください。

フィルターの指定は範囲が広いため、利用価値のあるものをサンプルとして集めました。フィルターとそれに類する指定方法は、ドキュメントに散見できますが、基本的なものはFiltersページで説明されています。

  • task +TAGGED タグ付きのタスクを表示。
  • task tags.any: タグ付きのタスクを表示。
  • task -TAGGED タグがついていないタスクを表示。
  • task tags.none: タグがついていないタスクを表示。
  • task +this +that thisとthatのタグを両方持つタスクを表示。
  • task +this -that thisのタグを持っており、thatのタグを持っていないタスクを表示。
  • task +this or +that thisかthat、どちらか1つでも持つタスクを表示。
  • task +fire proj:water waterプロジェクトでfireタグを持つタスクを表示。
  • task prio:M プライオリティにMを指定されているタスクを表示。
  • task +DUE 期限が設定範囲内のタスクを表示。(rc.due、デフォルト7日)
  • task +DUETODAY 今日が期限のタスクを表示。
  • task +WEEK 今週が期限のタスクを表示。
  • task +MONTH 今月が期限のタスクを表示。
  • task +OVERDUE 期限切れのタスクを表示。
  • task +COMPLETED 完了済みのタスクを表示。
  • task +DELETED 削除されたタスクを表示。
  • task /キーワード/ 説明に「キーワード」を含むタスクを表示。正規表現も使用可能。

色設定

Unix/Linux系のOS上で使用しているのであれば、設定ファイルが~/.taskrcに作られます。それを開くとあらかじめカラーテーマが並んでいます。

# Color theme (uncomment one to use)
#include /usr/share/doc/task/rc/light-16.theme
#include /usr/share/doc/task/rc/light-256.theme
#include /usr/share/doc/task/rc/dark-16.theme
#include /usr/share/doc/task/rc/dark-256.theme
#include /usr/share/doc/task/rc/dark-red-256.theme
#include /usr/share/doc/task/rc/dark-green-256.theme
...

どれか一つの先頭の#を削除し、コメントを外せば、そのカラーテーマに切り替わります。

ただし、例えば私の利用しているopenSUSEでは、ファイルパスが異なっていました。また、リポジトリからインストールした際には、テーマのファイルが足りていませんでした。そうした、OSによる違いはありますので、多少調べる必要はあるでしょう。

また、視覚に優しいSolarizedテーマも含まれていますが、まず端末ソフトをSolarizedテーマへ設定しておく必要があります。このテーマを使用する際には、注意しましょう。

多端末での利用

Unix/Linux系であれば、デフォルトで~/.taskディレクトリにタスクデータのテキストファイルが保存されています。このディレクトリーパスは、~/.taskrcの最初で定義されています。

多端末でTaskWarriorを使用する場合、一番簡単なのはDropboxのようなフォルダー自動同期サービスを使用することです。自動同期されるフォルダーの中に、データディレクトリーを指定すれば、どの端末からでもタスク管理が可能です。

data.location=~/Dropbox/.task

これが一番簡単です。

WebサービスでTaskWarriorの同期を行ってくれるものも存在しますが、最新バージョンに追従していないようなので、おすすめしません。

TaskWarriorでは、拡張機能としてToolsページに情報が集積されています。そこを探せばUIからブラウザを使って管理する拡張までいろいろあります。

残念ながら、自分で満足するものがありませんでした。やはり、一番簡単なのは自動同期サービスの利用です。

データ保存のディレクトリー下には、情報がJSON形式のテキストファイルとして保存されています。これをGitで管理することもできます。

Gitで管理できるのですから、GitHubなどのリポジトリサービスを経由して、多端末間でタスクを共有できます。

毎回、変化が起きるたびにaddとcommit、pushを自動的に行うのであれば、.taskディレクトリー下のhooksディレクトリーにon-exitというファイルを作成し、実行権限を付ければ、コマンド実行が終了するたびに、自動的に実行してくれます。

ただ、この方法の欠点は、出力がキャッシュされ、スクリプトが終了するまで、返ってきません。リモートへのpush処理は多少時間がかかるものです。その間、端末に制御が戻ってこないのは、勝手が悪いものでした。

そこで、エイリアスでtaskで自前のスクリプトを実行するバージョンを作りました。例えば、~/bin/wrapper-task.shという名前で保存します。

#!/bin/bash

# 引数をそのままtask(taskwarrior)コマンドに渡し、実行する
/usr/bin/task $@

# task(taskwarrior)コマンドにより、データディレクトリのパスを取得
work=$(/usr/bin/task _show | awk -e '{if (match($0, /data\.location=(.+)/, matched) > 0) { print matched[1] } }')

# gitコマンドを扱うため、データディレクトリへ移動する
cd "${work/\~\//$HOME/}"

# git監視下のデータファイルに変化があった場合のみ、変化をすべてコミットする
if [ -z "$(git status 2> /dev/null | grep 'nothing to commit')" ]
then
    git add --all
    git commit -m "$(date +changed\ at\ %y%m%d.%H%M)"

    # pushの時間がかかる。それを避けるにはcronで定時に実行したほうが良い
    git push &
fi

exit 0

このファイルを作成したら、.bashrcなどの適当なファイルの中で、alias task='~/bin/wrapper-task.sh'などと設定します。あとは、通常通り、task...とコマンドを実行します。保存内容に変化が起きると、その変化をcommitし、リモートリポジトリへpushします。Gitコマンドの出力が邪魔な場合は/dev/nullなどへ出力をリダイレクトしましょう。

ただ、自動同期サービスを使用するのが、やはりいちばん簡単で、使いやすいです。