0

From this post, Get Function Into PS1 (Zsh)? , it seems to be possible to execute a function inside a ZSH prompt`.

Here how to use a function into PROMPT :

setopt PROMPT_SUBST
slash_color () { dirs | awk -F "/" ' {for (i=1; i<=NF; i++) printf "\033[38;5;75m"$i"\033[38;5;206m/"} '; }

PS1='%F{13}|%F{green}%n@%F{cyan}%m%F{13}|%f%T%F{13}|$(slash_color)%F{13}|%F{7} '

Below the result :

Prompt result

ISSUE : But now, I am faced to another problem : when I am inside a directory, the first completion with TAB, for example "vim" ⇨Tab shift all the display to roughly one hundred of space characters to the right.

To illustrate, here is a screen capture :

vim tab screen capture

As you can see, just after typing vim te and after press ⇨Tab key, the command vim te is pushed to the right: I don't understand where this shifting could come from.

I am using zsh-5.8 from MacPorts and I also could reproduce the issue by compiling the sources of zsh-5.8 on macOS Catalina.

If someone could have an explanation/suggestion/clue, this would be fine to tell it.

PS: I suspect that using a simple ZSH environment variable could fix this strange behavior.

I have done some research and find these 2 interesting links :

It seems the shifting that occurs in my case is caused by the interpretation of ANSI escape characters but I didn't understand all the details.

However, i tried to modify slash_color() function like this :

slash_color () {
dirs | awk -F "/" '{ blue="\e[38;5;75m"; \
                     pink="\e[38;5;206m"; \
                     for (i=1; i<NF; i++) \
                       printf blue $i pink "/"; \
                     printf blue $NF pink; \
                     printf "\n"
                   }'
}

But this doesn't work, I get the following error about awk:

awk: cmd. line:1: warning: escape sequence `\e' treated as plain `e'

In my original issue (shifting to the right), everything happens like ZSH was badly computing the length of the real visible PATH of PROMPT and overestimating it? That would explain why I am shifted to the right.

Could anyone take a look please at the two links that I gave above, it could contain the solution in my case.

UPDATE 1: @Allan, here you can see my last attempt :

# Prompt for zsh : path separated by %F{13} slash to better see where we are
setopt PROMPT_SUBST

slash_color() {
dirs | awk -F "/" '{ blue="\033[38;5;75m"; \
                     pink="\033[38;5;206m"; \
                     for (i=1; i<NF; i++) \
                      printf blue $i pink "/"; \
                     printf blue $NF pink; \
                     printf "\n";
                   }';
}

# Last method using my_precmd_hook_function
my_precmd_hook_function() {
  slash_path=$(slash_color)
}

autoload -U add-zsh-hook
add-zsh-hook precmd my_precmd_hook_function

PROMPT='%F{13}|%F{green}%n@%F{cyan}%m%F{13}|%f%T%F{13}|''$slash_path''%F{13}|%F{7} '

Rendering of PATH with pink forward slash is good but the issue of shifting to the right remains when I type cd+⇨Tab or ls+⇨Tab. The presence of printf "\n"; doesn't change anything on the result.

Below a capture illustrating this :

shifting to the right

SOLUTION FINALLY FOUND : my perseverance has paid off, everyting is working fine, no more shifting and colorized forward slash in PATH, with :

# Prompt for zsh : path separated by %F{13} slash to better see where we are
setopt PROMPT_SUBST

# Path with colorized forward slash
slash_color() {
dirs | awk -F "/" '{ blue="%{\033[38;5;75m%}"; \
                     pink="%{\033[38;5;206m%}"; \
                     for (i=1; i<NF; i++) \
                      printf blue $i pink "/"; \
                     printf blue $NF pink; \
                   }';
}

# Prompt final
PROMPT=$'%F{13}|%F{green}%n@%F{cyan}%m%F{13}|%f%T%F{13}|$(slash_color)%F{13}|%F{7} '

# Zsh reverse auto-completion
bindkey '^[[Z' reverse-menu-complete

