Add README and shell polish
This commit is contained in:
337
README.md
337
README.md
@@ -0,0 +1,337 @@
|
|||||||
|
# Dot-Zsh
|
||||||
|
|
||||||
|
Personal cross-platform shell and workstation bootstrap for:
|
||||||
|
|
||||||
|
- Arch Linux
|
||||||
|
- Ubuntu / Debian-family Linux
|
||||||
|
- Fedora
|
||||||
|
- macOS
|
||||||
|
- WSL
|
||||||
|
|
||||||
|
The repo is built around a small bootstrap path and a fuller `just`-based workflow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── Bins/ # Pinned binary versions (nvim, eza, ...)
|
||||||
|
├── Commands/ # just modules
|
||||||
|
├── Scripts/ # install/setup scripts
|
||||||
|
├── Zsh/ # stowed shell files
|
||||||
|
├── Justfile # main just entrypoint
|
||||||
|
└── Makefile # lightweight bootstrap entrypoint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key folders
|
||||||
|
|
||||||
|
#### `Zsh/`
|
||||||
|
|
||||||
|
Stowed into `$HOME`.
|
||||||
|
|
||||||
|
- `.zshrc`
|
||||||
|
- `.zshenv`
|
||||||
|
- `.zsh_aliases`
|
||||||
|
- `.zsh_prompt`
|
||||||
|
- `.zsh_completion`
|
||||||
|
- `.zsh_secrets`
|
||||||
|
- `.zsh_secrets.example`
|
||||||
|
|
||||||
|
#### `Scripts/`
|
||||||
|
|
||||||
|
Main install logic.
|
||||||
|
|
||||||
|
- `base.sh` — system/base packages and common tools
|
||||||
|
- `setup.sh` — full setup flow
|
||||||
|
- `node.sh`, `go.sh`, `rust.sh`, `python.sh`, `r.sh`, `cpp.sh`
|
||||||
|
- `bin/install.sh` — install pinned repo-managed binaries
|
||||||
|
- `bin/update.sh` — update pinned binary versions
|
||||||
|
|
||||||
|
#### `Commands/`
|
||||||
|
|
||||||
|
Modular `just` commands.
|
||||||
|
|
||||||
|
- `Commands/Setup/mod.just`
|
||||||
|
- `Commands/Lang/mod.just`
|
||||||
|
- `Commands/Bin/mod.just`
|
||||||
|
|
||||||
|
#### `Bins/`
|
||||||
|
|
||||||
|
`versions.json` is the source of truth for pinned binary versions and per-platform asset mappings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Core workflow
|
||||||
|
|
||||||
|
### Bootstrap only
|
||||||
|
|
||||||
|
Use `make setup` when you want the lightweight bootstrap path:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make setup
|
||||||
|
```
|
||||||
|
|
||||||
|
This currently does:
|
||||||
|
|
||||||
|
1. run `Scripts/base.sh`
|
||||||
|
2. remove old `Zsh` stow links
|
||||||
|
3. stow `Zsh/` into `$HOME`
|
||||||
|
|
||||||
|
It is intentionally small.
|
||||||
|
|
||||||
|
### Full setup
|
||||||
|
|
||||||
|
Use `just setup all` for the full machine setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just setup all
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs the full flow in `Scripts/setup.sh`:
|
||||||
|
|
||||||
|
1. base system setup
|
||||||
|
2. node
|
||||||
|
3. go / gvm
|
||||||
|
4. rust
|
||||||
|
5. python / pyenv / miniforge
|
||||||
|
6. r
|
||||||
|
7. secret-file reconciliation
|
||||||
|
8. backup of conflicting unmanaged dotfiles
|
||||||
|
9. stow `Zsh/`
|
||||||
|
|
||||||
|
### Other useful commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just setup base
|
||||||
|
just setup stow
|
||||||
|
just setup clean
|
||||||
|
just setup update
|
||||||
|
|
||||||
|
just lang node
|
||||||
|
just lang go
|
||||||
|
just lang rust
|
||||||
|
just lang python
|
||||||
|
just lang r
|
||||||
|
just lang cpp
|
||||||
|
|
||||||
|
just bin show
|
||||||
|
just bin install-all
|
||||||
|
just bin install nvim
|
||||||
|
just bin list nvim
|
||||||
|
just bin update nvim
|
||||||
|
```
|
||||||
|
|
||||||
|
If `fzf` is available, `just bin update <tool>` can use interactive selection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets model
|
||||||
|
|
||||||
|
This repo now treats shell secrets as repo-managed local dotfiles instead of tracked plaintext config.
|
||||||
|
|
||||||
|
### Source of truth
|
||||||
|
|
||||||
|
```text
|
||||||
|
Zsh/.zsh_secrets
|
||||||
|
```
|
||||||
|
|
||||||
|
That file is intended to be stowed to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
$HOME/.zsh_secrets
|
||||||
|
```
|
||||||
|
|
||||||
|
### Important notes
|
||||||
|
|
||||||
|
- `.zsh_secrets` is ignored by git
|
||||||
|
- `.zsh_secrets.example` exists as a template/reference
|
||||||
|
- setup tries to reconcile an existing `$HOME/.zsh_secrets` safely
|
||||||
|
- if conflicting unmanaged dotfiles already exist, setup backs them up before stowing
|
||||||
|
|
||||||
|
Backup location:
|
||||||
|
|
||||||
|
```text
|
||||||
|
~/.dotzsh-pre-stow-backup/<timestamp>/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Binary management
|
||||||
|
|
||||||
|
This repo no longer stores shipped binaries in git.
|
||||||
|
|
||||||
|
Instead:
|
||||||
|
|
||||||
|
- pinned versions live in `Bins/versions.json`
|
||||||
|
- installs go into `~/.local/bin`
|
||||||
|
- updates happen through `just bin update <tool>`
|
||||||
|
|
||||||
|
Current managed binaries include:
|
||||||
|
|
||||||
|
- `nvim`
|
||||||
|
- `eza`
|
||||||
|
|
||||||
|
Platform behavior:
|
||||||
|
|
||||||
|
- Linux: install from pinned release assets
|
||||||
|
- macOS: install from pinned asset when supported, or use Homebrew formula fallback when configured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shell behavior
|
||||||
|
|
||||||
|
### Prompt
|
||||||
|
|
||||||
|
Prompt logic lives in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Zsh/.zsh_prompt
|
||||||
|
```
|
||||||
|
|
||||||
|
It adds:
|
||||||
|
|
||||||
|
- git branch
|
||||||
|
- git dirty/clean indicator
|
||||||
|
- conda / direnv context
|
||||||
|
- repo-scoped project markers
|
||||||
|
- language version hints
|
||||||
|
- separator rule between prompts
|
||||||
|
|
||||||
|
### Completion
|
||||||
|
|
||||||
|
Completion logic lives in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Zsh/.zsh_completion
|
||||||
|
```
|
||||||
|
|
||||||
|
It adds:
|
||||||
|
|
||||||
|
- custom first-word command completion
|
||||||
|
- recently used commands shown first
|
||||||
|
- used commands visually marked with `*`
|
||||||
|
- wrapper completion bindings for lazy-loaded tools like `gvm`, `conda`, `go`, `node`, `npm`, and `npx`
|
||||||
|
|
||||||
|
### Lazy loading
|
||||||
|
|
||||||
|
Several language managers are intentionally lazy-loaded to keep shell startup lighter.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `nvm`
|
||||||
|
- `gvm`
|
||||||
|
- `pyenv`
|
||||||
|
- `conda`
|
||||||
|
|
||||||
|
`openchamber` auto-start is restricted to WSL sessions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Install size
|
||||||
|
|
||||||
|
Measured practical installed footprint on Linux is roughly:
|
||||||
|
|
||||||
|
- Ubuntu: about `1.96 GB`
|
||||||
|
- Arch: about `1.84 GB`
|
||||||
|
- Fedora: about `1.77 GB`
|
||||||
|
|
||||||
|
So the setup is best thought of as:
|
||||||
|
|
||||||
|
```text
|
||||||
|
~1.8 GB to ~2.0 GB total
|
||||||
|
```
|
||||||
|
|
||||||
|
### Largest components
|
||||||
|
|
||||||
|
Measured Ubuntu component breakdown:
|
||||||
|
|
||||||
|
- Rust: about `1.5 GB`
|
||||||
|
- Python: about `1.1 GB`
|
||||||
|
- Go: about `635 MB`
|
||||||
|
- Node: about `235 MB`
|
||||||
|
- `~/.local`: about `128 MB`
|
||||||
|
- R wrapper/user area under `~/.programming/r`: very small (`~20 KB` in that measurement)
|
||||||
|
|
||||||
|
Important nuance:
|
||||||
|
|
||||||
|
- `~/.programming/r` is intentionally small because it mainly holds wrappers and user-library location
|
||||||
|
- the actual R runtime may still come from the distro package manager or Rig, depending on platform
|
||||||
|
- so not all R-related disk usage appears under `~/.programming/r`
|
||||||
|
|
||||||
|
### Measured paths
|
||||||
|
|
||||||
|
Representative measured path sizes from Linux test runs:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Ubuntu
|
||||||
|
~/.programming ~3.17 GB
|
||||||
|
~/.local ~133 MB
|
||||||
|
/usr/local ~13 MB
|
||||||
|
|
||||||
|
Arch
|
||||||
|
~/.programming ~3.17 GB
|
||||||
|
~/.local ~133 MB
|
||||||
|
|
||||||
|
Fedora
|
||||||
|
~/.programming ~3.17 GB
|
||||||
|
~/.local ~133 MB
|
||||||
|
```
|
||||||
|
|
||||||
|
Those path totals are larger than the final container image delta because some space is shared/overlapping across package layers and installed tooling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes by platform
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
- full setup has been exercised in container tests on Ubuntu, Arch, and Fedora x86_64
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
- supports Homebrew-based package install flow
|
||||||
|
- uses `/bin/zsh` for shell-change target
|
||||||
|
- handles existing dotfiles and secret symlink reconciliation more carefully
|
||||||
|
|
||||||
|
### WSL
|
||||||
|
|
||||||
|
- WSL-specific logic is used where needed
|
||||||
|
- `openchamber` is only auto-started in WSL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## First-run recommendation
|
||||||
|
|
||||||
|
If you are starting clean:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make setup
|
||||||
|
just setup all
|
||||||
|
```
|
||||||
|
|
||||||
|
If you only want shell files re-linked:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just setup clean
|
||||||
|
just setup stow
|
||||||
|
```
|
||||||
|
|
||||||
|
If you only want to refresh pinned binaries:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just bin install-all
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current philosophy
|
||||||
|
|
||||||
|
This repo aims to be:
|
||||||
|
|
||||||
|
- owned rather than magical
|
||||||
|
- reproducible rather than ad hoc
|
||||||
|
- modular rather than one giant dotfile blob
|
||||||
|
- explicit about pinned binaries and local secrets
|
||||||
|
|
||||||
|
It is not trying to be the smallest possible install. It is trying to be a repeatable personal workstation setup.
|
||||||
|
|||||||
175
Zsh/.zsh_completion
Normal file
175
Zsh/.zsh_completion
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# Completion behavior and wrapper bindings
|
||||||
|
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
|
||||||
|
if ! whence -w compdef >/dev/null 2>&1; then
|
||||||
|
autoload -Uz compinit
|
||||||
|
compinit -i >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
zmodload zsh/complist 2>/dev/null || true
|
||||||
|
|
||||||
|
zstyle ':completion:*' menu select
|
||||||
|
zstyle ':completion:*' verbose yes
|
||||||
|
zstyle ':completion:*' list-grouped yes
|
||||||
|
zstyle ':completion:*:descriptions' format '%F{240}%B%d%b%f'
|
||||||
|
|
||||||
|
typeset -ga DOTZSH_USED_COMMANDS
|
||||||
|
typeset -ga DOTZSH_ALL_COMMANDS
|
||||||
|
typeset -gA DOTZSH_USED_COMMAND_MAP
|
||||||
|
typeset -gA DOTZSH_ALL_COMMAND_MAP
|
||||||
|
typeset -g DOTZSH_USED_COMMANDS_INITIALIZED=0
|
||||||
|
typeset -g DOTZSH_ALL_COMMANDS_INITIALIZED=0
|
||||||
|
typeset -g DOTZSH_USED_COMMAND_LIMIT=120
|
||||||
|
|
||||||
|
_dotzsh_parse_history_line() {
|
||||||
|
local raw_line="$1"
|
||||||
|
local parsed_line="$raw_line"
|
||||||
|
|
||||||
|
case "$parsed_line" in
|
||||||
|
': '*';'*)
|
||||||
|
parsed_line="${parsed_line#*;}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
print -r -- "$parsed_line"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotzsh_extract_command_name() {
|
||||||
|
local line="$(_dotzsh_parse_history_line "$1")"
|
||||||
|
local command_name=""
|
||||||
|
local -a parts=()
|
||||||
|
local index=1
|
||||||
|
|
||||||
|
[ -n "$line" ] || return 1
|
||||||
|
[[ "$line" == '#'* ]] && return 1
|
||||||
|
|
||||||
|
parts=(${(z)line})
|
||||||
|
[ "${#parts[@]}" -gt 0 ] || return 1
|
||||||
|
|
||||||
|
while [ "$index" -le "${#parts[@]}" ]; do
|
||||||
|
command_name="${parts[$index]}"
|
||||||
|
|
||||||
|
case "$command_name" in
|
||||||
|
sudo|time|command|builtin|noglob|env)
|
||||||
|
((index++))
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*=*)
|
||||||
|
((index++))
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -n "$command_name" ] || return 1
|
||||||
|
[[ "$command_name" == _* ]] && return 1
|
||||||
|
[[ "$command_name" =~ '^[A-Za-z0-9][A-Za-z0-9+._-]*$' ]] || return 1
|
||||||
|
|
||||||
|
print -r -- "$command_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotzsh_remember_command() {
|
||||||
|
local command_name="$1"
|
||||||
|
|
||||||
|
[ -n "$command_name" ] || return 0
|
||||||
|
|
||||||
|
DOTZSH_USED_COMMANDS=(${DOTZSH_USED_COMMANDS:#$command_name})
|
||||||
|
DOTZSH_USED_COMMANDS=("$command_name" "${DOTZSH_USED_COMMANDS[@]}")
|
||||||
|
DOTZSH_USED_COMMAND_MAP[$command_name]=1
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotzsh_initialize_used_commands() {
|
||||||
|
local history_file="${HISTFILE:-$HOME/.zsh_history}"
|
||||||
|
local line=""
|
||||||
|
local command_name=""
|
||||||
|
|
||||||
|
[ "$DOTZSH_USED_COMMANDS_INITIALIZED" -eq 0 ] || return 0
|
||||||
|
|
||||||
|
DOTZSH_USED_COMMANDS=()
|
||||||
|
DOTZSH_USED_COMMAND_MAP=()
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
command_name="$(_dotzsh_extract_command_name "$line")" || continue
|
||||||
|
[[ -n ${DOTZSH_USED_COMMAND_MAP[$command_name]:-} ]] && continue
|
||||||
|
DOTZSH_USED_COMMANDS+=("$command_name")
|
||||||
|
DOTZSH_USED_COMMAND_MAP[$command_name]=1
|
||||||
|
[ "${#DOTZSH_USED_COMMANDS[@]}" -lt "$DOTZSH_USED_COMMAND_LIMIT" ] || break
|
||||||
|
done < <(
|
||||||
|
if [ -r "$history_file" ]; then
|
||||||
|
tac "$history_file" 2>/dev/null || tail -r "$history_file" 2>/dev/null || cat "$history_file"
|
||||||
|
else
|
||||||
|
fc -lnr 1 2>/dev/null
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
|
||||||
|
DOTZSH_USED_COMMANDS_INITIALIZED=1
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotzsh_initialize_all_commands() {
|
||||||
|
local command_name=""
|
||||||
|
|
||||||
|
[ "$DOTZSH_ALL_COMMANDS_INITIALIZED" -eq 0 ] || return 0
|
||||||
|
|
||||||
|
DOTZSH_ALL_COMMANDS=()
|
||||||
|
DOTZSH_ALL_COMMAND_MAP=()
|
||||||
|
|
||||||
|
for command_name in ${(k)aliases} ${(k)builtins} ${(k)commands} ${(k)functions}; do
|
||||||
|
[ -n "$command_name" ] || continue
|
||||||
|
[[ "$command_name" == _* ]] && continue
|
||||||
|
[[ -n ${DOTZSH_ALL_COMMAND_MAP[$command_name]:-} ]] && continue
|
||||||
|
DOTZSH_ALL_COMMANDS+=("$command_name")
|
||||||
|
DOTZSH_ALL_COMMAND_MAP[$command_name]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
DOTZSH_ALL_COMMANDS_INITIALIZED=1
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotzsh_record_command() {
|
||||||
|
local command_name=""
|
||||||
|
|
||||||
|
command_name="$(_dotzsh_extract_command_name "$1")" || return 0
|
||||||
|
_dotzsh_remember_command "$command_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotzsh_command_menu() {
|
||||||
|
local command_name=""
|
||||||
|
local -a other_commands=()
|
||||||
|
local -a filtered_used_commands=()
|
||||||
|
local -a used_display=()
|
||||||
|
local current_prefix="$PREFIX"
|
||||||
|
|
||||||
|
_dotzsh_initialize_used_commands
|
||||||
|
_dotzsh_initialize_all_commands
|
||||||
|
|
||||||
|
for command_name in "${DOTZSH_USED_COMMANDS[@]}"; do
|
||||||
|
[[ -n ${DOTZSH_ALL_COMMAND_MAP[$command_name]:-} ]] || continue
|
||||||
|
[ -z "$current_prefix" ] || [[ "$command_name" == ${~current_prefix}* ]] || continue
|
||||||
|
filtered_used_commands+=("$command_name")
|
||||||
|
used_display+=("* $command_name")
|
||||||
|
done
|
||||||
|
|
||||||
|
for command_name in "${DOTZSH_ALL_COMMANDS[@]}"; do
|
||||||
|
[[ -n ${DOTZSH_USED_COMMAND_MAP[$command_name]:-} ]] && continue
|
||||||
|
[ -z "$current_prefix" ] || [[ "$command_name" == ${~current_prefix}* ]] || continue
|
||||||
|
other_commands+=("$command_name")
|
||||||
|
done
|
||||||
|
|
||||||
|
[ "${#filtered_used_commands[@]}" -eq 0 ] || compadd -Q -U -o nosort -d used_display -- "${filtered_used_commands[@]}"
|
||||||
|
[ "${#other_commands[@]}" -eq 0 ] || compadd -Q -U -o nosort -- "${other_commands[@]}"
|
||||||
|
|
||||||
|
[ "${#filtered_used_commands[@]}" -gt 0 ] || [ "${#other_commands[@]}" -gt 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
compdef _dotzsh_command_menu -command-
|
||||||
|
add-zsh-hook preexec _dotzsh_record_command
|
||||||
|
|
||||||
|
autoload -Uz _gvm _conda _go _node _npm _npx 2>/dev/null
|
||||||
|
compdef _gvm gvm
|
||||||
|
compdef _go go gofmt
|
||||||
|
compdef _conda conda
|
||||||
|
compdef _node node
|
||||||
|
compdef _npm npm
|
||||||
|
compdef _npx npx
|
||||||
@@ -7,6 +7,10 @@ zstyle ':vcs_info:git:*' formats ' %b'
|
|||||||
|
|
||||||
typeset -g PROMPT_SHOW_SPACER=0
|
typeset -g PROMPT_SHOW_SPACER=0
|
||||||
typeset -gA PROMPT_PROJECT_MATCH_CACHE
|
typeset -gA PROMPT_PROJECT_MATCH_CACHE
|
||||||
|
typeset -gA PROMPT_VERSION_CACHE
|
||||||
|
typeset -g PROMPT_FIRST_RENDER=1
|
||||||
|
typeset -g PROMPT_PROJECT_ROOT_CACHE_PWD=''
|
||||||
|
typeset -g PROMPT_PROJECT_ROOT_CACHE=''
|
||||||
|
|
||||||
prompt_preexec() {
|
prompt_preexec() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@@ -24,8 +28,16 @@ get_command_version() {
|
|||||||
local binary_path=""
|
local binary_path=""
|
||||||
local raw_version=""
|
local raw_version=""
|
||||||
|
|
||||||
|
if [[ -n ${PROMPT_VERSION_CACHE[$command_name]+x} ]]; then
|
||||||
|
print -r -- "${PROMPT_VERSION_CACHE[$command_name]}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
binary_path="$(whence -p "$command_name" 2>/dev/null || true)"
|
binary_path="$(whence -p "$command_name" 2>/dev/null || true)"
|
||||||
[ -n "$binary_path" ] && [ -x "$binary_path" ] || return 0
|
if ! [ -n "$binary_path" ] || ! [ -x "$binary_path" ]; then
|
||||||
|
PROMPT_VERSION_CACHE[$command_name]=""
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
case "$command_name" in
|
case "$command_name" in
|
||||||
python)
|
python)
|
||||||
@@ -47,16 +59,29 @@ get_command_version() {
|
|||||||
raw_version="${raw_version%% *}"
|
raw_version="${raw_version%% *}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
PROMPT_VERSION_CACHE[$command_name]=""
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
[ -n "$raw_version" ] || return 0
|
[ -n "$raw_version" ] || {
|
||||||
|
PROMPT_VERSION_CACHE[$command_name]=""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
PROMPT_VERSION_CACHE[$command_name]="$raw_version"
|
||||||
print -r -- "$raw_version"
|
print -r -- "$raw_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
get_project_root() {
|
get_project_root() {
|
||||||
command git rev-parse --show-toplevel 2>/dev/null || print -r -- "$PWD"
|
if [ "$PROMPT_PROJECT_ROOT_CACHE_PWD" = "$PWD" ] && [ -n "$PROMPT_PROJECT_ROOT_CACHE" ]; then
|
||||||
|
print -r -- "$PROMPT_PROJECT_ROOT_CACHE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROMPT_PROJECT_ROOT_CACHE_PWD="$PWD"
|
||||||
|
PROMPT_PROJECT_ROOT_CACHE="$(command git rev-parse --show-toplevel 2>/dev/null || print -r -- "$PWD")"
|
||||||
|
print -r -- "$PROMPT_PROJECT_ROOT_CACHE"
|
||||||
}
|
}
|
||||||
|
|
||||||
project_has_pattern() {
|
project_has_pattern() {
|
||||||
@@ -166,6 +191,17 @@ build_prompt() {
|
|||||||
local prompt_spacer=""
|
local prompt_spacer=""
|
||||||
local separator="::"
|
local separator="::"
|
||||||
|
|
||||||
|
if [ "$last_status" -ne 0 ]; then
|
||||||
|
separator="%F{red}::%f"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$PROMPT_FIRST_RENDER" -eq 1 ]; then
|
||||||
|
PROMPT_FIRST_RENDER=0
|
||||||
|
PROMPT="%B%~%b ${separator} "
|
||||||
|
RPROMPT="%n@%m"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
vcs_info
|
vcs_info
|
||||||
git_segment="${vcs_info_msg_0_}"
|
git_segment="${vcs_info_msg_0_}"
|
||||||
git_status_segment="$(build_git_status_segment)"
|
git_status_segment="$(build_git_status_segment)"
|
||||||
@@ -228,10 +264,6 @@ build_prompt() {
|
|||||||
context_line+="${newline}"
|
context_line+="${newline}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$last_status" -ne 0 ]; then
|
|
||||||
separator="%F{red}::%f"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$PROMPT_SHOW_SPACER" -eq 1 ]; then
|
if [ "$PROMPT_SHOW_SPACER" -eq 1 ]; then
|
||||||
prompt_spacer="$(build_prompt_separator_line "$last_status")${newline}"
|
prompt_spacer="$(build_prompt_separator_line "$last_status")${newline}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
49
Zsh/.zshrc
49
Zsh/.zshrc
@@ -7,14 +7,23 @@ export ZSH="$HOME/.oh-my-zsh"
|
|||||||
export PROG_DIR="$HOME/.programming"
|
export PROG_DIR="$HOME/.programming"
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
plugins=(git zsh-syntax-highlighting zsh-autosuggestions sudo rclone rust nvm golang conda pyenv)
|
plugins=(git zsh-syntax-highlighting zsh-autosuggestions sudo rclone)
|
||||||
|
|
||||||
source $ZSH/oh-my-zsh.sh
|
source $ZSH/oh-my-zsh.sh
|
||||||
|
|
||||||
# Go and GVM (Black Box)
|
# Go and GVM (Black Box)
|
||||||
export GOPATH="$PROG_DIR/go"
|
export GOPATH="$PROG_DIR/go"
|
||||||
export GVM_ROOT="$GOPATH"
|
export GVM_ROOT="$GOPATH"
|
||||||
[[ -s "$GVM_ROOT/scripts/gvm" ]] && source "$GVM_ROOT/scripts/gvm"
|
|
||||||
|
gvm_load() {
|
||||||
|
unset -f gvm go gofmt
|
||||||
|
[[ -s "$GVM_ROOT/scripts/gvm" ]] && source "$GVM_ROOT/scripts/gvm"
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
gvm() { gvm_load gvm "$@"; }
|
||||||
|
go() { gvm_load go "$@"; }
|
||||||
|
gofmt() { gvm_load gofmt "$@"; }
|
||||||
|
|
||||||
# Node and NVM (Lazy Load)
|
# Node and NVM (Lazy Load)
|
||||||
export NVM_DIR="$PROG_DIR/node"
|
export NVM_DIR="$PROG_DIR/node"
|
||||||
@@ -37,16 +46,25 @@ export CARGO_HOME="$PROG_DIR/rust/cargo"
|
|||||||
|
|
||||||
# Python (Pyenv + Miniconda)
|
# Python (Pyenv + Miniconda)
|
||||||
export PYENV_ROOT="$PROG_DIR/python/pyenv"
|
export PYENV_ROOT="$PROG_DIR/python/pyenv"
|
||||||
export PATH="$PYENV_ROOT/bin:$PATH"
|
export PATH="$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH"
|
||||||
|
export CONDA_ROOT="$PYENV_ROOT/versions/miniforge3-latest"
|
||||||
|
|
||||||
if command -v pyenv 1>/dev/null 2>&1; then
|
pyenv_load() {
|
||||||
eval "$(pyenv init -)"
|
unset -f pyenv
|
||||||
fi
|
eval "$(command pyenv init -)"
|
||||||
|
pyenv "$@"
|
||||||
|
}
|
||||||
|
|
||||||
if command -v conda >/dev/null 2>&1; then
|
pyenv() { pyenv_load "$@"; }
|
||||||
CONDA_BASE=$(conda info --base)
|
|
||||||
[ -f "$CONDA_BASE/etc/profile.d/conda.sh" ] && source "$CONDA_BASE/etc/profile.d/conda.sh"
|
conda_load() {
|
||||||
fi
|
unset -f conda mamba
|
||||||
|
[ -f "$CONDA_ROOT/etc/profile.d/conda.sh" ] && source "$CONDA_ROOT/etc/profile.d/conda.sh"
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
conda() { conda_load conda "$@"; }
|
||||||
|
mamba() { conda_load mamba "$@"; }
|
||||||
|
|
||||||
# R and Rig
|
# R and Rig
|
||||||
export RIG_HOME="$PROG_DIR/r"
|
export RIG_HOME="$PROG_DIR/r"
|
||||||
@@ -54,6 +72,10 @@ if [ -d "$RIG_HOME/bin" ]; then
|
|||||||
export PATH="$RIG_HOME/bin:$PATH"
|
export PATH="$RIG_HOME/bin:$PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
is_wsl() {
|
||||||
|
[ -f /proc/version ] && grep -qEi "(Microsoft|WSL)" /proc/version
|
||||||
|
}
|
||||||
|
|
||||||
# Zoxide
|
# Zoxide
|
||||||
if command -v zoxide >/dev/null 2>&1; then
|
if command -v zoxide >/dev/null 2>&1; then
|
||||||
eval "$(zoxide init --cmd cd zsh)"
|
eval "$(zoxide init --cmd cd zsh)"
|
||||||
@@ -67,8 +89,8 @@ fi
|
|||||||
export PATH="$HOME/.local/bin:$CARGO_HOME/bin:$GOPATH/bin:$PATH"
|
export PATH="$HOME/.local/bin:$CARGO_HOME/bin:$GOPATH/bin:$PATH"
|
||||||
|
|
||||||
# opencode
|
# opencode
|
||||||
if command -v openchamber >/dev/null 2>&1 && ! pgrep -f "openchamber.*7891" > /dev/null; then
|
if is_wsl && command -v openchamber >/dev/null 2>&1 && ! pgrep -f "openchamber.*7891" > /dev/null; then
|
||||||
openchamber --port 7891 >/dev/null 2>&1
|
openchamber --port 7891 >/dev/null 2>&1 &!
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# direnv
|
# direnv
|
||||||
@@ -76,5 +98,8 @@ if command -v direnv >/dev/null 2>&1; then
|
|||||||
eval "$(direnv hook zsh)"
|
eval "$(direnv hook zsh)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Completion Styling
|
||||||
|
[ -f ~/.zsh_completion ] && source ~/.zsh_completion
|
||||||
|
|
||||||
# Prompt Styling
|
# Prompt Styling
|
||||||
[ -f ~/.zsh_prompt ] && source ~/.zsh_prompt
|
[ -f ~/.zsh_prompt ] && source ~/.zsh_prompt
|
||||||
|
|||||||
Reference in New Issue
Block a user