From 8cf22480c0817fe4de9503f9897e81197667b350 Mon Sep 17 00:00:00 2001 From: romkatv Date: Thu, 20 Feb 2020 16:24:36 +0100 Subject: [PATCH] add taskwarrior prompt segment; see #511 --- README.md | 1 + config/p10k-classic.zsh | 21 +++++++ config/p10k-lean-8colors.zsh | 21 +++++++ config/p10k-lean.zsh | 21 +++++++ config/p10k-rainbow.zsh | 22 +++++++ internal/icons.zsh | 5 ++ internal/p10k.zsh | 119 ++++++++++++++++++++++++++++++++++- 7 files changed, 209 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c71aa8f..fba6e18c 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,7 @@ enable as many segments as you like. It won't slow down your prompt or Zsh start | `nix_shell` | [nix shell](https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) indicator | | `todo` | [todo](https://github.com/todotxt/todo.txt-cli) items | | `timewarrior` | [timewarrior](https://timewarrior.net/) tracking status | +| `taskwarrior` | [taskwarrior](https://timewarrior.net/) task count | | `vpn_ip` | virtual private network indicator | | `ip` | IP address and bandwidth usage for a specified network interface | | `load` | CPU load | diff --git a/config/p10k-classic.zsh b/config/p10k-classic.zsh index b374a626..2f9c791d 100644 --- a/config/p10k-classic.zsh +++ b/config/p10k-classic.zsh @@ -91,6 +91,7 @@ # swap # used swap todo # todo items (https://github.com/todotxt/todo.txt-cli) timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) # time # current time # =========================[ Line #2 ]========================= newline # \n @@ -820,6 +821,26 @@ # Custom icon. # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##################################[ context: user@hostname ]################################## # Context color when running with privileges. typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 diff --git a/config/p10k-lean-8colors.zsh b/config/p10k-lean-8colors.zsh index 0484913c..96edf071 100644 --- a/config/p10k-lean-8colors.zsh +++ b/config/p10k-lean-8colors.zsh @@ -90,6 +90,7 @@ # swap # used swap todo # todo items (https://github.com/todotxt/todo.txt-cli) timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) # time # current time # =========================[ Line #2 ]========================= newline # \n @@ -799,6 +800,26 @@ # Custom icon. # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=6 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##################################[ context: user@hostname ]################################## # Context color when running with privileges. typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 diff --git a/config/p10k-lean.zsh b/config/p10k-lean.zsh index ce206f7f..57965ba7 100644 --- a/config/p10k-lean.zsh +++ b/config/p10k-lean.zsh @@ -90,6 +90,7 @@ # swap # used swap todo # todo items (https://github.com/todotxt/todo.txt-cli) timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) # time # current time # =========================[ Line #2 ]========================= newline @@ -799,6 +800,26 @@ # Custom icon. # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##################################[ context: user@hostname ]################################## # Context color when running with privileges. typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 diff --git a/config/p10k-rainbow.zsh b/config/p10k-rainbow.zsh index 9b9acfb9..8fafe651 100644 --- a/config/p10k-rainbow.zsh +++ b/config/p10k-rainbow.zsh @@ -91,6 +91,7 @@ # swap # used swap todo # todo items (https://github.com/todotxt/todo.txt-cli) timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) # time # current time # =========================[ Line #2 ]========================= newline @@ -848,6 +849,27 @@ # Custom icon. # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + # typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=0 + # typeset -g POWERLEVEL9K_TASKWARRIOR_BACKGROUND=6 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + ##################################[ context: user@hostname ]################################## # Context color when running with privileges. typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 diff --git a/internal/icons.zsh b/internal/icons.zsh index afdee1e8..3f001af9 100644 --- a/internal/icons.zsh +++ b/internal/icons.zsh @@ -129,6 +129,7 @@ function _p9k_init_icons() { PERL_ICON 'perl' NNN_ICON 'nnn' TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' NIX_SHELL_ICON 'nix' WIFI_ICON 'WiFi' ERLANG_ICON 'erl' @@ -249,6 +250,7 @@ function _p9k_init_icons() { PERL_ICON 'perl' NNN_ICON 'nnn' TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' NIX_SHELL_ICON 'nix' WIFI_ICON 'WiFi' ERLANG_ICON 'erl' @@ -373,6 +375,7 @@ function _p9k_init_icons() { PERL_ICON 'perl' NNN_ICON 'nnn' TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' NIX_SHELL_ICON 'nix' WIFI_ICON 'WiFi' ERLANG_ICON 'erl' @@ -494,6 +497,7 @@ function _p9k_init_icons() { PERL_ICON '\uE769' #  NNN_ICON 'nnn' TIMEWARRIOR_ICON '\uF49B' #  + TASKWARRIOR_ICON '\uF4A0 ' #  NIX_SHELL_ICON '\uF313 ' #  WIFI_ICON '\uF1EB ' #  ERLANG_ICON '\uE7B1 ' #  @@ -614,6 +618,7 @@ function _p9k_init_icons() { PERL_ICON 'perl' NNN_ICON 'nnn' TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' NIX_SHELL_ICON 'nix' WIFI_ICON 'WiFi' ERLANG_ICON 'erl' diff --git a/internal/p10k.zsh b/internal/p10k.zsh index 10183dd3..ff385118 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4478,6 +4478,113 @@ function _p9k_prompt_timewarrior_init() { typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[timew]' } +function _p9k_taskwarrior_check_meta() { + [[ -n $_p9k_taskwarrior_meta_sig ]] || return + [[ -z $^_p9k_taskwarrior_meta_non_files(#qN) ]] || return + local -a stat + if (( $#_p9k_taskwarrior_meta_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_meta_files 2>/dev/null || return + fi + [[ $_p9k_taskwarrior_meta_sig == ${(pj:\0:)stat}$'\0'$TASKRC$'\0'$TASKDATA ]] || return +} + +function _p9k_taskwarrior_init_meta() { + local last_sig=$_p9k_taskwarrior_meta_sig + { + local cfg + cfg="$(task show data.location /dev/null)" || return + local lines=(${(@M)${(f)cfg}:#data.location[[:space:]]##[^[:space:]]*}) + (( $#lines == 1 )) || return + local dir=${lines[1]##data.location[[:space:]]#} + : ${dir::=$~dir} # `task` can give us path with `~`` in it; expand it + + local -a stat files=(${TASKRC:-~/.taskrc}) + _p9k_taskwarrior_meta_files=($^files(N)) + _p9k_taskwarrior_meta_non_files=(${files:|_p9k_taskwarrior_meta_files}) + if (( $#_p9k_taskwarrior_meta_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_meta_files 2>/dev/null || stat=(-1) + fi + _p9k_taskwarrior_meta_sig=${(pj:\0:)stat}$'\0'$TASKRC$'\0'$TASKDATA + _p9k_taskwarrior_data_dir=$dir + } always { + if (( $? == 0 )); then + _p9k__state_dump_scheduled=1 + return + fi + [[ -n $last_sig ]] && _p9k__state_dump_scheduled=1 + _p9k_taskwarrior_meta_files=() + _p9k_taskwarrior_meta_non_files=() + _p9k_taskwarrior_meta_sig= + _p9k_taskwarrior_data_dir= + _p9k__taskwarrior_functional= + } +} + +function _p9k_taskwarrior_check_data() { + [[ -n $_p9k_taskwarrior_data_sig ]] || return + [[ -z $^_p9k_taskwarrior_data_non_files(#qN) ]] || return + local -a stat + if (( $#_p9k_taskwarrior_data_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_data_files 2>/dev/null || return + fi + [[ $_p9k_taskwarrior_data_sig == ${(pj:\0:)stat}$'\0'$TASKRC$'\0'$TASKDATA ]] || return +} + +function _p9k_taskwarrior_init_data() { + local -a stat files=($_p9k_taskwarrior_data_dir/{pending,completed}.data) + _p9k_taskwarrior_data_files=($^files(N)) + _p9k_taskwarrior_data_non_files=(${files:|_p9k_taskwarrior_data_files}) + if (( $#_p9k_taskwarrior_data_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_data_files 2>/dev/null || stat=(-1) + _p9k_taskwarrior_data_sig=${(pj:\0:)stat}$'\0' + else + _p9k_taskwarrior_data_sig= + fi + + _p9k_taskwarrior_data_files+=($_p9k_taskwarrior_meta_files) + _p9k_taskwarrior_data_non_files+=($_p9k_taskwarrior_meta_non_files) + _p9k_taskwarrior_data_sig+=$_p9k_taskwarrior_meta_sig + + local name val + for name in PENDING OVERDUE; do + val="$(task +$name count /dev/null)" || continue + [[ $val == <1-> ]] || continue + _p9k_taskwarrior_counters[$name]=$val + done + + _p9k__state_dump_scheduled=1 +} + +function prompt_taskwarrior() { + unset P9K_TASKWARRIOR_PENDING_COUNT P9K_TASKWARRIOR_OVERDUE_COUNT + if ! _p9k_taskwarrior_check_data; then + _p9k_taskwarrior_data_files=() + _p9k_taskwarrior_data_non_files=() + _p9k_taskwarrior_data_sig= + _p9k_taskwarrior_counters=() + _p9k_taskwarrior_check_meta || _p9k_taskwarrior_init_meta || return + _p9k_taskwarrior_init_data + fi + (( $#_p9k_taskwarrior_counters )) || return + local text c=$_p9k_taskwarrior_counters[OVERDUE] + if [[ -n $c ]]; then + typeset -g P9K_TASKWARRIOR_OVERDUE_COUNT=$c + text+="!$c" + fi + c=$_p9k_taskwarrior_counters[PENDING] + if [[ -n $c ]]; then + typeset -g P9K_TASKWARRIOR_PENDING_COUNT=$c + [[ -n $text ]] && text+='/' + text+=$c + fi + [[ -n $text ]] || return + _p9k_prompt_segment $0 6 $_p9k_color1 TASKWARRIOR_ICON 0 '' $text +} + +function _p9k_prompt_taskwarrior_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[task]:+$_p9k__taskwarrior_functional}' +} + prompt_wifi() { local -i len=$#_p9k__prompt _p9k__has_upglob _p9k_prompt_segment $0 green $_p9k_color1 WIFI_ICON 1 '$_p9k__wifi_on' '$P9K_WIFI_LAST_TX_RATE Mbps' @@ -5987,6 +6094,16 @@ typeset -g _p9k__param_pat typeset -g _p9k__param_sig _p9k_init_vars() { + typeset -ga _p9k_taskwarrior_meta_files + typeset -ga _p9k_taskwarrior_meta_non_files + typeset -g _p9k_taskwarrior_meta_sig + typeset -g _p9k_taskwarrior_data_dir + typeset -g _p9k__taskwarrior_functional=1 + typeset -ga _p9k_taskwarrior_data_files + typeset -ga _p9k_taskwarrior_data_non_files + typeset -g _p9k_taskwarrior_data_sig + typeset -gA _p9k_taskwarrior_counters + typeset -ga _p9k_asdf_meta_files typeset -ga _p9k_asdf_meta_non_files typeset -g _p9k_asdf_meta_sig @@ -7045,7 +7162,7 @@ _p9k_must_init() { [[ $sig == $_p9k__param_sig ]] && return 1 _p9k_deinit fi - _p9k__param_pat=$'v54\1'${ZSH_VERSION}$'\1'${ZSH_PATCHLEVEL}$'\1' + _p9k__param_pat=$'v55\1'${ZSH_VERSION}$'\1'${ZSH_PATCHLEVEL}$'\1' _p9k__param_pat+=$'${#parameters[(I)POWERLEVEL9K_*]}\1${(%):-%n%#}\1$GITSTATUS_LOG_LEVEL\1' _p9k__param_pat+=$'$GITSTATUS_ENABLE_LOGGING\1$GITSTATUS_DAEMON\1$GITSTATUS_NUM_THREADS\1' _p9k__param_pat+=$'$DEFAULT_USER\1${ZLE_RPROMPT_INDENT:-1}\1$P9K_SSH\1$__p9k_ksh_arrays'