In my .bashrc file, when I colour the prompt, I use \[ ... \] to prevent new bash lines overwriting previous ones (also prevent writing buffer overflow/underflow or cases when text being typed in random locations). This only happens when using colours. In my .bashrc file I have:
WHITE="\[$(tty -s && tput setaf 254)\]";
PS1+="${WHITE} # "
But \[ escapes don't work on zsh in .zshrc
How can I fix this please?
The zsh equivalent is %{ ... %}. However, it's not needed as frequently because zsh has a much richer set of prompt escapes that eliminate the need to use raw escape sequences. For example, the %F escape lets you select a foreground color by name or number. zsh already knows how to query your terminal for the exact bytes to use, and zsh also knows that those bytes should not count towards the width of the prompt.
PS1+="%F{white} # "
or
PS1+="%F{254} # "
Related
When I use my terminal (iTerm 2 Mac) with my PS1 set to "\[\e[38;5;117m\W \e[39;38;5;104m\$\e[39;0m\] " and I use the arrow keys to go through my bash history it sometimes changes my prompt from ~ $ to just the first character of it and whatever command I'm looking at. For example, going to rvim .bashrc from randomDir $ ls. This problem also persists in the default terminal app.
\W and \$ should not go inside the \[...\], since bash will know how much space each takes up on the terminal.
PS1="\[\e[38;5;117m\]\W \[\e[39;38;5;104m\]\$\[\e[39;0m\] "
Only the characters that make up the ANSI escape sequence (which only instruct the terminal to change colors, without displaying a single additional character) are enclosed in \[...\].
Putting them inside \[...\] tells bash to ignore their contribution to the length of the prompt, leading to incorrect redraws.
This question already has answers here:
Custom Bash prompt is overwriting itself
(3 answers)
Closed 6 years ago.
I want to set my PS1 prompt to the output from a function, but when I try to include ansi color sequences, bash will think the line length is longer than it actually is and mess up when you type enough after it to go to a new line. Here's what the code looks like:
ps1() {
echo -ne "\033[01;34m$(dirs -0)\033[0m \$ "
}
PS1='$(ps1)'
Put \[ and \] around escape sequences. This tells the shell not to count them when determining the width of the prompt.
ps1() {
echo -ne "\\[\033[01;34m\\]$(dirs -0)\\[\033[0m\\] \$ "
}
See Bash Prompt Escape Sequences for all the special sequences you can use in the prompt (e.g. you can use \e instead of \033 for Escape, and \w for the current directory instead of $(dirs -0)).
You need to double the backslashes in these sequences to keep them from being eaten by echo -e. But if you just use the escape sequences listed at the above page, you don't really need -e, since bash will process the escape sequences in PS1 itself.
I have written a small program that emits a command line prompt with some Git info. I use ANSI escape sequences to color it, and it looks something like this:
However, whenever I do tab completion or a search, zsh inserts several spaces after the prompt:
It seems to be inserting a space for each escape code character emitted by the prompt, since removing the color codes eliminates this behavior. Why is zsh doing so, and how can I stop this?
The actual character sequence emitted by my prompt program for this example is (assuming \e represents character 033)
~/s/promptd [\e[36mmaster \e[33m±\e[31m?\e[39m]
The relevant portion of my .zshrc is:
setopt PROMPT_SUBST
setopt PROMPT_PERCENT
PROMPT='%B$(promptd) %%%b '
After doing some additional research, the ZSH Prompt Expansion docs indicate that escape literals need to be enclosed in %{...%}.
This is bothersome since now I have to output those conditionally if I want the prompt program to work in other shells, but it seems to correct the behavior shown above.
Newbie question, I recently changed my PS1 into this:
RESET="\[\017\]"
NORMAL="\[\033[0m\]"
YELLOW="\[\033[0;33m\]"
CYAN="\[\033[0;36m\]"
export PS1="\[$RESET\]\u#\h:\[$CYAN\]\w\[$YELLOW\]\$(__git_ps1)\[$NORMAL\] \$ "
But now I get a line wrapping error. I created a gif to explain the problem:
Any ideas what might be wrong?
I think you're double-quoting your escape codes with [ and ]. Try this one:
export PS1="$RESET\u#\h:$CYAN\w$YELLOW\$(__git_ps1)$NORMAL \$ "
The wrapping error occurs whenever a non-printing character is not escaped (such as the escape codes that change the prompt color). It also occurs when the locale is set to something that does not understand unicode characters and the prompt includes them. An example would be non-breaking spaces. When the locale is "C" and there are unicode characters in the prompt, the shell thinks more characters are being printed than truly are, and the prompt wraps around prematurely.
shopt -s checkwinsize this should fix your problem.
This will set the variable checkwinsize on. This is set by default in /etc/bashrc however since you're using your custom .bashrc file you can put this code in there or in your .bashrc file load the /etc/bashrc by adding . /etc/bashrc at the top of your .bashrc file.
If I set my command prompt like:
export PS1='\033[0;33m[\u#\h \w]\$ \033[00m'
The color of the prompt will be yellow and everything after the '$' character will
be the default terminal color. This is what I expect. However, If I recall a command line and attempt to edit it, moving the cursor -- either UpArrow/Ctrl-A (set -o emacs) or ESC K (set -o vi)
if the command line I'm trying to edit is long enough, the cursor is not positioned at the beginning of the command. Typing either Ctrl-A (set -o emacs) or ^ (set -o vi) will not move the cursor to what I'm seeing as the beginning of the recalled line on the screen. Similarly, attempting to position the cursor to the end of the line (Ctrl-E or $, depending) results in it being placed several characters past what appears to be the end of the line.
It looks like bash is getting confused by the escape characters I've added to the prompt.
Is this just something I'll have to deal with, changing my prompt to a monochromatic one when I wish to edit recalled lines, or is there a way to get bash to correctly allow the editing of recalled commands with a colorful prompt?
You need to enclose the non-printing characters in \[ ... \] so that bash knows to ignore them when computing the length of the prompt:
export PS1='\[\033[0;33m\][\u#\h \w]\$ \[\033[00m\]'