DEV Community

riscie for EcoLogic

Posted on • Edited on

Using keyboard-shortcuts with zsh

Are you a zsh user? Do you like to tweak your shell to the maxium in order to gain a bit of time here or there? You might be in the right place here.

This post will show you how to use keyboard shortcuts within zsh to run common commands.

gif showing how to use the shortcut to run git pull

git pull using a keyboard shortcut

In this example we want to run git pull with the shortcut ctrl-g+p (meaning ctrl-g - releasing g - pressing p) as seen in the gif above.

We define our shortcuts in the zsh ressource file. It's normally called .zshrc and we find it within our home directory. I use visual studio code to edit the file:

code ~/.zshrc

Add the following content to the file:

# git pull (ctrl-g+p)
function gitpull() { echo "git pull"; git pull; zle reset-prompt; zle redisplay}
zle -N gitpull
bindkey '^gp' gitpull
Enter fullscreen mode Exit fullscreen mode

Lets break it down line-by-line

  1. A nice comment
  2. We define the function gitpull which we use for our keybinding later. The function does:
    1. Write out the command we send. (I like this over having an empty screen doing something)
    2. Runs git pull
    3. Resets our prompt. (This is useful, if we have git information in our prompt, as they are not updated if we don't use reset-prompt)
    4. Redisplays our prompt
  3. We define a widget that points to the function
  4. We bind our key-combination to the widget

That's it. Let me know if it works for you. If there is some interest in this kind of stuff, I could follow up with an example of how to pass an argument to a keyboard shortcut. I for example use this option to create feature branches by doing:

typing the name of the feature branch --> ctrl-g+f

gif showing how to use the shortcut to create a feature branch

Bonus

Some more shortcut definition examples also using alt as the modifier to get you started:

'^g'   # ctrl-g
'^gp'  # ctrl-g and then p (as shown in the example)
'^[x'  # alt-x
'^[xc' # alt-x and then c
Enter fullscreen mode Exit fullscreen mode

❤️ Let's connect!

I would love to grow my network with other tech enthusiasts. Let's connect here or over on twitter! 👋 @langhard

Resources

A User's Guide to the Z-Shell

Update

Part 2 - Passing a parameter to a zsh keyboard-shortcut - is now online.

Top comments (7)

Collapse
 
dmitrykrasilnikov profile image
Dmitriy Krasilnikov

But why define functions & shortcuts if there is a great git plugin for zsh? It's built around aliases, the commands are pretty short and mnemonic, and you can just add any flags you want after typing in the command, i.e. ga -u which is git add -u

Collapse
 
riscie profile image
riscie

Sure, aliases and plugins work as well, if not better.
I just wanted to show how to handle keybindings in zsh here. Git was just an example. Keybindings come in handy for more terminal-based commands imo. Like clearing the screen (which is often bound to ctrl-l) and stuff alike.

Collapse
 
dmitrykrasilnikov profile image
Dmitriy Krasilnikov

Fair enough, I misunderstood the topic I guess

Collapse
 
voyeg3r profile image
Sérgio Araújo • Edited

I am sharing some of my zsh widgets:

# toggles background shell
fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    BUFFER="fg"
    zle accept-line
  else
    zle push-input
    zle clear-screen
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z

# add a command line to the shells history without executing it
commit-to-history() {
    print -s ${(z)BUFFER}
    zle send-break
}
zle -N commit-to-history
bindkey "^x^h" commit-to-history

# sometimes you find a nice piece of code and want to change something before
# executing it, so you want to get the clipboard content in a new vim buffer
# Edit content of clipboard on vim (scratch buffer)
function _edit_clipboard(){
    # pbpaste | vim -c 'setlocal bt=nofile bh=wipe nobl noswapfile nu'
    pbpaste | vim
}
zle -N edit-clipboard _edit_clipboard
bindkey '^x^v' edit-clipboard

# Copy the most recent command to the clipboard
function _pbcopy_last_command(){
    fc -ln -1 | sed -r 's/(\\n)//g' | xclip -selection clipboard
    echo "last cmd -> $(xclip -i -selection clipboard -o)"
}
zle -N pbcopy-last-command _pbcopy_last_command
bindkey '^x^l' pbcopy-last-command

# put the cursor in a subshell $()
# using Ctrl-j
function _zle_subshell {
    RBUFFER='$()'"$RBUFFER"
    ((CURSOR=CURSOR+2))
}
zle -N _zle_subshell
bindkey '^J' _zle_subshell
Enter fullscreen mode Exit fullscreen mode

in my "autoloaded" folder I also have this function:

# source:https://stackoverflow.com/a/65375231/2571881
# fzf list of files to vim (if you give up it does nothing)
function vif() {
    local fname
    local current_dir=$PWD
    cd ~/.dotfiles
    fname=$(fzf) || return
    vim "$fname"
    cd $current_dir
}
Enter fullscreen mode Exit fullscreen mode

The keybinding to open it automatically is: bindkey -s '^o' 'vif^M', so it will run when I press Ctrl-o.

Some useful aliases:

(( $+commands[xclip] )) && {
    alias pbpaste='xclip -i -selection clipboard -o'
    alias pbcopy='xclip -selection clipboard'
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
fgiraldi profile image
fgiraldi

I have started using zsh about a couple of weeks ago. I was searching for a dark-theme friendly shell and features like this one.
I can't wait for the post with the "how to pass arguments" example!
Thanks for the time you took on writing this post.

Collapse
 
riscie profile image
riscie • Edited

I am happy to hear it is of use for you. Part 2 is now online.

Collapse
 
mprakash13 profile image
mprakash13

Nice and very useful. Thank you for posting this.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.