how to setup series — part 1: basic terminal config
in this series I want to show how I do things on my computer for my work life and my overall digital being. i’m currently using an m5 macbook pro for work and therefore use macos. i’m happy to be working with a unix-like system as my daily machine at work.
basic config + addons
the first point i want to start is my zsh config. zshell is the default one for macos and i was never missing a feature that only a different shell was able to offer, so I never really thought about switching. but the plain shell could be upgraded really easily with some little add-ons.
first i want to configure zsh itself, just expand the history and optimize search
HISTSIZE=50000 # Lines kept in memory per session (macOS default: 2000)
SAVEHIST=50000 # Lines saved to ~/.zsh_history (macOS default: 1000)
setopt HIST_IGNORE_ALL_DUPS # Remove older duplicate when a command is repeated (default: off)
setopt HIST_FIND_NO_DUPS # Skip duplicates when searching history (default: off)
setopt HIST_REDUCE_BLANKS # Strip superfluous spaces before saving (default: off)
setopt SHARE_HISTORY # Write and share history immediately across open tabs (default: off)then I add addons to customize my prompt, improve how I’m able to search the history, and add syntax highlighting. most of them can be installed via homebrew (and fzf-tab cloned as a lightweight git repo):
brew install jandedobbeleer/oh-my-posh/oh-my-posh zsh-completions fzf direnv zoxide zsh-autosuggestions zsh-syntax-highlighting
git clone https://github.com/Aloxaf/fzf-tab ~/.config/zsh/plugins/fzf-tabhere is what each addon does and the exact order they need to be loaded in ~/.zshrc:
the examples below use my own oh-my-posh theme and Ghostty colors: a blue folder name, a green git branch, and a cyan prompt on the next line. i’m using MesloLGM Nerd Font Mono for the icons. these are small illustrations of each addon in use; most change how the shell behaves while the prompt stays the same.
-
oh-my-posh
- renders a custom, fast prompt showing the current path, git branch, and active cloud/tool context (like Azure, AWS, Terraform, or Node) only when inside relevant project folders
~/.zshrc eval "$(oh-my-posh init zsh --config ~/.config/oh-my-posh/minimal.omp.json)"the prompt in this site's git repository Terminal lindlau.dev-workspace · main ❯ -
zsh-completions
- Adds completion definitions to
$fpath. - has to be run first, otherwise the following step
compinitcan’t add the completions - comes with completions for things like macos native utils like
networkQuality, ornvm,tsc,direnv, etc.
~/.zshrc fpath=(/opt/homebrew/share/zsh-completions $fpath)adds completion definitions; compinit activates them in the next step Terminal lindlau.dev-workspace · main ❯ networkQuality - - Adds completion definitions to
-
compinit
- initialize the completion engine and configure case-insensitive matching
~/.zshrc autoload -Uz compinit; compinit zstyle ':completion:*' menu no # Let fzf-tab handle the menu zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case-insensitive matchingnetworkQuality - then Tab shows the available options Terminal lindlau.dev-workspace · main ❯ networkQuality - -h -- Show help -s -- Run tests sequentially instead of parallel upload/download -v -- Verbose output -
fzf shell integration (requires
fzfwhich you can install via brew)- Binds
Ctrl+R(history search),Ctrl+T(file picker), andOpt+C(directory jump).
~/.zshrc source <(fzf --zsh)Ctrl+R opens history search; type part of a command and press Enter Terminal lindlau.dev-workspace · main ❯ git status --short > git status 2/2 > status - Binds
-
fzf-tab
- Replaces Zsh’s standard
Tabcompletion menu with an interactivefzfpopup and directory preview
~/.zshrc source ~/.config/zsh/plugins/fzf-tab/fzf-tab.plugin.zsh zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls -G $realpath'cd apps/ then Tab opens a picker with a directory preview Terminal lindlau.dev-workspace · main ❯ cd apps/ > port 1/5 > portfolio/ │ README.md │ astro.config.mjs │ src - Replaces Zsh’s standard
-
direnv
- loads
.envrcon folder switch
~/.zshrc eval "$(direnv hook zsh)"entering an allowed project with an .envrc that exports PROJECT_ENV Terminal ❯ cd ~/Code/example-project direnv: loading ~/Code/example-project/.envrc direnv: export +PROJECT_ENV example-project ❯a new
.envrcneedsdirenv allowbefore it can run. this example only exportsPROJECT_ENV; cloud segments in my prompt appear when the matching context is configured. - loads
-
zoxide
- provides smart directory jumping (
z <folder>andzi)
~/.zshrc eval "$(zoxide init zsh)"after visiting this folder, z jumps back to it by name Terminal ~ ❯ z lindlau.dev-workspace lindlau.dev-workspace · main ❯ - provides smart directory jumping (
-
zsh-autosuggestions
- shows command predictions based on history
~/.zshrc source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zshtype git s; the dim suffix comes from history. press → to accept it Terminal lindlau.dev-workspace · main ❯ git status -
zsh-syntax-highlighting
- colors valid and invalid commands
- must always be the last thing in the zsh config
~/.zshrc source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zshwhile typing: a known command is green, a typo is red, and a quoted string is yellow Terminal lindlau.dev-workspace · main ❯ git status ❯ gti status ❯ echo "hello"
now we have a set up terminal :)