diff --git a/.config/shell/env b/.config/shell/env index 76e188f..d870f26 100644 --- a/.config/shell/env +++ b/.config/shell/env @@ -8,8 +8,8 @@ export XDG_CACHE_HOME="$HOME/.cache" export XDG_CONFIG_HOME="$HOME/.config" -export XDG_DATA_HOME="$HOME/.local/share" # also set in ~/.local/bin/install-dotfiles -export XDG_STATE_HOME="$HOME/.local/state" +export XDG_DATA_HOME="$HOME/.local/share" # also set in ~/.local/bin/{generate-shell-completions,install-dotfiles} +export XDG_STATE_HOME="$HOME/.local/state" # also set in ~/.local/bin/generate-shell-completions # Make up a XDG directory for binaries (that does not exist in the standard) export XDG_BIN_HOME="$HOME/.local/bin" # also set in ~/.local/bin/install-dotfiles diff --git a/.local/bin/generate-shell-completions b/.local/bin/generate-shell-completions new file mode 100755 index 0000000..2861985 --- /dev/null +++ b/.local/bin/generate-shell-completions @@ -0,0 +1,99 @@ +#!/bin/sh + +# Generate shell completions for various tools into the XDG data directories, +# so that they are loaded lazily instead of `eval`ed on every shell start +# +# Run this after installing or updating any of the tools below + +set -eu + + + +XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" # also set in ~/.config/shell/env +XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" # also set in ~/.config/shell/env + + +BASH_DIR="$XDG_DATA_HOME/bash-completion/completions" +ZSH_DIR="$XDG_DATA_HOME/zsh/completions" + + +QUIET="${QUIET:-}" + + + +rm -rf "$BASH_DIR" "$ZSH_DIR" +mkdir -p "$BASH_DIR" "$ZSH_DIR" + + + +_command_exists() { + command -v "$1" 1>/dev/null 2>&1 +} + + +# Write to a temporary file first, +# so that a failing tool does not leave a truncated completion file +_generate() { + _name="$1" + _target="$2" + shift 2 + + if "$@" > "$_target.tmp" 2>/dev/null && [ -s "$_target.tmp" ]; then + mv "$_target.tmp" "$_target" + echo " $_name" + else + rm -f "$_target.tmp" + echo " $_name => FAILED" >&2 + fi +} + + + +echo "Generating bash completions in: $BASH_DIR" + + +_command_exists pip \ + && _generate pip "$BASH_DIR/pip" pip completion --bash + + +_command_exists register-python-argcomplete \ + && _command_exists pipx \ + && _generate pipx "$BASH_DIR/pipx" register-python-argcomplete pipx + + +_command_exists poetry \ + && _generate poetry "$BASH_DIR/poetry" poetry completions bash + + + +echo "Generating zsh completions in: $ZSH_DIR" + + +_pip_zsh() { + pip completion --zsh | sed -n '/^#compdef/,$p' +} + +_command_exists pip \ + && _generate pip "$ZSH_DIR/_pip" _pip_zsh + + +_command_exists register-python-argcomplete \ + && _command_exists pipx \ + && _generate pipx "$ZSH_DIR/_pipx" register-python-argcomplete pipx + + +_command_exists poetry \ + && _generate poetry "$ZSH_DIR/_poetry" poetry completions zsh + + + +rm -f "$XDG_STATE_HOME/zsh/zcompdump"* + + + +if [ -z "$QUIET" ]; then + echo "" + echo "Reload your shell to use them:" + echo " exec \$SHELL -l" + echo "" +fi diff --git a/.local/bin/install-dotfiles b/.local/bin/install-dotfiles index 91c9af8..d06049f 100755 --- a/.local/bin/install-dotfiles +++ b/.local/bin/install-dotfiles @@ -109,6 +109,11 @@ if command -v batcat >/dev/null 2>&1 && ! command -v bat >/dev/null 2>&1; then fi +if [ -x "$XDG_BIN_HOME/generate-shell-completions" ]; then + QUIET=1 "$XDG_BIN_HOME/generate-shell-completions" || true +fi + + echo "" echo "The dotfiles were installed successfully (branch: $DOTFILES_BRANCH)" echo "" diff --git a/.zshrc b/.zshrc index e3574f9..cac1794 100644 --- a/.zshrc +++ b/.zshrc @@ -49,6 +49,9 @@ stty -ixon # Prevent Ctrl+S from freezing `zsh` # Enable (tab) completions +# Look for completion files generated by ~/.local/bin/generate-shell-completions +fpath=("${XDG_DATA_HOME:-$HOME/.local/share}/zsh/completions" $fpath) + autoload -Uz compinit && compinit -u -d "${XDG_STATE_HOME:-$HOME/.local/state}/zsh/zcompdump" # Enable match highlighting and scrolling through long lists,