romkatv / powerlevel10k

A Zsh theme
MIT License
44.9k stars 2.13k forks source link

Show kubecontext on line 1 in active prompt, and line 2 in transient prompt #1263

Closed BMouser closed 3 years ago

BMouser commented 3 years ago

I've only just started using p10k in the last week and so far am quite happy with the tool. I was curious though if there was a better way to have a kubecontext that behaves as the picture below:

image

The key pieces from that picture are:

  1. If the active command has a "kube" command the context is added to line one of the prompt
  2. If a past command has a "kube" command the transient prompt shows the context on the single line summary

So far I have been able to do this by using the API described in https://github.com/romkatv/powerlevel10k/issues/318#issuecomment-573445060 as well as forking the powerlevel10k project and copying the built-in kubecontext prompt (https://github.com/BMouser/powerlevel10k/commit/6af165b2b47b76096db0af57445d2bd397418677 Note: that this is not at all a pull request. I do not believe my duplication should be made to the main project). With this setup I ended up with a p10k config similar to:

...
  typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
    # =========================[ Line #1 ]=========================
    # os_icon               # os identifier
    dir                     # current directory
    vcs                     # git status
    kubecontext             # current kubernetes context (https://kubernetes.io/)
    # =========================[ Line #2 ]=========================
    newline                 # \n
    time
    transient_kubecontext
    prompt_char             # prompt symbol
  )
...
# Other config in here that isn't important
typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito|k9s|helmfile'
typeset -g POWERLEVEL9K_TRANSIENT_KUBECONTEXT_SHOW_ON_COMMAND=''

# Other config items for POWERLEVEL9K_KUBECONTEXT_* are duplicated to POWERLEVEL9K_TRANSIENT_KUBECONTEXT_*
...

  typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off

  function p10k-on-pre-prompt() {
    p10k display '1'=show '2/left/time'=hide '2/right/*'=show
  }

  function p10k-on-post-prompt() {
    local z=$'\0' display_line_1=false
    if [[ ! $PWD == $my_last_dir ]]; then
      my_last_dir=$PWD
      display_line_1=true
    fi

    p10k display '2/left/time'=show

    # I want the transient prompt's context to match the on_show_command of the main kubecontext config.
    if (( $P9K_COMMANDS[(I)(|*[/$z])(${POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND})] )); then
      p10k display '2/left/transient_kubecontext'=show
    fi

    if ! $display_line_1 ; then
      p10k display '1'=hide
    fi
  }
...

What I have "works" but isn't exactly elegant and I was curious if I had another option. I did see the original gist you created https://gist.github.com/romkatv/33f02f42245967072f8d00fc1db0f7fc but had wanted to try and keep the main and transient prompt configuration as similar as possible to avoid oddities.

Edit: I realized the picture had the same-dir like behavior so added that config back to my p10k-on-post-prompt to avoid potential confusion.

romkatv commented 3 years ago

This should work:

POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
  dir vcs kubecontext newline
  time kubecontext prompt_char
)

POWERLEVEL9K_TRANSIENT_PROMPT=off

function p10k-on-pre-prompt() {
  p10k display '(1|/right/*)'=show '2/left/time'=hide
}

function p10k-on-post-prompt() {
  local -a reply
  p10k display -a '1/left/kubecontext'
  p10k display '(1|/right/*)'=hide '2/left/time'=show '2/left/kubecontext'=$reply[2]
}

function p10k-on-post-widget() {
  p10k display '2/left/kubecontext'=hide
}

p10k-on-post-widget hides kubecontext on the second prompt line so that you never have two instances displayed at once. p10k-on-post-prompt copies the display status from kubecontext on the first line to the one on the second.

BMouser commented 3 years ago

Thanks Roman for the response. I had tried something similar but was misusing the reply array API. I'll incorporate this into my config.