# Zsh Configuration

<!-- TODO: GIF -->

## [conduit][conduit]

Simple, local, configuration manager.

Installation of the configuration files in this repository is orchestrated by
[conduit][conduit] as defined in the [`.conduit.yaml`](.conduit.yaml) file. This
includes [Zsh][zsh] package installs, setting [Zsh][zsh] as the users default
shell, and symbolic linking file such as [`zshrc`](zshrc) to `~/.zshrc`, and
cloning plugin repositories. The repository is cloned to `~/.config/zsh`.

## Prompt

A custom prompt theme called "fresh" is used by default, its defined in
[prompt\_fresh\_setup](prompt_fresh_setup) and symbolic linked to
`~/.local/share/zsh/site-functions` which is on the `fpath`. The prompt enabled
using `prompt fresh` when the prompt subsystem is enabled. The prompt is
multi-line and does not redraw during command editing. The first line of the
prompt is drawn using a `precmd` hook and displays variable length information
such as the time, current directory, [Git][git] repository branch and status,
and the last commands exit code if its non-zero.

<!-- ### Options
TODO: Implement options:
  * disable git-prompt
  * disable almost on top
  * disable RPS1
  * add widget support?
-->

### Git Status

The "fresh" theme supports displaying Git repository status information, the
majority of this information is gathered using a C program which is compiled on
the fly when the theme is enabled, it resides in `~/.cache/zsh/git-prompt` and
is removed when the theme is disabled. Since the C program uses the standard
library, development headers must be present in addition to the compiler.

[zsh-git-prompt][git-prompt] was originally used but proved to be agonisingly
slow on large repositories containing many unstaged changes. Instead the
`git-prompt` C program calls `git status --porcelain`, which is extremely fast,
and parses the output in a loop. Output from `git-prompt` is a space separated
list of interesting numbers which is captured in a Zsh array and interpreted for
display. This results in no noticeable lag when redrawing the prompt.

## Plugins

Plugins are sourced manually and their git repositories tracked by
[conduit][conduit], no plugin manager is used.

### [zsh-syntax-highlighting][syntax]

Fish shell like syntax highlighting for Zsh.

### [zsh-history-substring-search][search]

ZSH port of the FISH shell's history search.

## Environment & Settings

The bulk of, if not all, configuration occurs in [`zshenv`](zshenv) and
[`zshrc`](zshrc) these files.

### ~/.local

In addition to `/usr/local` add `~/.local` to useful environment variables. This
is especially useful with `pip install --user <package>`.

* Add `~/.local/share/zsh/site-functions` to `fpath`
* Add `~/.local/bin` to `PATH`
* Add `~/.local/share/man` to `MANPATH`
* Add `~/.local/share/info` to `INFOPATH`

### History

Command history is stored in `~/.cache/zsh/histfile`, duplicates are removed,
and multi-terminal history support is enabled.

### Line Editor

The vi mode line editor is enabled. [zsh-vim-mode][vim-mode] was a reasonable
starting point but was replaced as it uses some strange defaults.

#### `vicmd` Mode

Whole line operations for yank, change, and delete are enabled mode with `Y`,
`C`, and `D` respectively. Undo and repo and enabled using `u` and `U`. Showing
help for the command under the cursor with `<Esc>h` is replaced with `K`. The
[Vim][vim] "Ex" mode binding `:` is disabled mode since is barely of use and
easy to enter accidentally. Bindings for `k` and `j` integrate with
[zsh-history-substring-search][search] performing up and down searches
respectively.

#### Edit Command Line

When editing a command using Zsh's line editor becomes cumbersome due to length
the `<Ctrl>+V` binding opens the default editor (Vim) to edit the current
command.

### Miscellaneous

Interactive comments are enabled, useful when creating demo GIF's of terminal
program usage. Ignore end of file, bound to `<Ctrl>+D`, is disabled to avoid
accidentally exiting the terminal.

Audio beeps are disable. Terminal flow control is disabled, this allows
[Vim][vim] and other terminal programs to use `<Ctrl>+S` mapping/binding, this
proves useful as the `S` key is in the middle of the home row on QWERTY
keyboards.

### Completion

The completion subsystem is enable, any custom completions should be symbolic
linked to `~/.local/share/zsh/site-functions`.

<!-- TODO: Enable compiling completions -->

### Aliases

Various aliases are defined at the end of [zshrc](zshrc) for convenience.

[conduit]: https://github.com/kbenzie/conduit
[zsh]: https://www.zsh.org/
[git]: https://git-scm.com/
[git-prompt]: https://github.com/olivierverdier/zsh-git-prompt
[syntax]: https://github.com/zsh-users/zsh-syntax-highlighting
[search]: https://github.com/zsh-users/zsh-history-substring-search
[vim-mode]: https://github.com/sharat87/zsh-vim-mode