Browse Source

Init hardened zsh config

master
Taylor Bockman 1 week ago
commit
e04b71932d
  1. 43
      .gitignore
  2. 182
      README.md
  3. 63
      aliases.zsh
  4. 76
      exports.zsh
  5. 12
      functions.zsh
  6. 19
      initializations.zsh
  7. 3
      keybinds.zsh
  8. 51
      macrc
  9. 10
      ps1.zsh
  10. 109
      scripts/cgen.sh
  11. 16
      scripts/cgen_etc/clang_format_template
  12. 97
      scripts/cgen_etc/gitignore_template
  13. 2
      zprofile
  14. 230
      zshrc

43
.gitignore vendored

@ -0,0 +1,43 @@
# Private shell config
.bash_private
.private
.zsh_private
*.private
*.local
*.secret
*.secrets
# Environment files
.env
.env.*
!.env.example
# Shell history
.zsh_history
.bash_history
.python_history
.lesshst
.psql_history
.mysql_history
.sqlite_history
# SSH / keys / certs
id_rsa
id_ed25519
*.pem
*.key
*.crt
*.p12
*.pfx
# Cloud credentials
.aws/
.gcp/
.azure/
.kube/config
# macOS / editor junk
.DS_Store
*.swp
*.swo
*~

182
README.md

@ -0,0 +1,182 @@
# ZSH Configuration
A modular ZSH configuration designed to be portable, easy to maintain, and friendly to both Linux and macOS.
The main idea is simple: keep the top-level shell startup files small, then split aliases, functions, exports, prompt setup, keybindings, and OS-specific behavior into separate files.
## Layout
| File | Purpose |
|---|---|
| `zshrc` | Main interactive shell configuration. Sources the modular config files. |
| `zprofile` | Login shell configuration. Sources `zshrc` where appropriate. |
| `aliases.zsh` | Shell aliases. |
| `functions.zsh` | Utility function definitions. |
| `exports.zsh` | Cross-platform environment variables and PATH setup. |
| `initializations.zsh` | Tool initialization code, such as language managers or runtime setup. |
| `keybinds.zsh` | Custom ZSH keybindings. |
| `ps1.zsh` | Prompt configuration. |
| `macrc` | macOS-specific configuration, especially Homebrew paths and macOS-only tools. |
| `scripts/` | Helper scripts used by this configuration. |
## Installation
Clone the repository:
```sh
git clone git.xchg.sh:angrygoats/zsh-v2.git ~/zsh-v2
```
Back up any existing ZSH files:
```sh
mv ~/.zshrc ~/.zshrc.backup 2>/dev/null || true
mv ~/.zprofile ~/.zprofile.backup 2>/dev/null || true
```
Symlink the main files:
```sh
ln -s ~/zsh-v2/zshrc ~/.zshrc
ln -s ~/zsh-v2/zprofile ~/.zprofile
```
Reload your shell:
```sh
source ~/.zshrc
```
## Private Configuration
Private or machine-local values should not be committed to this repository.
The following files are automatically sourced if present:
```text
$HOME/.bash_private
$HOME/.private
$HOME/.zsh_private
```
Use these for secrets, tokens, private exports, work-specific paths, or anything machine-specific that should not live in Git.
## OS-Specific Configuration
macOS-specific configuration belongs in:
```text
$HOME/.macrc
```
This is the right place for Homebrew paths, macOS-only tools, GUI application CLI paths, and Apple Silicon versus Intel Homebrew differences.
Linux-specific configuration can be placed in a Linux-specific file if needed.
## PATH Management
This configuration uses ZSH’s `path` array where possible instead of repeatedly prepending strings to `$PATH`.
At the end of shell initialization, PATH entries should be deduplicated with:
```zsh
typeset -U path PATH
```
This keeps path ordering predictable while avoiding duplicate entries.
## Git Completion
Git completion support is installed automatically on first run into:
```text
$HOME/.zsh
```
The setup downloads:
```text
git-completion.bash
_git
```
from the official Git repository.
If the download fails, manually place both completion files in `$HOME/.zsh` and reload the shell.
## Syntax Highlighting
If the installed ZSH version is new enough, `zsh-syntax-highlighting` is automatically cloned into:
```text
$HOME/.zsh/zsh-syntax-highlighting
```
It is sourced last, which is required for `zsh-syntax-highlighting` to work correctly with most ZSH configurations.
## Rust
Rust is initialized from:
```text
$HOME/.cargo/env
```
if that file exists.
This exposes standard Rust tooling such as:
```text
cargo
rustc
rustfmt
clippy
rust-analyzer
```
when installed through `rustup`.
## Go
If Go is installed, this configuration sets:
```zsh
GOPATH=$HOME/.go
```
and adds the Go binary directory to `PATH`.
## macOS Notes
On macOS, machine-specific Homebrew setup should live in `macrc`, not in the shared cross-platform exports file.
Common macOS tools configured there include:
```text
Homebrew
LLVM / clangd / clang-format
OpenSSL
OpenJDK
Qt
Tcl/Tk
Ghostty
Sublime Text CLI
```
The Sublime Text CLI symlink should be created once per machine, not on every shell startup:
```sh
sudo mkdir -p /usr/local/bin
sudo ln -sf "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl
```
## Design Goals
This configuration aims to be:
- Modular
- Portable across Linux and macOS
- Safe to version-control
- Friendly to private machine-local overrides
- Predictable about `PATH` ordering
- Minimal enough to debug when something goes wrong

