Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# Luke's config for the Zoomer Shell
# Enable colors and change prompt:
autoload -U colors && colors
PS1="%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[magenta]%}%~%{$fg[red]%}]%{$reset_color%}$%b "
# History in cache directory:
HISTSIZE=10000
SAVEHIST=10000
HISTFILE=~/.cache/zsh/history
# Basic auto/tab complete:
autoload -U compinit
zstyle ':completion:*' menu select
zmodload zsh/complist
compinit
_comp_options+=(globdots) # Include hidden files.
# vi mode
bindkey -v
export KEYTIMEOUT=1
# Use vim keys in tab complete menu:
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -v '^?' backward-delete-char
# Change cursor shape for different vi modes.
function zle-keymap-select {
if [[ ${KEYMAP} == vicmd ]] ||
[[ $1 = 'block' ]]; then
echo -ne '\e[1 q'
elif [[ ${KEYMAP} == main ]] ||
[[ ${KEYMAP} == viins ]] ||
[[ ${KEYMAP} = '' ]] ||
[[ $1 = 'beam' ]]; then
echo -ne '\e[5 q'
fi
}
zle -N zle-keymap-select
zle-line-init() {
zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere)
echo -ne "\e[5 q"
}
zle -N zle-line-init
echo -ne '\e[5 q' # Use beam shape cursor on startup.
preexec() { echo -ne '\e[5 q' ;} # Use beam shape cursor for each new prompt.
# Use lf to switch directories and bind it to ctrl-o
lfcd () {
tmp="$(mktemp)"
lf -last-dir-path="$tmp" "$@"
if [ -f "$tmp" ]; then
dir="$(cat "$tmp")"
rm -f "$tmp"
[ -d "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir"
fi
}
bindkey -s '^o' 'lfcd\n'
# Edit line in vim with ctrl-e:
autoload edit-command-line; zle -N edit-command-line
bindkey '^e' edit-command-line
# Load aliases and shortcuts if existent.
[ -f "$HOME/.config/shortcutrc" ] && source "$HOME/.config/shortcutrc"
[ -f "$HOME/.config/aliasrc" ] && source "$HOME/.config/aliasrc"
# Load zsh-syntax-highlighting; should be last.
source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh 2>/dev/null
@aquaductape

This comment has been minimized.

Copy link

@aquaductape aquaductape commented Sep 22, 2019

In my fork I found bracket surround i.e. deleting stuff in parenthesis.

@impulse

This comment has been minimized.

Copy link

@impulse impulse commented Sep 23, 2019

@sharethewisdom

This comment has been minimized.

Copy link

@sharethewisdom sharethewisdom commented Sep 23, 2019

turn CTRL+z into a toggle switch

ctrlz() {
  if [[ $#BUFFER == 0 ]]; then
    fg >/dev/null 2>&1 && zle redisplay
  else
    zle push-input
  fi
}
zle -N ctrlz
bindkey '^Z' ctrlz
@yochem

This comment has been minimized.

Copy link

@yochem yochem commented Sep 23, 2019

Is it possible to have the beam shape cursor without blinking? I tried changing \e[5 q to \e[0 q (this turns off blinking according to the ascii table), but that doesn't seem to work.

@flamendless

This comment has been minimized.

Copy link

@flamendless flamendless commented Sep 23, 2019

How about displaying the current mode in the prompt?

@JasoonS

This comment has been minimized.

Copy link

@JasoonS JasoonS commented Sep 24, 2019

@pypaut

This comment has been minimized.

Copy link

@pypaut pypaut commented Sep 30, 2019

Greetings, loving the vi-mode in terminal. Any way to change prompt in Vim the same way as you configured in the command line? I found that Nvim does this well, but would still like to configure this in Vim.

@rod-stuchi

This comment has been minimized.

Copy link

@rod-stuchi rod-stuchi commented Oct 19, 2019

Binding to ctrl in bindkey -M menuselect '^h' vi-backward-char you still can typing.

@Arjentix

This comment has been minimized.

Copy link

@Arjentix Arjentix commented Nov 4, 2019

After apllying this settings for vi-mode I've got a beam cursor in all mods in my vim. How can I fix it?

@okapia

This comment has been minimized.

Copy link

@okapia okapia commented Nov 10, 2019

The KEYTIMEOUT=1 recommendation for vi mode is out-of-date. There were some changes made around the 5.1/5.2 release period for how key prefixes are handled that solved the issue for the most part. It's still a good idea to reduce it to around 5 from the default of 20. 20 was necessary a couple of decades ago on slower terminals. It depends how fast you type.

Adding globdots to _comp_options is a bit of a hack. The proper way is supposed to be via the file-patterns style, e.g.:
zstyle ':completion:*' file-patterns '%p(D):globbed-files *(D-/):directories' '*(D):all-files'
However, that won't work in all cases such as for the cd command.

As others have mentioned, if you want delete in brackets, in typical zsh style, you have to enable it, zsh comes with select-bracketed, select-quoted and surround functions. Also builtin is ia/aa text objects to match shell words.

For completion, I would very much recommend you turn on grouping and group headings, e.g.

    zstyle ':completion:*:descriptions' format '%B%d%b'
    zstyle ':completion:*:messages' format '%d'
    zstyle ':completion:*:warnings' format 'No matches for: %d'
    zstyle ':completion:*' group-name ''
@jaworek

This comment has been minimized.

Copy link

@jaworek jaworek commented Nov 10, 2019

When you try to run lfcd() while having some input in terminal (e.g. skdjaskd), it will fail as the command run will be skdjaskd. Does anyone know the way to clear input in terminal before bindkey command is executed?

@kiprasmel

This comment has been minimized.

Copy link

@kiprasmel kiprasmel commented Nov 10, 2019

Does anyone know how to select AND confirm the selection from the auto-complete menu?
Currently, I need to press Return twice, and I'd like to do it only once.

@okapia

This comment has been minimized.

Copy link

@okapia okapia commented Nov 10, 2019

Does anyone know how to select AND confirm the selection from the auto-complete menu?
Currently, I need to press Return twice, and I'd like to do it only once.

   bindkey -M menuselect '^M' .accept-line
@kiprasmel

This comment has been minimized.

Copy link

@kiprasmel kiprasmel commented Nov 10, 2019

@okapia thanks, I've tried this before, but I always get this error once I launch my terminal (st):

/home/kipras/.zshrc:bindkey:314: no such keymap `menuselect'
@okapia

This comment has been minimized.

Copy link

@okapia okapia commented Nov 10, 2019

When you try to run lfcd() while having some input in terminal (e.g. skdjaskd), it will fail as the command run will be skdjaskd. Does anyone know the way to clear input in terminal before bindkey command is executed?

You need to invoke some other widget first to clear the line. You could use kill-whole-line but a better alternative is perhaps push-input. That puts the current line on a stack and it is popped next time a new command-line is started. It's often useful on it's own when you construct a complicated line and then want to quickly run something else first. Either way, if you're using bindkey -s, the sequence depends what keys those are bound to. For example:

    bindkey '\eq' push-input
    bindkey -s '^o' '\eqlfcd\n'

Alt-q is a common, albeit emacsy, binding for push-input. I use vi-mode but rebind a lot of the emacs widgets in the main (viins) keymap.

And for what it's worth Ctrl-O is commonly used for something like infer-next-history or accept-line-and-down-history which is really useful for repetitive steps like a git bisect or make, install, test steps.

@okapia

This comment has been minimized.

Copy link

@okapia okapia commented Nov 10, 2019

/home/kipras/.zshrc:bindkey:314: no such keymap `menuselect'

Move it down to later in your .zshrc. The menuselect keymap is defined in the complist module. You may have a line which says zmodload -i zsh/complist so it needs to be after that. It is also possible that the module is only being loaded by some plugin manager/framework but if you've got the cursor driven completion menu working then it must load at some stage. zmodload without arguments lists loaded modules.

@kiprasmel

This comment has been minimized.

Copy link

@kiprasmel kiprasmel commented Nov 10, 2019

@okapia I was missing the zmodload -i zsh/complist :o I was looking for ways to fix this for weeks, holy moly thanks fam! ❤️

@tinfoil-hat

This comment has been minimized.

Copy link

@tinfoil-hat tinfoil-hat commented Dec 1, 2019

You inspired me to do a rangercd:

rangercd () {
    tmp="$(mktemp)"
    ranger --choosedir="$tmp" "$@"
    if [ -f "$tmp" ]; then
        dir="$(cat "$tmp")"
        rm -f "$tmp"
        [ --datadir "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir"                                               
    fi
}

so you just have to switch
last-dir-path with --choosedir and -d with --datadir

another plugin you could very appreciate is zsh-autosuggestions or fzf (fuzzy finder for ZSH)

also: does lf have an imagepreview?

@gregops

This comment has been minimized.

Copy link

@gregops gregops commented Dec 1, 2019

Is it possible to have the beam shape cursor without blinking? I tried changing \e[5 q to \e[0 q (this turns off blinking according to the ascii table), but that doesn't seem to work.

Yes, use '\e[2 q' (instead of 1), and '\e[6 q' (instead of 5). That'll give you beam and block cursors respectively, without blinking. Mix and match as desired.

@TomasDrozdik

This comment has been minimized.

Copy link

@TomasDrozdik TomasDrozdik commented Dec 11, 2019

Hi, the code which changes your cursor seems to be breaking my tmux.
After running it it immediately exits.
Haven't looked further into it just wanna know if anybody else has been experiencing similar issue?

p.s. this happens only in simple terminal which I have only default version of from your st-luke-git AUR repo

@snamjoshi

This comment has been minimized.

Copy link

@snamjoshi snamjoshi commented Dec 17, 2019

None of the shortcuts appear to work for me... I have copied the entire script except lines 3-5 (colors) 68-69 (aliases/shortcuts).

I cannot leave insert mode in zsh vi mode. If I press ESC, nothing happens. Or sometimes, can't exactly tell why, it attempts to enter the man page for the command I'm typing. Ctrl+e does nothing and Ctrl+o does nothing. I have lf installed and can run it normally in the terminal.

@okapia

This comment has been minimized.

Copy link

@okapia okapia commented Dec 17, 2019

I'd also remove line 21 (setting KEYTIMEOUT). Setting it to 1 is not a good idea anyway. The default of 20 is perhaps too high (I use 5). Setting it to 1 gets widely perpetuated as advice for vi mode. At some point, it alleviated one problem while creating a different problem, but since around zsh 5.1 the original problem has been fixed properly.

Make sure you've really got vi mode. What is escape bound to - run bindkey '\e'

The man page printing is the run-help widget which is typically bound to F1. Given that F1 is right next to Escape, could you be sometimes hitting that by mistake.

How are you invoking the "script"? It needs to be sourced or included in .zshrc. Running it as a script will use a subshell which is no help at all.

@SpawnAtis

This comment has been minimized.

Copy link

@SpawnAtis SpawnAtis commented Jan 11, 2020

You inspired me to do a rangercd:

rangercd () {
    tmp="$(mktemp)"
    ranger --choosedir="$tmp" "$@"
    if [ -f "$tmp" ]; then
        dir="$(cat "$tmp")"
        rm -f "$tmp"
        [ --datadir "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir"                                               
    fi
}

so you just have to switch
last-dir-path with --choosedir and -d with --datadir

another plugin you could very appreciate is zsh-autosuggestions or fzf (fuzzy finder for ZSH)

also: does lf have an imagepreview?

I don't understand this part [ --datadir "$dir" ]. It causes an error. I think, u need to leave it as in the original script.
[ -d "$dir" ] means " $dir file exists and is a directory".

@duncan-f

This comment has been minimized.

Copy link

@duncan-f duncan-f commented Jan 18, 2020

Hi, the code which changes your cursor seems to be breaking my tmux.
After running it it immediately exits.
Haven't looked further into it just wanna know if anybody else has been experiencing similar issue?

p.s. this happens only in simple terminal which I have only default version of from your st-luke-git AUR repo

Just change your termname variable in your st config.h file: termname = "screen-256color";

@allesklar

This comment has been minimized.

Copy link

@allesklar allesklar commented Apr 17, 2020

Came here via your video and the code to change the cursor in normal vs insert is fantastic.

@dm17

This comment has been minimized.

Copy link

@dm17 dm17 commented Jun 14, 2020

I think my keyboard may be different but this is making the DELETE button non-functional. Is it intentional that DELETE causes some strange mode that causes any letter it is typed on to become capitalized? Having a pain figuring out why home, end, pageup, pagedown work fine in all apps except the terminals. (I have installed larbs.sh btw.)
END works in bash but not zsh, but DELETE does for neither.

@timescam

This comment has been minimized.

Copy link

@timescam timescam commented Jun 17, 2020

I think my keyboard may be different but this is making the DELETE button non-functional. Is it intentional that DELETE causes some strange mode that causes any letter it is typed on to become capitalized? Having a pain figuring out why home, end, pageup, pagedown work fine in all apps except the terminals. (I have installed larbs.sh btw.)
END works in bash but not zsh, but DELETE does for neither.

found the fix: https://stackoverflow.com/a/8645267

@duncan-f

This comment has been minimized.

Copy link

@duncan-f duncan-f commented Jun 17, 2020

I think my keyboard may be different but this is making the DELETE button non-functional. Is it intentional that DELETE causes some strange mode that causes any letter it is typed on to become capitalized? Having a pain figuring out why home, end, pageup, pagedown work fine in all apps except the terminals. (I have installed larbs.sh btw.)
END works in bash but not zsh, but DELETE does for neither.

I think this is due to st suckless terminal, but i'm not sure.

@fayefossegrim

This comment has been minimized.

Copy link

@fayefossegrim fayefossegrim commented Jun 25, 2020

You may also enjoy using url-quote-magic
https://github.com/zsh-users/zsh/blob/master/Functions/Zle/url-quote-magic

it gives me this error. I did all the steps from here

https://stackoverflow.com/questions/20357441/zsh-on-10-9-widgets-can-only-be-called-when-zle-is-active#comment33992880_20357441

and still, same error when opening the shell. Can u help me please/ im alo a noobie and im not 100% what all of this means but i want to make my shell practical & lit af xD

thank you so much for your effort on writing this code for us :( i wish i would've been smarter to understand what im doing wrong

@fayefossegrim

This comment has been minimized.

Copy link

@fayefossegrim fayefossegrim commented Jun 25, 2020

THAAAAAAAAAAANNNNNNNNNNNKKKKKKKKKKKIIIIIIIIIIIEEEESSSSSSS <3 <3
now my shell looks sooooo faaannncyyyyyy <3 <3 <3

@zaid-g

This comment has been minimized.

Copy link

@zaid-g zaid-g commented Aug 19, 2020

Also have the same problem as @Arjentix , this for some reason changes my cursor inside actual Vim to always look like it's in insert.

@dm17

This comment has been minimized.

Copy link

@dm17 dm17 commented Aug 19, 2020

Also have the same problem as @Arjentix , this for some reason changes my cursor inside actual Vim to always look like it's in insert.

There is a vim emulation somewhere in this zsh config I think.

@zaid-g

This comment has been minimized.

Copy link

@zaid-g zaid-g commented Aug 19, 2020

@dm17 are you referring to bindkey -v? I know there are vi keybindings in zsh, why would that break the actual Vim cursor though (and how to fix)? The # Change cursor shape for different vi modes. block is the one that breaks the cursor in Vim.

@corneliusroemer

This comment has been minimized.

Copy link

@corneliusroemer corneliusroemer commented Oct 12, 2020

The code to change the cursor based on vi mode works perfectly, thanks so much! I've been trying loads of suggestions from SO but they all had bugs.

Wit this table, one can customise the type of cursor one gets as requested by @yochem and suggested by @gregops:

Replace number in '\e[5 q' with number below for customisation:
CSI Ps SP q
          Set cursor style (DECSCUSR), VT520.
            Ps = 0  ⇒  blinking block.
            Ps = 1  ⇒  blinking block (default).
            Ps = 2  ⇒  steady block.
            Ps = 3  ⇒  blinking underline.
            Ps = 4  ⇒  steady underline.
            Ps = 5  ⇒  blinking bar, xterm.
            Ps = 6  ⇒  steady bar, xterm.

(source: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)

@JDeepD

This comment has been minimized.

Copy link

@JDeepD JDeepD commented Oct 25, 2020

I'd also remove line 21 (setting KEYTIMEOUT). Setting it to 1 is not a good idea anyway. The default of 20 is perhaps too high (I use 5). Setting it to 1 gets widely perpetuated as advice for vi mode. At some point, it alleviated one problem while creating a different problem, but since around zsh 5.1 the original problem has been fixed properly.

Make sure you've really got vi mode. What is escape bound to - run bindkey '\e'

The man page printing is the run-help widget which is typically bound to F1. Given that F1 is right next to Escape, could you be sometimes hitting that by mistake.

How are you invoking the "script"? It needs to be sourced or included in .zshrc. Running it as a script will use a subshell which is no help at all.

Setting KEYTIMEOUT=1 or deleting it will create problems as you will not be able to bind the jj key to Esc. The minimum KEYTIMEOUT for making jj work is 20ms. So if someone wants to map jj to Esc , he has to set KEYTIMEOUT=20

@therajat08

This comment has been minimized.

Copy link

@therajat08 therajat08 commented Nov 4, 2020

turn CTRL+z into a toggle switch

ctrlz() {
  if [[ $#BUFFER == 0 ]]; then
    fg >/dev/null 2>&1 && zle redisplay
  else
    zle push-input
  fi
}
zle -N ctrlz
bindkey '^Z' ctrlz

what is this used for?

@rod-stuchi

This comment has been minimized.

Copy link

@rod-stuchi rod-stuchi commented Nov 5, 2020

hi @therajat08 it's for alternate your processes in background.
Try this:

open vim, then ctrl+z (back to terminal), then ctrl+z (back to vim)

@Blugil

This comment has been minimized.

Copy link

@Blugil Blugil commented Dec 31, 2020

Both the bindkey -s '^o' 'lfcd\n' and bindkey '^e' edit-command-line keybinds don't work for me. I saw someone above that had a similar issue and I've tried my best to look up how to do this on my own. I've made sure there are no conflicting keybinds but I've also set a myriad of different keybinds besides ^o and ^e just in case but to no avail. Let me know if anyone else has had this issue and how you fixed it or if you know the fix.

@souvikhaldar

This comment has been minimized.

Copy link

@souvikhaldar souvikhaldar commented Dec 31, 2020

hi @therajat08 it's for alternate your processes in background.
Try this:

open vim, then ctrl+z (back to terminal), then ctrl+z (back to vim)

Ctrl+z did take me to terminal from vim, but pressing ctrl+z from terminal did not take me back to vim, I ran ‘fg’ for that.

@dm17

This comment has been minimized.

Copy link

@dm17 dm17 commented Dec 31, 2020

starship.rs might be a candidate to replace a bit of this... Thoughts?

@RichardBronosky

This comment has been minimized.

Copy link

@RichardBronosky RichardBronosky commented Feb 17, 2021

@Arjentix @zaid-g
It turns out that, unless told to do otherwise, vim will just use whatever cursor shaped your terminal/shell is currently using. And when you type vim and hit <return> (even if you hit <esc> to enter vi-mode and then hit <return>) you are in main or viins mode/keymap in your shell and the zle-keymap-select function has used echo -ne '\e[5 q' to set your cursor to "blinking vertical bar". You can overcome this by doing:

echo -ne "\e[1 q"; vim

Or in vim you can do:

:!echo -ne "\e[1 q";

That is not convenient, but if it's possible, then it has to be scriptable! Sure enough, armed with that info, I was able to find this…

Taken from https://vim.fandom.com/wiki/Change_cursor_shape_in_different_modes#For_Terminal_on_macOS adding this to my ~/.vim/vimrc gave me the same behavior in vim as in zsh.

"Mode Settings

let &t_SI.="\e[5 q" "SI = INSERT mode
let &t_SR.="\e[4 q" "SR = REPLACE mode
let &t_EI.="\e[1 q" "EI = NORMAL mode (ELSE)

"Cursor settings:

"  1 -> blinking block
"  2 -> solid block 
"  3 -> blinking underscore
"  4 -> solid underscore
"  5 -> blinking vertical bar
"  6 -> solid vertical bar
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment