定常的な作業のチェックリストを確認するためのAlfred Workflowを作成する

# TL;DR
定常的な作業の実施確認のためのチェックリストをAlfred Workflowで作成しました。
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180925/38c911b1-3f18-7349-2567-802915aa292d.gif)


[ダウンロード](https://github.com/ObaTakeshi/flight_checklists/releases)
[ソースコード・使い方](https://github.com/ObaTakeshi/flight_checklists)

# 本文
デスクワークは日々同じ作業をするということが多いと思います。しかし、同じ作業だからこそ惰性でやってしまいミスをする。また、うっかり行うのを忘れてしまうということがあると思います。

そのための手軽なチェックリストとしてFlight ChecklistsというAlfred Workflowを作成しました。
機能は以下の通りです。
1. `continue`: 前回のchecklistデータを読み込み、続きから確認を再開する。
2. `checklists`: checklistsを読み込み、初めから確認を行う。
3. `make`: checklistを作成する。~/Documents/checklists上でvimが起動する。
4. `clean`: 実行途中のchecklistデータを削除する。

使用例は上記のgifをご参照ください。
今回は以下のWorkflowの全体像のうちのいくつかを説明します。
![スクリーンショット 2021-06-13 14.25.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180925/435851a6-b710-c183-473a-88a56715d1d2.png)

### ①Workflowのトリガー
ここでは、AlfredからWorkflowへの入り口の部分を説明します。

ここでやっていることは以下の3点です。
1. `Keyword`トリガー (今回は「flight」で起動）
2. `Script Filter`アクション（機能を選択する）
3. `Conditional`で選択された機能を呼び出す
 
今回は4つの機能の選択を表示するため、`Script Filter`では以下のようなJSONをpythonで出力しています。

```python:Script_filter(python)
import sys
import json

options = {"items": [
            {"title": "continue", "arg": ""},
            {"title": "checklists", "arg": "txt"},
            {"title": "make", "arg": "make"},
            {"title": "clean", "arg": "clean"}
        ]}

print(json.dumps(options))
```

ここで、`"title"`はメニューに表示する文字列であり、`"arg"`が次の`Conditional`に渡す値です。
`Script Filter`で選択された値を`Conditional`で分岐させ、それぞれの機能を動作させます。
次以降の節で、それぞれの機能の記述について説明します。

### ②キャッシュをクリアする
`clean`機能の記述について説明します。
`clean`機能は、チェックリストの確認途中でAlfredを閉じた場合に残るキャッシュをクリアするために用います。
内部では、④,⑤の`checklists`機能で使用するキャッシュデータをクリアしています。

~~ちなみに、やりかけのチェックリストがある状態で`checklists`機能を新たに実行すると、選択されたチェックリストでキャッシュが上書きされて、正常に新たなチェックリストを実行できます。~~
~~つまり、`clean`機能はその名の通り、キャッシュが残っている状態が心地良くないと感じる人の心をクリーンにするための機能です。~~

### ③チェックリストを作成する
ここでは、`make`機能の記述について説明します。
Flight Checklistsでは以下の`txt`ファイルでチェックリストを作成することを前提にしています。

```txt:txt
* 必須のチェック要素。
- 任意のチェック要素。

...[以下上記２点のどちらかの繰り返し]
```

<details>
<summary>例:使用例のチェックリストの記述</summary><div>

```txt:foo.txt
* タイマー
* 打刻
* 瞑想
- あいさつ
```

</div></details>

上記のような、txtファイルを指定のディレクトリで作成することで、チェックリスト確認を実行する`checklists`や確認を再開する`continue`機能でチェックリストを読み込めます。

フォーマットをある程度指定されているので、専用のエディタという選択肢もありますが、
今回はvimを指定のディレクトリで起動させるTerminal Commandアクションを用いました。

```zsh:Terminal_Command(zsh)
mkdir ~/Documents/checklists

cd ~/Documents/checklists

vim
```

### ④, ⑤チェックリストを実行する
ここでは、`checklists`機能の記述について説明します。
`checklists`は、以下の様なフローです。

1. `File Filter`で指定のディレクトリ以下の`txt`ファイル一覧を表示する
1. 選択された`txt`ファイルの情報をWorkflowのキャッシュに書き込みする
1. `Call External`で`self.selectCheck`を呼び出す
1. `Script Filter`でキャッシュのチェックリストを表示する
1. 4で選択されたチェック要素について、キャッシュの情報を書き換える。
   * また、必須の要素について全て実行済みステータスになっているか判定する
1. 全て終わっていない　→　4に戻る
   * 終わっている →　キャッシュをクリアし、完了の通知を出す

今回作成したWorkflowのキモは3~5のループです。`External`の呼び出しにより、ループの処理を記述しております。

キャッシュに関しては、以下の公式ページを参考にファイルを作成し、そのパスを環境変数として定義しています。
https://www.alfredapp.com/help/workflows/script-environment-variables/

キャッシュの中身は、元の`txt`ファイルとほぼ変わりません。
実行済みのチェック要素に関して、行頭の記号を変更し、チェックリストの末尾にずらす操作を 5. で行なっています。

### `continue`機能
今まで言及していなかった`continue`機能についても少し説明します。
`continue`機能とは、確認途中で一旦Alfredを閉じた際に、再度途中から再開する機能です。
キャッシュに必須項目が残っている場合、上のフローの　4. から再開します。
残っていない場合は、Workflowのトリガーの`Script Filter`に遷移します。

# おわりに
手軽に定常的な作業のチェックリストを確認できるWorkflow `Flight Checklists`について説明をしました。 
ぜひ、使っていただければ幸いです。もし改良されたい方はプルリクやissueをお待ちしております。