63
aliases.zsh

@ -0,0 +1,63 @@
# Alias
if [[ "$OS_TYPE" != "gnu-linux" ]]; then
alias python='python3'
fi
# rlwrap provides readline wrapping for programs.
# This alias makes the SBCL REPL usable.
alias sbcl='rlwrap sbcl'
# Useful git aliases
alias gita='git add'
alias gitap='git add -p'
alias gitc='git commit'
alias gitp='git push'
alias gits='git status'
alias gitd='git diff'
alias k8='kubectl'
# Good overrides
alias ls='ls --color=auto'
alias grep='grep --colour=auto'
alias egrep='egrep --colour=auto'
alias fgrep='fgrep --colour=auto'
# Don't nuke the computer
alias rm='rm -i'
# Confirm before overwriting
alias cp='cp -i'
# Default free to sizes in megabytes
alias free='free -m'
# Better ls - lists more information for each file
alias ll='ls -lh'
# Less is a better more
alias more=less
# df in human readable sizes
alias df='df -h'
# I use Neovim
if [ -x "$(command -v nvim)" ]; then
alias vim=nvim
fi
# Human readable ls for the current directory
if [[ "$OS_TYPE" != "gnu-linux" ]]; then
# OS X lt
alias lt='du -sh * | sort -h'
else
alias lt='ls --human-readable --size -1 -S --classify'
fi
# Count files in the current directory
alias count='find . -type f | wc -l'
# Generate sha1 hashes on the fly
alias sha1='openssl sha1'

76
exports.zsh

@ -0,0 +1,76 @@
#!/bin/zsh
# -------------------------
# Editor
# -------------------------
if command -v vim >/dev/null 2>&1; then
export EDITOR=vim
else
export EDITOR=vi
fi
# -------------------------
# C / C++ compiler defaults
# -------------------------
if command -v clang >/dev/null 2>&1; then
export CC="$(command -v clang)"
elif command -v gcc >/dev/null 2>&1; then
export CC="$(command -v gcc)"
fi
if command -v clang++ >/dev/null 2>&1; then
export CXX="$(command -v clang++)"
elif command -v g++ >/dev/null 2>&1; then
export CXX="$(command -v g++)"
fi
# -------------------------
# History
# -------------------------
# Note: HISTCONTROL is bash-specific, but harmless.
# ZSH history dedupe should usually be configured with setopt elsewhere.
export HISTCONTROL=ignoredups
# -------------------------
# User paths
# -------------------------
path=("$HOME/bin" $path)
path=("$HOME/.local/bin" $path)
# -------------------------
# Go
# -------------------------
if command -v go >/dev/null 2>&1; then
export GOPATH="$HOME/.go"
path=("$(go env GOPATH)/bin" $path)
fi
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# If the Go install guide was followed for Linux,
# /usr/local/go will contain the go binary.
[[ -d "/usr/local/go/bin" ]] && path=("/usr/local/go/bin" $path)
fi
# -------------------------
# Ruby / RVM
# -------------------------
if [[ -d "$HOME/.rvm/bin" ]]; then
path=("$HOME/.rvm/bin" $path)
fi
# -----------------------------
# Rust / Cargo - Let rustup win
# -----------------------------
if [[ -f "$HOME/.cargo/env" ]]; then
. "$HOME/.cargo/env"
fi
if [[ -d "$HOME/.cargo/bin" ]]; then
path=("$HOME/.cargo/bin" $path)
fi
# -------------------------
# OpenSSL fallback
# -------------------------
if command -v openssl >/dev/null 2>&1; then
export OPENSSL_BIN="$(command -v openssl)"
fi

