Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,13 @@ function setupShellEnv {
copyFile fish/functions/$f.fish $fishConfigDir/functions/$f.fish
done

# Switch users shell to fish:
# zsh:
local zshConfigDir=$configDir/zsh
copyFile zsh/zshenv $zshConfigDir/.zshenv
copyFile zsh/zshrc $zshConfigDir/.zshrc
copyFile zsh/plugins.zsh $zshConfigDir/plugins.zsh

# Switch user's shell to fish:
if ! grep -qi -- "fish" /etc/shells; then
echo "Adding fish to /etc/shells"
echo $(which fish) | sudo tee -a /etc/shells
Expand Down
7 changes: 4 additions & 3 deletions fish/config.fish
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ end

fish_vi_key_bindings

if functions -q nvm
nvm use --silent lts > /dev/null
end

if command -s zoxide > /dev/null
zoxide init fish | source
function zz
Expand All @@ -62,9 +66,6 @@ if command -s starship > /dev/null
function starship_transient_prompt_func
starship module character
end
function starship_transient_rprompt_func
starship module time
end
starship init fish | source
enable_transience
end
Expand Down
2 changes: 1 addition & 1 deletion fish/functions/la.fish
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function la
ls -a $argv
ls -a --git $argv
end
2 changes: 1 addition & 1 deletion fish/functions/ll.fish
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
function ll
ls -l $argv
ls -lh --git $argv
end
4 changes: 2 additions & 2 deletions starship.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ $nodejs\
$rust\
$golang\
$docker_context\
$time\
$cmd_duration\
\n$character"""
$time\
$character"""

[character]
success_symbol = "[[](green) ❯](peach)"
Expand Down
27 changes: 27 additions & 0 deletions zsh/plugins.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ~/.config/zsh/plugins.zsh

ZPLUGINDIR="${ZDOTDIR:-$HOME/.config/zsh}/plugins"

_zplugin_load() {
local plugin_path="${ZPLUGINDIR}/${2}"
if [[ ! -d "$plugin_path" ]]; then
mkdir -p "$ZPLUGINDIR"
echo "Installing ${2}..."
git clone --depth=1 "https://github.com/${1}/${2}" "$plugin_path" \
|| { echo "ERROR: failed to install ${2}" >&2; return 1; }
fi
source "${plugin_path}/${2}.plugin.zsh"
}

zplugin-update() {
local dir
for dir in "${ZPLUGINDIR}"/*/; do
echo "Updating ${dir:t}..."
git -C "$dir" pull --ff-only
Comment thread
davidjenni marked this conversation as resolved.
done
}

_zplugin_load zsh-users zsh-autosuggestions
_zplugin_load zsh-users zsh-history-substring-search
_zplugin_load jeffreytse zsh-vi-mode
_zplugin_load zdharma-continuum fast-syntax-highlighting
36 changes: 36 additions & 0 deletions zsh/zshenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# ~/.config/zsh/.zshenv
#
# to bootstrap zsh to this config, ensure /etc/zshenv has this entry:
#
# if [[ -d "$HOME/.config/zsh" ]]
# then
# export ZDOTDIR="$HOME/.config/zsh"
# fi

# ---------- XDG base directories ----------
# Centralizes config/cache/data locations
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"

export EDITOR="nvim"
export VISUAL="nvim"
export LESS="-c -i -x4 -J -w -M -r"

if [[ ! -d "$XDG_DATA_HOME/zsh" ]]
then
mkdir -p "$XDG_DATA_HOME/zsh"
fi
if [[ ! -d "$XDG_STATE_HOME/zsh" ]]
then
mkdir -p "$XDG_STATE_HOME/zsh"
fi
Comment thread
davidjenni marked this conversation as resolved.

if command -v bat >/dev/null 2>&1; then
export MANPAGER="bat -l man -p"
fi

export STARSHIP_CONFIG="$XDG_CONFIG_HOME/starship.toml"

export PATH="$HOME/.local/bin:$PATH"
125 changes: 125 additions & 0 deletions zsh/zshrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# ~/.config/zsh/.zshrc

HISTFILE="$XDG_STATE_HOME/zsh/history"
HISTSIZE=100000
SAVEHIST=100000

setopt APPEND_HISTORY
setopt SHARE_HISTORY
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE
setopt HIST_EXPIRE_DUPS_FIRST
setopt HIST_FIND_NO_DUPS

setopt AUTOCD
setopt NOBEEP
setopt NUMERIC_GLOB_SORT # sort file10 after file9, not after file1

# Initialize zoxide
eval "$(zoxide init zsh)"
Comment thread
davidjenni marked this conversation as resolved.

# Load completion system
autoload -Uz compinit
Comment thread
davidjenni marked this conversation as resolved.
# Ensure completion cache directory exists
mkdir -p -- "$XDG_CACHE_HOME/zsh"
# Initialize completion with cached metadata file
compinit -d "$XDG_CACHE_HOME/zsh/zcompdump"

zstyle ':completion:*' menu select
# Make completion case-insensitive
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' # lowercase input matches upper and lower

alias l='bat'
alias ls='eza --sort ext --group-directories-first --classify --icons'
alias ll='eza -lh --sort ext --group-directories-first --classify --icons --git'
alias la='eza -lah --sort ext --group-directories-first --classify --icons --git'
alias tree='eza --tree --sort ext --group-directories-first --classify --icons'
# Reuse ls completions for eza (avoids defining a separate completion function)
compdef eza=ls

alias cat='bat'
alias grep='rg --color=auto'
alias diff='diff --color=auto'
alias df='df -h'

alias -- -='cd -' # -- prevents - being parsed as a flag; cd - jumps to previous directory

alias v='nvim'
alias vi='nvim'
alias vim='nvim'

## FZF Configuration
export FZF_DEFAULT_COMMAND='fd --type f --hidden --strip-cwd-prefix' # strip-cwd-prefix removes the leading ./ from results
# Ctrl-T uses fd
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"

export FZF_DEFAULT_OPTS='
--height=60%
--layout=reverse
--border=rounded
--prompt=" "
--pointer=" "
--preview-window=right:65%:wrap:border-left
'

export _FZF_PREVIEW_CMD='bat --color=always --style=plain,numbers --line-range=:500 {}'
export FZF_CTRL_T_OPTS="--preview '$_FZF_PREVIEW_CMD'"

# Ctrl+F: file picker excluding hidden files
_fzf_file_no_hidden() {
local cmd result
cmd="${FZF_DEFAULT_COMMAND/--hidden /}"
result=$(eval "${cmd:-find . -type f}" | fzf --preview "$_FZF_PREVIEW_CMD") \
Comment thread
davidjenni marked this conversation as resolved.
&& LBUFFER+="$result" # LBUFFER is the text left of the cursor
zle reset-prompt
}
zle -N _fzf_file_no_hidden

# macOS / Homebrew (Apple Silicon)
if [[ -f /opt/homebrew/opt/fzf/shell/key-bindings.zsh ]]; then
source /opt/homebrew/opt/fzf/shell/key-bindings.zsh
source /opt/homebrew/opt/fzf/shell/completion.zsh
fi

# Arch
if [[ -f /usr/share/fzf/key-bindings.zsh ]]; then
source /usr/share/fzf/key-bindings.zsh
source /usr/share/fzf/completion.zsh
fi

# Ubuntu
if [[ -f /usr/share/doc/fzf/examples/key-bindings.zsh ]]; then
source /usr/share/doc/fzf/examples/key-bindings.zsh
source /usr/share/doc/fzf/examples/completion.zsh
fi

# Cursor shape per vi mode
ZVM_INSERT_MODE_CURSOR=$ZVM_CURSOR_BEAM
ZVM_NORMAL_MODE_CURSOR=$ZVM_CURSOR_BLOCK
ZVM_VISUAL_MODE_CURSOR=$ZVM_CURSOR_BLOCK

ZVM_VI_HIGHLIGHT_BACKGROUND=none
ZVM_VI_HIGHLIGHT_FOREGROUND=none
ZVM_VI_HIGHLIGHT_EXTRASTYLE=none

# zsh-vi-mode resets all bindings on init, so custom bindings
# must be registered via this hook to survive.
zvm_after_init() {
# Ctrl+F -> fzf file picker (no hidden files)
bindkey '^F' _fzf_file_no_hidden

# Ctrl+\ -> toggle autosuggestions (useful for screen recordings)
bindkey '^\' autosuggest-toggle

bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
}

# Plugins and plugin manager
source "$ZDOTDIR/plugins.zsh"

if [[ -f "$HOME/.cargo/env" ]]; then
source "$HOME/.cargo/env"
fi

eval "$(starship init zsh)"
Comment thread
davidjenni marked this conversation as resolved.
Loading