Configuration for Z shell that aims to work really well out of the box. It combines the best Zsh plugins into a coherent whole that feels like a finished product rather than a DIY starter kit.
If you want a great shell that just works, this project is for you.
-
- 3.1. Key bindings
- 3.1.1. Cursor movement
- 3.1.2. Editing
- 3.1.3. Accepting autosuggestions
- 3.1.4. Completing commands
- 3.1.5. Searching command history
- 3.1.6. Changing current directory
- 3.1.7. Miscellaneous
- 3.2. Fuzzy search
- 3.3. SSH
- 3.1. Key bindings
- Optional: Install MesloLGS NF terminal font.
- Execute this command.
if command -v curl >/dev/null 2>&1; then
sh -c "$(curl -fsSL https://raw.githubusercontent.com/romkatv/zsh4humans/v2/install)"
else
sh -c "$(wget -O- https://raw.githubusercontent.com/romkatv/zsh4humans/v2/install)"
fi
The installer backs up the existing Zsh startup files, downloads .zshrc, installs everything necessary for Zsh For
Humans and opens a new shell. It asks for confirmation on every step so that you are always in
control. Installation requires curl
or wget
. It does not require git
, zsh
, sudo
or
anything else.
Try Zsh for Humans in a Docker container. You can safely make any changes to the file system. Once you exit Zsh, the image is deleted.
docker run -e TERM -e COLORTERM -w /root -it --rm alpine sh -uec '
sh -c "$(wget -O- https://raw.githubusercontent.com/romkatv/zsh4humans/v2/install)"'
If you've used Zsh, Bash or Fish, Zsh for Humans should feel familiar. For the most part everything works as you would expect.
These are the key bindings that you get with the default ~/.zshrc
. You can
change them.
The default bindings currently work well only in emacs
mode. If you would like to use vi
mode,
you'll likely need to define additional bindings.
Zle Widget | Description | Bindings |
---|---|---|
backward-char |
move cursor one char backward | Left Ctrl-B |
forward-char |
move cursor one char forward | Right Ctrl-F |
backward-word |
move cursor one word backward | Ctrl-Left Alt-B |
forward-word |
move cursor one word forward | Ctrl-Right Alt-F |
z4h-up-local-history |
move cursor up or fetch previous local history event | Up Ctrl-P |
z4h-down-local-history |
move cursor down or fetch next local history event | Down Ctrl-N |
z4h-up-global-history |
move cursor up or fetch previous global history event | Ctrl-Up |
z4h-down-global-history |
move cursor down or fetch next global history event | Ctrl-Down |
beginning-of-line |
move cursor to the beginning of line | Home Ctrl-A |
end-of-line |
move cursor to the end of line | End Ctrl-E |
z4h-beginning-of-buffer |
move cursor to the beginning of buffer | Ctrl-Home Alt-Home |
z4h-end-of-buffer |
move cursor to the end of buffer | Ctrl-End Alt-End |
Zle Widget | Description | Bindings |
---|---|---|
delete-char |
delete the character under the cursor | Delete |
backward-delete-char |
delete the character behind the cursor | Backspace |
backward-kill-word |
delete the previous word | Ctrl-Backspace Alt-Backspace Ctrl-W Ctrl-H |
kill-word |
delete the next word | Ctrl-Delete Alt-Delete Alt-D |
backward-kill-line |
delete from the beginning of the line to the cursor | Alt-K |
kill-line |
delete from the cursor to the end of the line | Ctrl-K |
kill-whole-line |
delete the whole current line | Ctrl-U |
kill-buffer |
delete all lines | Alt-J |
z4h-stash-buffer |
push command to history and delete all lines | Alt-O |
undo |
undo the last edit | Ctrl-/ |
redo |
redo the last undone edit | Alt-/ |
All key bindings that move cursor can accept command autosuggestions. For example, moving the cursor one word to the right will accept that word from the autosuggestion.
By default, Right accepts one character from the autosuggestion (because it moves cursor one character forward) but you can rebind it to accept the whole autosuggestion instead.
There is one special binding that is specific to autosuggestions.
Zle Widget | Description | Bindings |
---|---|---|
z4h-autosuggest-accept |
accept the whole autosuggestion without moving the cursor | Alt-M |
Autosuggestions in Zsh For Humans are provided by zsh-autosuggestions. See its homepage for more information.
Zle Widget | Description | Bindings |
---|---|---|
z4h-expand |
expand an alias, glob or parameter | Ctrl-Space |
z4h-expand-or-complete |
complete interactively with fuzzy search | Tab Ctrl-I |
fzf-completion |
complete files recursively; great for completing file paths | Alt-I |
When completing with Tab, you can move the cursor with arrow keys. Editing is mostly
consistent with emacs
keymap from Zsh For Humans but not quite the same. There are several
additional bindings to accept selection.
Description | Key Binding |
---|---|
accept selection | Enter |
mark selection (for accepting multiple entries) | Ctrl-Space |
accept selection and trigger another completion right away; great for completing file paths | Tab |
The content of command completions in Zsh For Humans comes from completion functions. For most commands completion functions are provided by Zsh proper. Additional completion functions are contributed by zsh-completions. See its homepage for the list of commands it supports.
The UI for interacting with the completion system is provided by fzf-tab and fzf. fzf-tab is a bridge that connects the powerful Zsh completions system (completion functions) with fzf fuzzy searcher.
Up and Down keys fetch commands from history when the cursor is already at the
top or the bottom line respectively. Otherwise they just move the cursor. When they do fetch
history, they filter it by the prefix bound by the command line start and the cursor. For example,
if you press Up when the first line of the command buffer contains echo hello world
and
the cursor is positioned before world
, it'll fetch the last executed command that starts with
echo hello
.
All active shells running under the same user have access to each other's command history in real time. History events from the current shell together with all history events that happened before the current shell started are collectively called local history. Global history contains all events.
Up and Down use local history. Everything else uses global history. Thus, when you press Up with empty command line buffer, it fetches the last command executed in the current shell. Conversely, Ctrl-Up fetches the last command executed in any shell. The only difference between Up/Down and Ctrl-Up/Ctrl-Down is the use of local vs global history.
Ctrl-R searches over global history. There is no equivalent binding for local history.
Zle Widget | Description | Bindings |
---|---|---|
z4h-up-local-history |
move cursor up or fetch previous local history event | Up Ctrl-P |
z4h-down-local-history |
move cursor down or fetch next local history event | Down Ctrl-N |
z4h-up-global-history |
move cursor up or fetch previous global history event | Ctrl-Up |
z4h-down-global-history |
move cursor down or fetch next global history event | Ctrl-Down |
z4h-fzf-history |
fuzzy search history from all shells | Ctrl-R |
These bindings allows you to quickly change current directory without losing command line buffer. Going to the previous/next directory works similarly to the Back and Forward buttons in a Web browser.
Zle Widget | Description | Bindings |
---|---|---|
z4h-cd-back |
cd into the previous directory |
Alt-Left |
z4h-cd-forward |
cd into the next directory |
Alt-Right |
z4h-cd-up |
cd into the parent directory |
Alt-Up |
z4h-cd-down |
cd into a subdirectory; uses fuzzy search |
Alt-Down |
Another way to change current directory is to type cd ~/
and hit Alt I. It works with
any directory prefix. Alt I completes files with fuzzy search but it's
smart enough to recognize that the argument to cd
must be a directory, so it'll only show those.
If you want create a directory and cd
into it, use md
:
md foo/bar # the same as: mkdir -p foo/bar && cd foo/bar
This simple function is defined right in your ~/.zshrc
to serve as an example. It comes with a
completion function, too, so that md fo<TAB>
will complete to md foo/
but not to md fo.txt
.
Zle Widget | Description | Bindings |
---|---|---|
clear-screen |
clear screen and place prompt at the top | Ctrl-L |
z4h-run-help |
show help for the command at cursor | Alt-H |
z4h-do-nothing |
do nothing; useful for blocking keys that would otherwise print garbage | PageUp PageDown |
Several UI elements in Zsh For Humans use fzf to quickly select an item from a potentially large list of candidates. You can type multiple search terms delimited by spaces. For example:
^music .mp3$ sbtrkt !fire
Token | Match type | Description |
---|---|---|
sbtrkt |
fuzzy-match | Items that match sbtrkt |
'wild |
exact-match (quoted) | Items that include wild |
^music |
prefix-exact-match | Items that start with music |
.mp3$ |
suffix-exact-match | Items that end with .mp3 |
!fire |
inverse-exact-match | Items that do not include fire |
!^music |
inverse-prefix-exact-match | Items that do not start with music |
!.mp3$ |
inverse-suffix-exact-match | Items that do not end with .mp3 |
A single bar character term acts as an OR operator. For example, the following query matches entries
that start with core
and end with either go
, rb
, or py
.
^core go$ | rb$ | py$
See fzf homepage for more information.
You can bring your Zsh For Humans environment along when connecting over SSH to a remote host.
Simply use z4h ssh
instead of ssh
.
z4h ssh [email protected]
This command connect to the remote host over SSH and starts Zsh with your local configs. The remote
host must have login shell compatible with the Bourne shell (sh
, bash
, zsh
, ash
, dash
,
etc.), curl
or wget
, and internet connection. Nothing else is required. In particular, the
remote host doesn't need to have zsh
, git
or sudo
.
Here's what z4h ssh
does:
- Archives Zsh config files on the local host and sends them to the remote host.
- Extracts Zsh config files on the remote host.
- Sources
.zshrc
, which starts the usual Zsh For Humans bootstrap process.
ZDOTDIR
and Z4H
on the remote host both point to "${XDG_CACHE_HOME:-$HOME/.cache}/z4h-ssh"
.
This prevents clashes with regular Zsh configs if they exist.
Whenever you are in a remote shell opened via z4h ssh
, Z4H_SSH
environment variable is set to
1
.
The first login to a remote host may take some time. After that it's as fast as normal ssh
.
For z4h ssh
to work, you must follow the best practice of checking for presence of external
commands and files before using them in ~/.zshrc
.
You can (and should) edit ~/.zshrc
to customize your shell. It's a very good idea to read through
the whole file to see which customization options are in there and to flip some of them to your
liking.
When adding your customizations, put them next to the exiting lines that do similar things. The
default ~/.zshrc
contains the following types of customizations that should serve as examples:
- Export environment variables.
- Extend
PATH
. - Define aliases.
- Add flags to existing aliases.
- Define functions.
- Source additional local files.
- Load Oh My Zsh plugins.
- Clone and load external Zsh plugins.
- Set shell options.
- Autoload functions.
- Change key bindings.
Prompt in Zsh For Humans is provided by Powerlevel10k.
Run p10k configure
to access its interactive configuration wizard. Further customization can be
done by editing ~/.p10k*.zsh
files. There can be more than one configuration file to account for
terminals with limited capabilities. Most users will ever only see ~/.p10k.zsh
. In in doubt,
consult $POWERLEVEL9K_CONFIG_FILE
. This parameter is set by Zsh For Humans and it always points
to the config file currently in use.
See Powerlevel10k homepage for more information.
There are several common key binding customizations that many users apply. They can be achieved
with one-line changes in ~/.zshrc
.
Customization | How |
---|---|
swap the bindings for Alt-Arrows and Ctrl-Arrows | flip the value of cd-key style |
accept the whole autosuggestion with Right key | flip the value of forward-char style |
delete one character with Backspace and Ctrl-H | delete the binding for backward-kill-word |
move cursor to the end when Up, Down, Ctrl-Up or Ctrl-Down fetch commands from history | flip the value of leave-cursor |
You can rebind any key with bindkey
builtin. See reference.
Different parts of Zsh For Humans UI are rendered by different projects.
Everything within the highlighted areas on the screenshot is prompt. It is produced by Powerlevel10k. See Customizing prompt.
The listing of files produced by ls
command is colored by ls
itself. Different commands have
different ways of customizing their output, and even different version of ls
have different flags
and environment variables related to colors. Zsh For Humans enables colored output from common
commands (such as ls
). For further customization consult documentation of the respective command.
echo hello
is the current command being typed. Syntax highlighting for it is provided by
zsh-syntax-highlighting. See its homepage
for documentation on how to customize it.
After echo hello
you can see world
in grey. This is not a part of the command, so pressing
Enter will print only hello
but not world
. The latter is an autosuggestion provided
by zsh-autosuggestions that you can
accept in part or in full. It comes from command history and it's a
great productivity booster. See zsh-autosuggestions homepage for more information.
Last but not least, your terminal has a say about the appearance of everything that runs within it. The base colors, numbered from 0 to 15, can look very different in different terminals and even in the same terminal with different settings. Most modern terminals support themes, color palettes or color schemes that allow you to quickly change base colors. If colors in your terminal look unpleasant, try a different theme. Note that colors with codes above 15, as well as colors specified as RGB triplets, don't get affected by terminal themes. They look the same everywhere.
When using external commands or files in ~/.zshrc
, prefer conditional evaluation. If your
~/.zshrc
uses only things that exist, it'll be easier to replicate shell on another machine.
Here are a few examples to demonstrate this:
# Load pyenv if ~/.pyenv exists.
if [[ -e ~/.pyenv ]]; then
export PYENV_ROOT=~/.pyenv
path=($PYENV_ROOT/bin $path)
eval "$(pyenv init -)"
fi
# Enable direnv hooks if direnv is installed.
if (( $ commands[direnv] )); then
eval "$(direnv hook zsh)"
fi
When sourcing a file, prefer z4h source
over plain source
. The former will check that the file
exists before attempting to source it and will zcompile
it for faster loading.
# Enable iTerm2 shell integration if the corresponding file exists.
z4h source ~/.iterm2_shell_integration.zsh
When you start Zsh, it automatically sources ~/.zshrc
-- your personal config that builds on
Zsh For Humans. Zsh supports several additional startup files with complex rules governing when each
file is sourced. The additional startup files are ~/.zshenv
, ~/.zprofile
, ~/.zlogin
and
~/.zlogout
. It is not recommended to create these files.
By default you'll be prompted to update once a month when starting Zsh. You can customize frequency
or disable auto-update prompt altogether. You can manually update with z4h update
. There are three
update channels. From the most stable to the most fresh: stable
(default), testing
and dev
.
There is no update mechanism for ~/.zshrc
itself.
To uninstall Zsh For Humans, remove ~/.zshrc
or replace it with a different version. If you had
this file prior to the installation of Zsh For Humans and have replied in the affirmative when asked
by the installer whether you want ~/.zshrc
backed up, you can find it in ~/zsh-backup
.
Zsh For Humans uses the following configuration files:
~/.zshrc
. Main Zsh configuration file. Zsh For Humans gets bootstrapped from it. See Replicating Zsh For Humans on another machine or restoring it from a backup.~/.p10k*.zsh
. Powerlevel10k (prompt) configuration files. There can be more than one such file (hence*
) to account for terminals with limited capabilities. Most users will ever only see~/.p10k.zsh
. Powerlevel10k configuration wizard starts automatically upon Zsh startup if there is no suitable configuration file. You can also run it manually withp10k configure
. Either way it will write new configuration to~/.p10k*.zsh
.
It's a very good idea to backup ~/.zshrc
and/or store it in a Git repository. If you expend
non-trivial amount of effort customizing prompt, give the same treatment to ~/.p10k*.zsh
.
Zsh For Humans stores transient state in the directory designated by $Z4H
. Do not manually modify
or delete files from this directory. It's OK, however, to delete the whole directory. It'll be
recreated. You don't have to back it up and you shouldn't share it between different machines or
different users on the same machine.
If you have ~/.zshrc
from your Zsh For Humans setup, you can recreate the environment on another
machine or restore it on the original machine.
- Optional: Install MesloLGS NF terminal font.
- Remove or backup the existing Zsh config files:
~/.zshenv
,~/.zshrc
,~/.zprofile
,~/.zlogin
and~/.zlogout
. - Place
~/.zshrc
from your Zsh For Humans setup in the home directory. - If you have
~/.p10k*.zsh
files, place them in the home directory. - Run the following command:
ZDOTDIR="$HOME" exec sh -c '. ~/.zshrc'
This requires curl
or wget
. It does not require git
, zsh
, sudo
or anything else.
Note: If you have Zsh For Humans installed on local host and want to have the same environment
when you SSH to remote host, use z4h ssh
command instead of the regular ssh
. See SSH.