12
functions.zsh

@ -0,0 +1,12 @@
#!/usr/zsh
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
# If you ever needed weather...
weather() {
curl wttr.in
}

19
initializations.zsh

@ -0,0 +1,19 @@
#!/bin/zsh
if [[ "$OSTYPE" == linux-gnu* ]]; then
export PATH="/usr/local/bin:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
[[ -d "$PYENV_ROOT/bin" ]] && export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv >/dev/null 2>&1; then
eval "$(pyenv init -)"
if pyenv commands | grep -qx "virtualenv-init"; then
eval "$(pyenv virtualenv-init -)"
fi
fi
fi
# RVM configuration
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

3
keybinds.zsh

@ -0,0 +1,3 @@
if command -v setxkbmap >/dev/null 2>&1 && [[ "$XDG_SESSION_TYPE" == "x11" ]]; then
setxkbmap -option caps:escape
fi

51
macrc

@ -0,0 +1,51 @@
#!/bin/zsh
# -------------------------
# macOS-specific setup
# -------------------------
# Prefer Apple Silicon Homebrew, fall back to Intel Homebrew.
if [[ -d "/opt/homebrew" ]]; then
export HOMEBREW_PREFIX="/opt/homebrew"
elif [[ -d "/usr/local/Homebrew" || -d "/usr/local/Cellar" ]]; then
export HOMEBREW_PREFIX="/usr/local"
fi
if [[ -n "$HOMEBREW_PREFIX" ]]; then
[[ -d "$HOMEBREW_PREFIX/bin" ]] && path=("$HOMEBREW_PREFIX/bin" $path)
[[ -d "$HOMEBREW_PREFIX/sbin" ]] && path=("$HOMEBREW_PREFIX/sbin" $path)
# LLVM / clangd / clang-format
if [[ -d "$HOMEBREW_PREFIX/opt/llvm/bin" ]]; then
path=("$HOMEBREW_PREFIX/opt/llvm/bin" $path)
export LDFLAGS="-L$HOMEBREW_PREFIX/opt/llvm/lib ${LDFLAGS:-}"
export CPPFLAGS="-I$HOMEBREW_PREFIX/opt/llvm/include ${CPPFLAGS:-}"
fi
# OpenSSL
if [[ -d "$HOMEBREW_PREFIX/opt/openssl@3" ]]; then
export OPENSSL_ROOT_DIR="$HOMEBREW_PREFIX/opt/openssl@3"
export LDFLAGS="-L$OPENSSL_ROOT_DIR/lib ${LDFLAGS:-}"
export CPPFLAGS="-I$OPENSSL_ROOT_DIR/include ${CPPFLAGS:-}"
export PKG_CONFIG_PATH="$OPENSSL_ROOT_DIR/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
elif [[ -d "$HOMEBREW_PREFIX/opt/openssl" ]]; then
export OPENSSL_ROOT_DIR="$HOMEBREW_PREFIX/opt/openssl"
export LDFLAGS="-L$OPENSSL_ROOT_DIR/lib ${LDFLAGS:-}"
export CPPFLAGS="-I$OPENSSL_ROOT_DIR/include ${CPPFLAGS:-}"
export PKG_CONFIG_PATH="$OPENSSL_ROOT_DIR/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
fi
# OpenJDK
[[ -d "$HOMEBREW_PREFIX/opt/openjdk/bin" ]] && path=("$HOMEBREW_PREFIX/opt/openjdk/bin" $path)
# Qt
[[ -d "$HOMEBREW_PREFIX/opt/qt/bin" ]] && path=("$HOMEBREW_PREFIX/opt/qt/bin" $path)
# Tcl/Tk
[[ -d "$HOMEBREW_PREFIX/opt/tcl-tk/bin" ]] && path=("$HOMEBREW_PREFIX/opt/tcl-tk/bin" $path)
fi
# Ghostty CLI
if [[ -d "/Applications/Ghostty.app/Contents/MacOS" ]]; then
path=("/Applications/Ghostty.app/Contents/MacOS" $path)
fi

10
ps1.zsh

@ -0,0 +1,10 @@
#!/bin/zsh
setopt prompt_subst
autoload -Uz vcs_info
precmd () { vcs_info }
# Format = [<branch>]
zstyle ':vcs_info:*' formats ' %F{green}[%b]%f'
PS1='%B%n@%m%b %F{blue}%2~%f${vcs_info_msg_0_} %B⇨%b '

109
scripts/cgen.sh

@ -0,0 +1,109 @@
#! /usr/bin/env bash
name=$1
cmake_version=$2
c_standard=$3
# Finds the directory of this script
if [[ "$OS_TYPE" == "linux-gnu" ]]; then
script_dir=$(cd "$( dirname "`readlink -f ${BASH_SOURCE[0]}`")" && pwd)
else
script_dir=$(cd "$( dirname "`greadlink -f ${BASH_SOURCE[0]}`")" && pwd)
fi
if [ -z $name ]
then
echo "Name must be specified"
echo ""
echo "./cgen.sh <name> [cmake version] [C Standard]"
exit -1
fi
if [ -z $cmake_version ]
then
echo "No CMake version supplied...defaulting to 3.15"
cmake_version="3.15"
fi
if [ -z $c_standard ]
then
echo "No C Standard supplied...defaulting to 11"
c_standard="11"
fi
mkdir $name
mkdir $name/src
mkdir $name/include
cmake_config=$name/CMakeLists.txt
touch $cmake_config
echo "cmake_minimum_required(VERSION $cmake_version)" >> $cmake_config
echo "project($name)" >> $cmake_config
echo "" >> $cmake_config
echo "set (CMAKE_C_STANDARD $c_standard)" >> $cmake_config
echo "" >> $cmake_config
echo "# Output to bin and lib" >> $cmake_config
echo "set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \${CMAKE_BINARY_DIR}/lib)" >> $cmake_config
echo "set(CMAKE_LIBRARY_OUTPUT_DIRECTORY \${CMAKE_BINARY_DIR}/lib)" >> $cmake_config
echo "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \${CMAKE_BINARY_DIR}/bin)" >> $cmake_config
echo "" >> $cmake_config
echo "" >> $cmake_config
echo "# The following lines enable compile_commands.json and dump it in the root of the project" >> $cmake_config
echo "# This is needed for clangd and lsp to work" >> $cmake_config
echo "" >> $cmake_config
echo "set(CMAKE_EXPORT_COMPILE_COMMANDS ON)" >> $cmake_config
echo "" >> $cmake_config
echo "if(EXISTS \"\${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json\")" >> $cmake_config
echo " execute_process(COMMAND \${CMAKE_COMMAND} -E copy_if_different" >> $cmake_config
echo " \${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json" >> $cmake_config
echo " \${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json" >> $cmake_config
echo " )" >> $cmake_config
echo "endif()" >> $cmake_config
echo "#-------- END COMPILE_COMMANDS.JSON SECTION --------#" >> $cmake_config
echo "" >> $cmake_config
echo "" >> $cmake_config
echo "file(GLOB SOURCE \${PROJECT_SOURCE_DIR}/src/*.c)" >> $cmake_config
echo "file(GLOB INCLUDE \${PROJECT_SOURCE_DIR}/include/*.h)" >> $cmake_config
echo "" >> $cmake_config
echo "" >> $cmake_config
echo "include_directories(\${PROJECT_SOURCE_DIR}/include)" >> $cmake_config
echo "" >> $cmake_config
echo "" >> $cmake_config
echo "# Controls debug printing based on the compiled binary mode - check with #ifdef DEBUG_BUILD" >> $cmake_config
echo "IF(CMAKE_BUILD_TYPE MATCHES DEBUG)" >> $cmake_config
echo "message(\"-- Configuring debug build...\")" >> $cmake_config
echo "add_compile_definitions(DEBUG_BUILD)" >> $cmake_config
echo "ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG)" >> $cmake_config
echo "" >> $cmake_config
echo "add_executable(\${PROJECT_NAME} \${SOURCE} \${INCLUDE})" >> $cmake_config
echo "Copying .clang-format..."
cp $script_dir/cgen_etc/clang_format_template $name/.clang-format
echo "Copying .gitignore..."
cp $script_dir/cgen_etc/gitignore_template $name/.gitignore
sample_file=$name/src/main.c
echo "#include <stdio.h>" >> $sample_file
echo "" >> $sample_file
echo "" >> $sample_file
echo "int main(int argc, char **argv)" >> $sample_file
echo "{" >> $sample_file
echo " printf(\"Hello, world!\\n\");" >> $sample_file
echo " return 0;" >> $sample_file
echo "}" >> $sample_file
echo "" >> $sample_file
git --version 2>&1 >/dev/null
GIT_IS_AVAILABLE=$?
if [ $GIT_IS_AVAILABLE -eq 0 ]
then
git init $name
fi
echo "Created project $name."

