From e213290fca56560d44786fd9b3d5ab852416dfd5 Mon Sep 17 00:00:00 2001 From: Oleg Utkin Date: Tue, 21 Feb 2023 01:02:14 -0800 Subject: [PATCH] fixup: EPOCHSECONDS requires zsh/datetime zsh module This revision loads the zsh/datetime during prompt setup, and ensures that empty strings are not passed to query parameters. Also relax the int requirements on query parameters that are Shell driven. --- cmd/goprompt/cmdQuery.go | 32 ++++++++------ plugin/zsh/prompt_asynczle_setup.zsh | 65 ++++++++++++++-------------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/cmd/goprompt/cmdQuery.go b/cmd/goprompt/cmdQuery.go index f27c842..584d405 100644 --- a/cmd/goprompt/cmdQuery.go +++ b/cmd/goprompt/cmdQuery.go @@ -8,6 +8,7 @@ import ( "os/signal" "os/user" "path/filepath" + "strconv" "strings" "syscall" "time" @@ -22,13 +23,13 @@ var ( Use: "query", Short: "start the query that pulls data for the prompt", } - flgQCmdStatus = cmdQuery.PersistentFlags().Int( - "cmd-status", 0, - "cmd status of previous command", + flgQCmdStatus = cmdQuery.PersistentFlags().String( + "cmd-status", "0", + "cmd status of previous command (int)", ) - flgQPreexecTS = cmdQuery.PersistentFlags().Int( - "preexec-ts", 0, - "pre-execution timestamp to gauge how log execution took", + flgQPreexecTS = cmdQuery.PersistentFlags().String( + "preexec-ts", "0", + "pre-execution timestamp to gauge how log execution took (int)", ) flgQTimeout = cmdQuery.PersistentFlags().Duration( "timeout", 0, @@ -164,8 +165,9 @@ func cmdQueryRun(_ *cobra.Command, _ []string) error { nowTS := time.Now() printPart(_partTimestamp, timeFMT(nowTS)) - if *flgQCmdStatus != 0 { - printPart(_partStatus, fmt.Sprintf("%#v", *flgQCmdStatus)) + prevCMDStatus := trim(*flgQCmdStatus) + if prevCMDStatus != "0" { + printPart(_partStatus, fmt.Sprintf("%s", prevCMDStatus)) } tasks.Go(func(ctx context.Context) error { @@ -188,12 +190,14 @@ func cmdQueryRun(_ *cobra.Command, _ []string) error { printPart(_partSessionHostname, sessionHostname) } - if *flgQPreexecTS != 0 { - cmdTS := time.Unix(int64(*flgQPreexecTS), 0) - - diff := nowTS.Sub(cmdTS).Round(time.Second) - if diff > 1 { - printPart(_partDuration, diff) + preexecTS := trim(*flgQPreexecTS) + if preexecTS != "0" { + if ts, err := strconv.Atoi(preexecTS); err == nil { + cmdTS := time.Unix(int64(ts), 0) + diff := nowTS.Sub(cmdTS).Round(time.Second) + if diff > 1 { + printPart(_partDuration, diff) + } } } diff --git a/plugin/zsh/prompt_asynczle_setup.zsh b/plugin/zsh/prompt_asynczle_setup.zsh index f280ab9..9ebda10 100755 --- a/plugin/zsh/prompt_asynczle_setup.zsh +++ b/plugin/zsh/prompt_asynczle_setup.zsh @@ -1,21 +1,18 @@ # In a file `prompt_asynczle_setup` available on `fpath` emulate -L zsh -typeset -g C_PROMPT_NEWLINE=$'\n%{\r%}' - -typeset -g G_LAST_STATUS=0 -typeset -g G_PREEXEC_TS=0 -typeset -g G_ASYNC_DONE=0 - -typeset -g G_PROMPT_DATA="" - -typeset -g G_LAST_PROMPT="" +typeset -g ZSH_ASYNC_PROMPT_TIMEOUT=${ZSH_ASYNC_PROMPT_TIMEOUT:-5s} +typeset -g ZSH_ASYNC_PROMPT_EXEC=${GOPROMPT} -declare -gA ZLE_ASYNC_FDS=() +typeset -g ZSH_ASYNC_PROMPT_DATA="" +typeset -g ZSH_ASYNC_PROMPT_LAST="" -typeset -g ZSH_ASYNC_PROMPT_TIMEOUT=${ZSH_ASYNC_PROMPT_TIMEOUT:-5s} +typeset -g ZSH_ASYNC_PROMPT_LAST_STATUS=0 +typeset -g ZSH_ASYNC_PROMPT_PREEXEC_TS=0 +typeset -g ZSH_ASYNC_PROMPT_QUERY_DONE=0 -typeset -g G_GOPROMPT=${GOPROMPT} +declare -gA __ZLE_ASYNC_FDS=() +typeset -g __ZSH_ASYNC_PROMPT_NEWLINE=$'\n%{\r%}' #------------------------------------------------------------------------------- @@ -31,20 +28,20 @@ __async_check_exec() { } __async_prompt_query() { - if ! __async_check_exec "${G_GOPROMPT}"; then + if ! __async_check_exec "${ZSH_ASYNC_PROMPT_EXEC}"; then echo -n "" return fi - ${G_GOPROMPT} query \ - --cmd-status "$G_LAST_STATUS" \ - --preexec-ts "$G_PREEXEC_TS" \ + ${ZSH_ASYNC_PROMPT_EXEC} query \ + --cmd-status "${ZSH_ASYNC_PROMPT_LAST_STATUS:-0}" \ + --preexec-ts "${ZSH_ASYNC_PROMPT_PREEXEC_TS:-0}" \ --pid-parent-skip 1 \ - --timeout "$ZSH_ASYNC_PROMPT_TIMEOUT" + --timeout "${ZSH_ASYNC_PROMPT_TIMEOUT:-5s}" } __async_prompt_render() { - if ! __async_check_exec "${G_GOPROMPT}"; then + if ! __async_check_exec "${ZSH_ASYNC_PROMPT_EXEC}"; then echo -n "?>" return fi @@ -55,11 +52,11 @@ __async_prompt_render() { fi local LOADING=1 - if [[ $G_ASYNC_DONE -eq 1 ]]; then + if [[ $ZSH_ASYNC_PROMPT_QUERY_DONE -eq 1 ]]; then LOADING=0 fi - ${G_GOPROMPT} render \ + ${ZSH_ASYNC_PROMPT_EXEC} render \ --prompt-mode "$MODE" \ --prompt-loading="$LOADING" \ --color-mode "zsh" @@ -68,15 +65,15 @@ __async_prompt_render() { #------------------------------------------------------------------------------- __prompt_rerender() { - local BR=$C_PROMPT_NEWLINE + local BR=$__ZSH_ASYNC_PROMPT_NEWLINE - PROMPT="$(printf "%s\n" "$G_PROMPT_DATA" | __async_prompt_render) " + PROMPT="$(printf "%s\n" "$ZSH_ASYNC_PROMPT_DATA" | __async_prompt_render) " - if [[ $PROMPT != $G_LAST_PROMPT ]]; then + if [[ $PROMPT != $ZSH_ASYNC_PROMPT_LAST ]]; then zle && zle reset-prompt fi - G_LAST_PROMPT="$PROMPT" + ZSH_ASYNC_PROMPT_LAST="$PROMPT" } #------------------------------------------------------------------------------- @@ -84,18 +81,18 @@ __prompt_rerender() { #------------------------------------------------------------------------------- __prompt_preexec() { - typeset -g G_PREEXEC_TS=$EPOCHSECONDS + typeset -g ZSH_ASYNC_PROMPT_PREEXEC_TS=$EPOCHSECONDS } __prompt_precmd() { # save the status of last command. - G_LAST_STATUS=$? + ZSH_ASYNC_PROMPT_LAST_STATUS=$? # reset prompt state - G_PROMPT_DATA="" + ZSH_ASYNC_PROMPT_DATA="" # set prompt status to rendering - G_ASYNC_DONE=0 + ZSH_ASYNC_PROMPT_QUERY_DONE=0 __zle_async_dispatch __zle_async_fd_handler __async_prompt_query @@ -116,15 +113,15 @@ __zle_async_fd_handler() { # select marks this fd if we reach EOF, # so handle this specially. __zle_async_detach "$ZLE_FD" - G_ASYNC_DONE=1 + ZSH_ASYNC_PROMPT_QUERY_DONE=1 - G_PROMPT_DATA="${G_PROMPT_DATA}"$'\n'"${ASYNC_RESULT}" + ZSH_ASYNC_PROMPT_DATA="${ZSH_ASYNC_PROMPT_DATA}"$'\n'"${ASYNC_RESULT}" __prompt_rerender return 1 fi - G_PROMPT_DATA="${G_PROMPT_DATA}"$'\n'"${ASYNC_RESULT}" + ZSH_ASYNC_PROMPT_DATA="${ZSH_ASYNC_PROMPT_DATA}"$'\n'"${ASYNC_RESULT}" if [[ $ASYNC_RESULT == "" ]]; then __prompt_rerender fi @@ -135,7 +132,7 @@ __zle_async_dispatch() { local command=( "$@" ) # Close existing file descriptor for this handler. - local OLD_ZLE_FD=${ZLE_ASYNC_FDS["${dispatch_handler}"]} + local OLD_ZLE_FD=${__ZLE_ASYNC_FDS["${dispatch_handler}"]} if [[ -n $OLD_ZLE_FD ]]; then __zle_async_detach "$OLD_ZLE_FD" 2>/dev/null fi @@ -147,7 +144,7 @@ __zle_async_dispatch() { # Attach file a ZLE handler to file descriptor. zle -F $ZLE_FD "${dispatch_handler}" - ZLE_ASYNC_FDS["${dispatch_handler}"]="$ZLE_FD" + __ZLE_ASYNC_FDS["${dispatch_handler}"]="$ZLE_FD" } __zle_async_detach() { @@ -162,6 +159,8 @@ __zle_async_detach() { #------------------------------------------------------------------------------- prompt_asynczle_setup() { + zmodload zsh/datetime || : + autoload -Uz +X add-zsh-hook 2>/dev/null autoload -Uz +X add-zle-hook-widget 2>/dev/null