Thanks a lot for all your advices.

  • If you get Down votes, consider making all your troubleshooting an answer - even partial answers and wrong answers get upvotes and help people learn. Then the question can be shortened to a sentence or two describing the problem clearly. Those also tend to get upvotes and traction. – bmike Apr 19 '20 at 12:42
  • 1
    apple.stackexchange.com/questions/383297/… is about zsh 5.7.1, the answer described that the problem doesn't occur in 5.8. So I'm not sure why you consider it relevant. – nohillside Apr 19 '20 at 13:45
  • @nohillside I suspect that the function slash_color () puts the mess in the display of the prompt, especially, non visible characters like ANSI escape codes seem to be added to the prompt when I try to do a TAB completion and all command cd foo/ is shifted on the right. This issue occurs both on zsh-5.7.1 and zsh-5.8. – youpilat13 Apr 19 '20 at 14:35
  • So apple.stackexchange.com/questions/383297/… doesn't apply, right? :-) Look, on the one hand it's great that you doing research on this and documenting the results, on the other hand it makes the question hard to read and understand (so most people will just ignore it). So please focus the question on the actual problem at hand to get more attention. – nohillside Apr 19 '20 at 14:51
  • @nohillside your link talks about another issue, when one character of command is removed. In this case, zsh-5.8 fixes it, but here in this post, this is another problem. – youpilat13 Apr 19 '20 at 15:27
1

To be candid, I think your making this prompt overly complex and attempting to introduce additional, complex "layers" to what's supposed to be a simple prompt is having unforeseen and unpredictable issues.

In my previous answer to your related question, which what you based your slash_color function on, I cautioned against this from a usability standpoint. In the comments, I mentioned that I wasn't amenable to putting a function within a prompt for security reasons.

Ok...disclaimers are out of the way.


My first observation is that you have a newline character being generated by awk.

slash_color code

So, in your prompt, you're telling it to output a new line in something that's supposed to be contained to a single line. I don't now how PROMPT handles things within ZSH, but I doubt it handles new line chars very well.

Secondly, you seem to be mixing up all the different things that ZSH, awk, and functions in general have to deal with. I'm still a bit foggy as to the actual logic here, but it seems like you're trying to push "normal" escape codes through two layers of functions within ZSH by using their color conventions and ZSH's loadable modules.

Could anyone take a look please at the 2 links that I gave above, it could contain the solution in my case?

Why? What in those links lead you to believe that? The first link is about variable expansion within the prompt. The second show you how to colorize your prompt using both escape sequences and the preferred braces method in ZSH.

I believe the issue is the over-complexity.

You're shoehorning a function that not only has the ANSI escape codes, which are supported, but calling another function that creates a pipe, which means it creates a sub shell to call yet another function! (This is what I was referring to re: layers and complexity).

This is why I suggested using precmd(). Not only can you nest functions, but you can call multiple functions and then generate your prompt. I advise you to explore that more and not fixate on PROMPT being the sole method to skin this cat.

My other piece of advice is to articulate what you'd ultimately like to accomplish and post that as a new question because there's probably a solution you're not aware of. IMO, this sounds like an XY Problem

  • Sorry to be boring with my attempt which is tricky, I must admit it. So I am going to follow your advice and explore the precmd() world. zsh can be quickly a monster at level of options and possible configurations, that's why my old bash configuration is simple compared to zsh (I don't say that bash is basic itself). I will add an update as soon as possible to keep interacting with you. Thanks – youpilat13 Apr 19 '20 at 21:41
  • Solution finally found as you can see after my UPDATE1. Thanks a lot ! – youpilat13 Apr 20 '20 at 6:28
0

SOLUTION FINALLY FOUND : my perseverance has paid off, everyting is working fine, no more shifting and colorized forward slash in PATH, with :

# Prompt for zsh : path separated by %F{13} slash to better see where we are
setopt PROMPT_SUBST

# Path with colorized forward slash
slash_color() {
dirs | awk -F "/" '{ blue="%{\033[38;5;75m%}"; \
                     pink="%{\033[38;5;206m%}"; \
                     for (i=1; i<NF; i++) \
                      printf blue $i pink "/"; \
                     printf blue $NF pink; \
                   }';
}

# Prompt final
PROMPT=$'%F{13}|%F{green}%n@%F{cyan}%m%F{13}|%f%T%F{13}|$(slash_color)%F{13}|%F{7} '

# Zsh reverse auto-completion
bindkey '^[[Z' reverse-menu-complete

Thanks a lot for all your advices.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .