romkatv / zsh-defer

Deferred execution of Zsh commands
GNU General Public License v3.0
343 stars 11 forks source link

zsh-defer in precmd_function breaks exiting from shell-out #15

Closed Mellbourn closed 5 months ago

Mellbourn commented 5 months ago

I have the following in my .zshrc:

set_p10k_branch_in_tmux() {
  zsh-defer -1sm -t 0.2 -c 'printf "\033]2;$VCS_STATUS_LOCAL_BRANCH\033\\"'
}
precmd_functions+=set_p10k_branch_in_tmux

The idea is to set the tmux title to the branch name of the current git repo. This works. In particular the above is superior to the following alternative, because the following will not report the branch correctly when first entering the repo, but rather on the second command in the repo.

set_p10k_branch_in_tmux() {
  printf "\033]2;$VCS_STATUS_LOCAL_BRANCH\033\\"
}
precmd_functions+=set_p10k_branch_in_tmux

However, I have found that the top script causes a problem in the following scenario: If I shell out of a program, e.g. if I in less do the command !zsh, then I correctly enter a subshell, but when I exit the subshell I am not returned to the original program, rather it results in:

❯ exit
[1]  + 11072 suspended (tty output)

At this point, I can (for some commands) use fg to return to the original command (e.g. less).

Is this a bug in zsh-defer, or is it just an inherent issue with my usage of zsh-defer?

Thanks for your great zsh tools!

Mellbourn commented 5 months ago

My current hacky workaround is to try to guess if I'm in a subshell or not, by checking SHLVL:

set_p10k_branch_in_tmux() {
  if [ "$SHLVL" -lt 4 ]; then
    zsh-defer -1sm -t 0.2 -c 'printf "\033]2;$VCS_STATUS_LOCAL_BRANCH\033\\"'
  fi
}
precmd_functions+=set_p10k_branch_in_tmux
romkatv commented 5 months ago

I don't know why the process gets suspended but I can tell you that there is no guarantee that VCS_STATUS_LOCAL_BRANCH is set when zle goes idle after precmd. Thus, this code is inherently incorrect and won't work if the machine is slow when you cd into a git repo.

You can try replacing your code with printf '\e]2;%s\e\\' $branch >$TTY within my_git_formatter. Put it on this line: https://github.com/romkatv/powerlevel10k/blob/178fcda3487afb3bd540d784cf472c60ec0de94a/config/p10k-lean.zsh#L388.

Mellbourn commented 5 months ago

I guess my machine is fast enough, because I've never noticed it not working.

Your suggestion does work to set the branch, but I can't figure out how to clear it when I'm not in a git repo.

I tried this (since printf '\e]0;\a' > $TTY clears the title if I run it on the command line), but it does not succeed in clearing the title.

    if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
      local branch=${(V)VCS_STATUS_LOCAL_BRANCH}
      # If local branch name is at most 70 characters long, show it in full.
      # Otherwise show the first 34 … the last 34.
      # Tip: To always show local branch name in full without truncation, delete the next line.
      (( $#branch > 70 )) && branch[35,-35]="…"  # <-- this line
      res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${branch//\%/%%}"
      printf '\e]2;%s\e\\' $branch >$TTY
    else
      printf '\e]0;\a' > $TTY
    fi
romkatv commented 5 months ago

I guess my machine is fast enough, because I've never noticed it not working.

I do hope you understand my point.

I can't figure out how to clear it when I'm not in a git repo.

You can clear it in precmd.

Mellbourn commented 5 months ago

You can clear it in precmd.

Thank you.

romkatv commented 5 months ago

You are welcome.