16
scripts/cgen_etc/clang_format_template

@ -0,0 +1,16 @@
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: 'true'
AlignConsecutiveAssignments: 'true'
AlignConsecutiveDeclarations: 'true'
AlignTrailingComments: 'true'
BreakBeforeBraces: Allman
IndentCaseLabels: 'true'
IndentWidth: '4'
Language: Cpp
PointerAlignment: Right
SortIncludes: 'true'
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: 'true'
SpaceInEmptyParentheses: 'false'
UseTab: Never
ColumnLimit: 80

97
scripts/cgen_etc/gitignore_template

@ -0,0 +1,97 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Vim
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
# CMake
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

2
zprofile

@ -0,0 +1,2 @@
#!/bin/zsh

230
zshrc

@ -0,0 +1,230 @@
#!/bin/zsh
# -------------------------
# Resolve this config's real directory
# -------------------------
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
symlink_dir="$(cd "$(dirname "$(readlink -f "${(%):-%N}")")" && pwd)"
else
# macOS does not ship GNU readlink -f by default.
symlink_dir="$(cd "$(dirname "$(readlink "${(%):-%N}")")" && pwd)"
fi
# -------------------------
# Private, machine-local configuration
# -------------------------
# These files are intentionally not part of this repository.
# Use them for secrets, tokens, private exports, work paths, and host-specific setup.
[[ -f "$HOME/.bash_private" ]] && source "$HOME/.bash_private"
[[ -f "$HOME/.private" ]] && source "$HOME/.private"
[[ -f "$HOME/.zsh_private" ]] && source "$HOME/.zsh_private"
# Do not source ~/.inputrc here.
# It is a readline config file, not shell code.
# -------------------------
# OS-specific configuration
# -------------------------
if [[ "$OSTYPE" == "darwin"* ]]; then
[[ -f "$HOME/.macrc" ]] && source "$HOME/.macrc"
fi
# -------------------------
# Local directories
# -------------------------
if [[ ! -d "$HOME/projects" ]]; then
echo "Making $HOME/projects"
mkdir -p "$HOME/projects"
fi
if command -v go >/dev/null 2>&1; then
mkdir -p "$HOME/.go"
fi
# -------------------------
# Git completion
# -------------------------
# Auto-installs Git completion files from a pinned Git commit.
# This avoids fetching from a moving branch like master.
#
# To fill in the placeholders:
#
# cd /tmp
# git clone https://github.com/git/git.git git-src
# cd git-src
# git checkout v2.45.2
# git rev-parse HEAD
# shasum -a 256 contrib/completion/git-completion.bash
# shasum -a 256 contrib/completion/git-completion.zsh
#
# Then paste the commit and hashes below.
ZSH_CACHE_DIR="$HOME/.zsh"
mkdir -p "$ZSH_CACHE_DIR"
GIT_COMPLETION_COMMIT="bea9ecd24b0c3bf06cab4a851694fe09e7e51408"
GIT_COMPLETION_BASH_URL="https://raw.githubusercontent.com/git/git/${GIT_COMPLETION_COMMIT}/contrib/completion/git-completion.bash"
GIT_COMPLETION_ZSH_URL="https://raw.githubusercontent.com/git/git/${GIT_COMPLETION_COMMIT}/contrib/completion/git-completion.zsh"
GIT_COMPLETION_BASH_FILE="$ZSH_CACHE_DIR/git-completion.bash"
GIT_COMPLETION_ZSH_FILE="$ZSH_CACHE_DIR/_git"
GIT_COMPLETION_BASH_SHA256="e667d8fdc0f0071833c94ccb2565a503bf413da0ae28d74efe2e70e2beb1c4c6"
GIT_COMPLETION_ZSH_SHA256="f6075d283250785edcf09281992bde6b4bcc43eb2dca74488d880a52f7659c09"
_zshv2_sha256() {
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "$1" | awk '{print $1}'
elif command -v shasum >/dev/null 2>&1; then
shasum -a 256 "$1" | awk '{print $1}'
else
echo "No SHA-256 tool found. Need sha256sum or shasum." >&2
return 1
fi
}
_zshv2_file_has_sha256() {
local file="$1"
local expected_sha="$2"
local actual_sha
[[ -f "$file" ]] || return 1
actual_sha="$(_zshv2_sha256 "$file")" || return 1
[[ "$actual_sha" == "$expected_sha" ]]
}
_zshv2_install_verified_file() {
local name="$1"
local url="$2"
local dest="$3"
local expected_sha="$4"
local tmp_file
local actual_sha
if [[ -z "$url" || -z "$dest" || -z "$expected_sha" ]]; then
echo "Git completion install misconfigured for $name." >&2
return 1
fi
if _zshv2_file_has_sha256 "$dest" "$expected_sha"; then
return 0
fi
if ! command -v curl >/dev/null 2>&1; then
echo "curl is required to install $name." >&2
return 1
fi
tmp_file="$(mktemp "${dest}.tmp.XXXXXX")" || return 1
if ! curl --fail --location --silent --show-error --output "$tmp_file" "$url"; then
echo "Failed to download $name from $url" >&2
rm -f "$tmp_file"
return 1
fi
actual_sha="$(_zshv2_sha256 "$tmp_file")" || {
rm -f "$tmp_file"
return 1
}
if [[ "$actual_sha" != "$expected_sha" ]]; then
echo "SHA-256 mismatch for $name." >&2
echo "Expected: $expected_sha" >&2
echo "Actual: $actual_sha" >&2
rm -f "$tmp_file"
return 1
fi
mv "$tmp_file" "$dest"
}
_zshv2_install_git_completion() {
_zshv2_install_verified_file \
"git-completion.bash" \
"$GIT_COMPLETION_BASH_URL" \
"$GIT_COMPLETION_BASH_FILE" \
"$GIT_COMPLETION_BASH_SHA256"
_zshv2_install_verified_file \
"git-completion.zsh" \
"$GIT_COMPLETION_ZSH_URL" \
"$GIT_COMPLETION_ZSH_FILE" \
"$GIT_COMPLETION_ZSH_SHA256"
}
_zshv2_install_git_completion
if [[ -f "$GIT_COMPLETION_BASH_FILE" ]]; then
zstyle ':completion:*:*:git:*' script "$GIT_COMPLETION_BASH_FILE"
fi
fpath=("$ZSH_CACHE_DIR" $fpath)
autoload -Uz compinit
compinit
# -------------------------
# Pull in modular config
# -------------------------
source "$symlink_dir/aliases.zsh"
source "$symlink_dir/functions.zsh"
source "$symlink_dir/exports.zsh"
source "$symlink_dir/initializations.zsh"
source "$symlink_dir/ps1.zsh"
source "$symlink_dir/keybinds.zsh"
# -------------------------
# Language/tool initialization
# -------------------------
# Rust
[[ -f "$HOME/.cargo/env" ]] && source "$HOME/.cargo/env"
# Haskell / GHCup
[[ -f "$HOME/.ghcup/env" ]] && source "$HOME/.ghcup/env"
# OCaml / opam
[[ -r "$HOME/.opam/opam-init/init.sh" ]] && . "$HOME/.opam/opam-init/init.sh" >/dev/null 2>/dev/null || true
# -------------------------
# ZSH syntax highlighting
# -------------------------
# This still supports an existing local clone under:
#
# $HOME/.zsh/zsh-syntax-highlighting
#
# But it does not automatically clone during shell startup.
# Install with:
#
# brew install zsh-syntax-highlighting
#
# or:
#
# sudo apt install zsh-syntax-highlighting
#
# It must be sourced last.
if [[ -f "$HOME/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]]; then
source "$HOME/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
elif [[ -f "/opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]]; then
source "/opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
elif [[ -f "/usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]]; then
source "/usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
elif [[ -f "/usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]]; then
source "/usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
fi
# -------------------------
# Deduplicate PATH
# -------------------------
typeset -U path PATH
Loading…
Cancel
Save