I just made the switch to Zsh, but I'm facing a weird problem with it: every time I hit the tab key, the prompt goes up a line, thus eating what was above.
In order to demonstrate the problem more clearly, I created a GIF:
I'm using a custom theme and Oh My Zsh. You can find the theme here: http://pastebin.com/12dZtZf3.
EDIT: The problem seems to reside in my theme, as using other themes solves the problem.
EDIT: The culprit seems to be in the function that prints the row of dashes and the date above the prompt:
_professional_prompt_header() {
echo -n "$bg[grey]"
for i in {0..$(( $(tput cols) / 2 - 6 ))}; do
echo -n "--"
done
# Uncommenting this line fixes the problem.
# Tried echo without -n and print, but no success.
echo -n " %*$reset_color"
}
This has also emerged as an issue with multiline prompts in the release of zsh 5.3. As of 2017-01-13, a patch has not been released. A discussion and explanation can be found in this prezto issue.
More discussion of the offending zsh issue itself can be found here.
Hopefully a fix will emerge from the zsh project. If not, some workarounds mentioned on that github repo are to make your PROMPT variable only a single line, outputting any other lines in the precmd function. This seems like a pain, however, so until it is fixed (or decided to be a "feature"), the easiest fix sounds like it is to roll back to zsh 5.2.
Related
I use zsh and I would like backward-kill-word in Emacs mode to behave like Emacs (and bash, fwiw). The behaviour that I have failed to reproduce is that when I press multiple backward-kill-word Emacs adds the killed text to the cut buffer (the first item in the killring) making it possible for me to yank everything with one yank command.
How can I configure zsh to behave like this aspect of Emacs editors?
Actually, by default, Zsh's cut buffer works exactly the same as in Emacs. Just use zsh -f to start Zsh without config files and try it.
However, are you perhaps using zsh-autosuggestions or zsh-syntax-highlighting? There are bugs in these plugins that break this feature:
https://github.com/zsh-users/zsh-autosuggestions/issues/363
https://github.com/zsh-users/zsh-syntax-highlighting/issues/150#issuecomment-658381485
Fixes have been submitted, but for zsh-autosuggestions, none have yet been merged, and for zsh-syntax-highlighting, the fix won't work until Zsh 5.9 has been released.
In the meantime, though, zsh-autocomplete contains a workaround that fixes the problem. If you add that plugin, your cut buffer will start functioning like normal again.
I'm confused what data is being shown in my terminal tabs. The first part, epzio is obviously my username. But the second part, #C02S60BBG8WP, I have no idea.
Note: I use zsh combined with oh-my-zsh for my shell.
Is it possible to customize what is shown in the tab titles? I'd like to remove the epzio#C02S60BBG8WP part altogether and just display the current working directory.
Also, why do my tab titles turn blue for no apparent reason? I thought this was only supposed to happen when you had a specific process such as node running. As you can see in the screenshot below, the tic-tac-toe tab has turned blue even though nothing is happening in that tab.
Update: It seems that the solution might involve making changes to ~/.oh-my-zsh/lib/termsupport.zsh, but I'm not sure if these would get overridden when oh-my-zsh updates itself.
C02S60BBG8WP is probably your hostname; check by typing hostname.
You can change the terminal title by printing an escape sequence like this:
echo -en "\033]0;New terminal title\a"
So this should change the title to your current working directory, $PWD, substituted by a single ~ if you're in $HOME:
echo -en "\033]0;${PWD/#$HOME/~}\007"
If that doesn't work, it's probably being overridden immediately afterwards by a command that is automatically invoked by your shell. In bash, this would be PROMPT_COMMAND which on my system looks like this:
$ echo $PROMPT_COMMAND
__vte_prompt_command; printf "\033]0;%s#%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"
The zsh equivalent seems to be to define a precmd hook:
precmd() { echo -en "\033]0;${PWD/#$HOME/~}\007" }
To make that permanent, you can just put it your .zshrc.
Problem steps like this:
copy text 'kill-server' to system clipboard
hit Prefix : to enter the tmux command prompt
hit command+v to paste
The result paste text is 200~kill-server201~ instead of kill-server. This weird bracketed paste mode text do not happen in shell prompt but in tmux command prompt, and I had tried to turn off bracketed paste mode but without luck.
Environment that has this issue:
Mac OS 10.11.1, iTerm, zsh 5.0.7, Tmux 2.1
Mac OS 10.10.1, iTerm, zsh 5.1.1, Tmux 1.9
Environment that without this issue:
Mac OS 10.11.1, iTerm, bash, Tmux 2.1
I'm posting this as an answer because it's a bit too long and I need some formatting... So here it goes.
I can reproduce only with zsh 5.1+. There's no reason to expect the problem on 5.0.x, because bracketed paste mode was introduced in 5.1. You might be doing something wrong in your testing, or there might be something peculiar about your setup, in which case you have to explain better. Also, iTerm2 probably doesn't play any part in this, since I could reproduce in Terminal.app just fine (of course they could both have the same defect...).
Considering bracketed paste mode is a ZLE feature, I think (disclaimer: the rest of this paragraph is purely my speculation) the real problem is that tmux uses the underlying shell's line editing features (ZLE, in zsh's case) in its command prompt to offer better editing experience (for instance, you have access to all the Emacs style shortcuts there), but its command prompt is a dumb term, and doesn't understand the bracketed paste sequences. So we have this weird situation of two modes of terminal emulation within tmux, one is fairly smart which happens within each pane, and the other is dumb which happens in its command prompt.
Solutions and workarounds:
This is probably worth reporting to tmux. https://github.com/tmux/tmux/issues.
Turn off ZLE bracketed paste. It does work, you're probably doing it wrong. If you don't mind losing bracketed paste in tmux, you could put the following somewhere in your shell init sequence:
(( $+TMUX )) && unset zle_bracketed_paste
In iTerm2, you have access to advanced paste (Edit->Paste Special->Advanced Paste..., or ⌥⌘V). Just uncheck "Bracketed paste mode", and you shouldn't see the escape sequences.
I solved this problem finally just deactivated the safe-paste plugin in my oh-my-zsh.
The safe-paste used to fix zsh up arrow completion issue. But now, the arrow completion issue is gone while inducing tmux bracketed paste problem. I haven't dived into the code of safe-paste yet. Hope to help others encountering the same problem.
How would I hide the computer name in the prompt while using the terminal?
At the moment it shows both username and computer name like so:
It would save some space by removing anwarchoukah#anwars-mbp, seeing as I actually know who I am:)
Try to add export DEFAULT_USER=$USER to your .zshrc file
On MacOS 10.15 Catalina:
Open the file /private/etc/zshrc in a text editor
Locate the comment: # Default prompt
Modify the line that looks like this: PS1="%n#%m~ %& # "
Save the file. You will be prompted to enter a password to save it.
Load a new Terminal window.
For example, you can:
Remove "%n#%m" to get rid of both the username and computer name
Remove "%n" to get rid of the user name
Remove "%m" to get rid of the machine name
step 1. one your .zshrc file by vim .zshrc
step 2. go to end of your file.
Paste this code:
careful indent again your code
prompt_context() {
if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
prompt_segment black default "%(!.%{%F{yellow}%}.)$USER"
fi
}
EDIT - explaining what this does
This will remove the machine#user name from the prompt IF:
- you are not logged in as the default user
- you are not in an ssh client shell
For most people, not needed, but if you regularly ssh to other machines and have multiple terminals open (eg remote sys admin type work) then this is extremely useful so when you look at your terminal you know which machine and user you are logged in as inside that terminal.
If you don't need/manage that type of complexity then use one of the other answers to just modify your export PROMPT/PS1 value.
* WARNING *
If you are using a custom shell or theme, this might not work and although the prompt will no longer show your computer and username it will keep throwing the error:
prompt_context:2: command not found: prompt_segment
For example, you can see with this (very popular) powerlevel9k it does not work. This is because the Powerlevel9k theme uses it's own magic and you simply add commands to your ~/.zshrc file to get the same result, eg:
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context)
More info on that here.
Open up .zshrc, find the line reading export PS1 or maybe export PROMPT.
Remove the variable that is used for the hostname, could be %m or %M.
Zsh on Archlinux wiki
You can use colors and also have a prompt (or some information) on the right side.
I like this approach (on my mac)
put in .zshrc
PS1="%n$ "
The terminal will look like
username$
Just add prompt_context() {} to .zshrc
Unfortunately none of the .zshrc changes worked for me.
Machine : Mac M1, Big Sur 11.4
So this is what worked.
I Navigated to where the ZSH themes were installed, opened my theme, agnoster in TextEdit, and modified the configuration where it chooses what do display, which by default is $username#%m.
Note : %m here is the machine name.
Here is a screenshot of delta. Yellow is what I did, Green is the default setting from github version of agnoster theme.
Voila this worked. Now to me it just displays the machine name, as I intended.
Hope that helps. Many links and SOF posts only made me click that solution.
Set DEFAULT_USER in ~/.zshrc file to your regular username. You can get your exact username value by executing whoami in the terminal.
Something like this:
export DEFAULT_USER=username
If you are using PowerLevel9k theme, there is a variable POWERLEVEL9K_CONTEXT_TEMPLATE that can change the view of your hostname and computer name.
The default option is %n#%m,
%n -> username
%m -> machine name
to hide hostname:
Open the .zshrc file using sudo nano ~/.zshrc
Add the line
POWERLEVEL9K_CONTEXT_TEMPLATE="%n" at the end of .zshrc file
Save the file.
Maybe this will help you [ Open Profile => Shell ]
PS1="~ $: ";clear;
Just add this to your ~/.zshrc file:
export DEFAULT_USER=\`whoami`
Install Oh My Zsh is the easiest solution for me:
https://ohmyz.sh/
One liner install:
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Result:
If you're using Powerlevel10k, then you can run p10k configure and configure the output a bit.
My username and computer-name was gone after having gone through it. It feel less hacky, than the other solutions here.
I don't know why I can't find a simplified solution.
So here is the simplified one.
Just jump into the themes directory,
# ~/.oh-my-zsh/themes
Select the theme, as I have been using
# vim agnoster.zsh-theme
Just remove %m to remove and also you can remove the username too.
Once done,
Just run
#zsh
To reflect the changes, Enjoy :)
Thanks to Wes Bos' amazing video series Command Line Power User , I managed to find the answer.. It's pretty simple. Stuff like that is set in the ZSH theme.
Open up .zshrc, change the theme from ZSH_THEME="agnoster" (which is what I was using) to something else.
Wes Bos has made a lovely theme called Cobalt2 which does exactly what I was looking for :)
I've now changed it to ZSH_THEME="cobalt2"
I know that I can exec a date command in my zsh prompt.
However, it shows the old time; to see the current time, I have to hit <return> and get a new prompt with the current time.
Is there a way to configure the zsh prompt to constantly update itself every second?
Note: I wrote this answer for a similar question, but seeing how this question has more views I think reposting my answer here would be useful.
This is in fact possible without resorting to strange hacks. I've got this in my .zshrc
RPROMPT='[%D{%L:%M:%S %p}]'
TMOUT=1
TRAPALRM() {
zle reset-prompt
}
The TRAPALRM function gets called every TMOUT seconds (in this case 1), and here it performs a prompt refresh, and does so until a command starts execution (and it doesn't interfere with anything you type on the prompt before hitting enter).
Source: http://www.zsh.org/mla/users/2007/msg00944.html (It's from 2007!)
Sounds like a pleasant request to me. If anything it makes more sense than showing the time when the prompt was displayed.
Fortunately Peter Stephenson posted a technique. Try something like this in .zshrc:
PROMPT="[%T] %n#%M %~ %# "
schedprompt() {
emulate -L zsh
zmodload -i zsh/sched
# Remove existing event, so that multiple calls to
# "schedprompt" work OK. (You could put one in precmd to push
# the timer 30 seconds into the future, for example.)
integer i=${"${(#)zsh_scheduled_events#*:*:}"[(I)schedprompt]}
(( i )) && sched -$i
# Test that zle is running before calling the widget (recommended
# to avoid error messages).
# Otherwise it updates on entry to zle, so there's no loss.
zle && zle reset-prompt
# This ensures we're not too far off the start of the minute
sched +30 schedprompt
}
schedprompt
This would be .... unpleasant in a standard zsh prompt (or bash, or other shells).
I suggest you'd be better off using Gnu Screen.
Screen can have a status line which can show the time.
Here's an example screenrc scroll down to "Red Hat Magazine A guide to GNU Screen" to see the sample (i'll reproduce that here) which will, when screen is run, show the current time in the lower right corner of the terminal:
~/.screenrc
hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B}%Y-%m-%d %{W}%c %{g}]'
# Default screens
screen -t shell1 0
screen -t shell2 1
http://www.gnu.org/software/screen/