👋

starship(on nushell)のcustom commandで超簡易TODO

2022/11/26に公開

Starshipのカスタムコマンド

カスタムコマンドは他の記事でもありますので、省略します。簡単に言うと、特定条件下でプロンプトにコマンドの結果を表示するようにしたものです。今回はこの機能を使って超簡易TODOを実施してみました。

超簡易TODO

CLIのTODO ManagerやGUIアプリのTODO管理などがありますが、覚えるコストに対して使用頻度が低いということで見合わないので、これまで使ってなかったんですが、Starshipをインストールして簡易TODOできそうということで実践してみました。

こんな感じでStarshipでプロンプトにカレントフォルダのファイルから情報を取得して表示します。
📝DenoTODO.itemファイルから、Markdownファイルから未チェックボックスの件数をカウントして💦(件数)として表示しています。

超簡易TODO #1

カレントディレクトリにTODO.itemというファイルを見つけるとその内容を表示させるというものです。TODO.itemファイルには下記のように短い内容で記載しておきます。

📝Deno

ただ常に出るとプレッシャーになるので、一旦表示した以降は10分経過するまで非表示としました。

超簡易TODO #2

カレントディレクトリにあるMarkdownファイル内の未チェックボックの件数をカウントしてプロンプトに表示します。具体的には、下記のMarkdownのフォーマットのみ対応しています。

- [ ] 未チェックボックス

Tips

  • NuShellの変数って...Variables in Nushell are immutable, that means that you cannot change its value after declaration. だそうで、ちょっとハマった。
  • starshipのwhenってうまく動作しなかったので、commandで実行するコマンド(スクリプト)内で表示するか決定するようにしています。arm64環境とかの問題かもしれません。ただプロンプト表示のたびに複数コマンドを実行するよりは1つのコマンドで実行する方がオーバーヘッドが少ないかもしれません。

付録(Starship設定とスクリプト)

StarshipもNushellも初心者なんで参考程度に見ておいてください。

設定ファイルの全体フォーマット指定に$customを追加

format = """
$directory\
[](fg:#DA627D bg:#FCA17D)\
$git_branch\
$git_status\
[](fg:#FCA17D bg:#86BBD8)\
$c\
$nodejs\
$rust\
$deno\
[](fg:#86BBD8 bg:#06969A)\
$docker_context\
[](fg:#06969A bg:#33658A)\
$status\
[](fg:#33658A bg:#191970)\
$custom\
[](fg:#191970)\
❯ 
"""

設定ファイルの最後にカスタムコマンドの設定を追記しておきます。

[custom.todo]
# Todo.item ファイルがあれば、その内容を表示。ただし以降10分間は表示抑止。
style = "bg:#191970 fg:#FFFFFF"
command = "source /home/kawa90/.config/nushell/chktodo.nu"
detect_files = ["TODO.item"]

[custom.md]
# Markdownファイルがあれば、未チェックのcheck boxの数を表示
# 例:💦2
style = "bg:#191970 fg:#FFFFFF"
command = "source /home/kawa90/.config/nushell/chkbox.nu"
detect_extensions = ["md"]

上記で使用しているスクリプトは以下のような実装です。

chktodo.nu:

#!/home/kawa90/.cargo/bin/nu

if ('TODO.item' | path exists) {
   # TODO.itemファイルの修正時刻が10分以上であれば内容を表示
   let $r = (ls TODO.item | where modified > (date now) - 10min | length)
      if ($r == 0) {
         touch -m 'TODO.item'
         cat TODO.item
      } else {
         error make {msg:"exit code != 0"}
      }
}

chkbox.nu:

#!/home/kawa90/.cargo/bin/nu

let mdlist = (ls *.md)
let count = 0

if ($mdlist | length) > 0 {
   let cnt = ($mdlist | get name |
       each { | it | open $it | lines |
            each { | line |
                 if ($line | str contains '- [ ] ') {
                      'found'
                 }
            }
       } | flatten | length
   )
   if $cnt > 0 {
      echo $'💦($cnt)'
   }
}

Discussion