Skip to content
forked from romkatv/zsh4humans

Zsh for Humans: Single-file configuration for Zsh with sane defaults

License

Notifications You must be signed in to change notification settings

tumd/zsh4humans

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 

Repository files navigation

Zsh for Humans

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.

Table of contents

Installation

  1. Optional: Install MesloLGS NF terminal font.
  2. 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 it in Docker

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)"'

Usage

If you've used Zsh, Bash or Fish, Zsh for Humans should feel familiar. For the most part everything works as you would expect.

Key bindings

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.

Cursor movement

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

Editing

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-/

Accepting autosuggestions

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.

Completing commands

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.

Searching command history

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

Changing current directory

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.

Miscellaneous

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

Fuzzy search

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.

SSH

You can bring your Zsh For Humans environment along when connecting over SSH to a remote host. Simply use z4h ssh instead of ssh.

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:

  1. Archives Zsh config files on the local host and sends them to the remote host.
  2. Extracts Zsh config files on the remote host.
  3. 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.

Customization

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.

Customizing prompt

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.

Customizing key bindings

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.

Customizing appearance

Different parts of Zsh For Humans UI are rendered by different projects.

Zsh For Humans

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.

Using external commands or files

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

Additional Zsh startup files

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.

Updating

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.

Uninstalling

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.

Configuration files

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 with p10k 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.

Replicating Zsh For Humans on another machine or restoring it from a backup

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.

  1. Optional: Install MesloLGS NF terminal font.
  2. Remove or backup the existing Zsh config files: ~/.zshenv, ~/.zshrc, ~/.zprofile, ~/.zlogin and ~/.zlogout.
  3. Place ~/.zshrc from your Zsh For Humans setup in the home directory.
  4. If you have ~/.p10k*.zsh files, place them in the home directory.
  5. 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.

About

Zsh for Humans: Single-file configuration for Zsh with sane defaults

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published