From 15fbdaab58e349d23908666f94690e9ef4ae603f Mon Sep 17 00:00:00 2001 From: Hobeom Date: Mon, 9 Mar 2026 22:59:45 +0900 Subject: [PATCH] refactor(zellij): separate root alias from sub-command prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split _zellij_root_alias and _zellij_short_prefix so that when z is taken (e.g. by zoxide), only the root alias falls back to zj while sub-commands keep the shorter z prefix (zl, za, zk, zd, …). Every alias and function now checks for conflicts before defining, and compdef targets are collected dynamically to avoid binding completions to names that were never created. Co-Authored-By: Claude Opus 4.6 --- plugins/zellij/README.md | 44 +++++++------ plugins/zellij/zellij.plugin.zsh | 103 +++++++++++++++++++++++-------- 2 files changed, 103 insertions(+), 44 deletions(-) diff --git a/plugins/zellij/README.md b/plugins/zellij/README.md index c4c8fd2ea..c91d2c880 100644 --- a/plugins/zellij/README.md +++ b/plugins/zellij/README.md @@ -10,35 +10,43 @@ plugins=(... zellij) ## Dynamic prefix -The default alias prefix is `zj`. To use the shorter `z` prefix instead, set the following -variable before oh-my-zsh is sourced: +The default prefix is `zj`. To use the shorter `z` prefix instead, set the following variable +before oh-my-zsh is sourced: ```zsh ZSH_ZELLIJ_PREFIX_Z=true ``` -> **Note:** If `z` is already defined as an alias, function, or command by another plugin -> (e.g., zoxide), the `zj` prefix is used for the main `zellij` alias even when -> `ZSH_ZELLIJ_PREFIX_Z` is set. +When `ZSH_ZELLIJ_PREFIX_Z` is set, the root alias (`z`) and sub-command prefix are handled +separately: + +- If `z` is **not** taken → `z`=zellij, sub-commands use `z` prefix (`zl`, `za`, …) +- If `z` **is** taken (e.g., by zoxide) → `zj`=zellij, but sub-commands still use `z` prefix (`zl`, `za`, …) + +This means only the root alias falls back to `zj`; the shorter sub-command shortcuts remain +usable. + +All aliases and functions perform a conflict check before being defined — if a name is already +taken by another alias, function, or command, it is silently skipped. ## Aliases -| Alias (default) | Alias (with `z`) | Command | Description | -| ---------------- | ---------------- | ---------------------------- | ------------------------ | -| `zj` | `z` | `zellij` | Zellij command | -| `zjl` | `zl` | `zellij list-sessions` | List sessions | -| `zjs` | `zs` | `zellij -s` | Start a named session | -| `zjda` | `zda` | `zellij delete-all-sessions` | Delete all sessions | -| `zjka` | `zka` | `zellij kill-all-sessions` | Kill all sessions | -| `zjr` | — | `zellij run` | Run a command in a pane | +| Alias (default) | Alias (with `z`) | Alias (`z` + conflict) | Command | Description | +| ---------------- | ---------------- | ---------------------- | ---------------------------- | ------------------------ | +| `zj` | `z` | `zj` | `zellij` | Zellij command | +| `zjl` | `zl` | `zl` | `zellij list-sessions` | List sessions | +| `zjs` | `zs` | `zs` | `zellij -s` | Start a named session | +| `zjda` | `zda` | `zda` | `zellij delete-all-sessions` | Delete all sessions | +| `zjka` | `zka` | `zka` | `zellij kill-all-sessions` | Kill all sessions | +| `zjr` | — | — | `zellij run` | Run a command in a pane | ## Functions -| Function (default) | Function (with `z`) | Command | Description | -| ------------------- | ------------------- | ------------------------------ | --------------------------------- | -| `zja` | `za` | `zellij attach` | Attach to a session | -| `zjd` | `zd` | `zellij delete-session` | Delete a session | -| `zjk` | `zk` | `zellij kill-session` | Kill a session | +| Function (default) | Function (with `z`) | Command | Description | +| ------------------- | ------------------- | ------------------------ | -------------------- | +| `zja` | `za` | `zellij attach` | Attach to a session | +| `zjd` | `zd` | `zellij delete-session` | Delete a session | +| `zjk` | `zk` | `zellij kill-session` | Kill a session | The following convenience functions are always available (unless the name is already taken): diff --git a/plugins/zellij/zellij.plugin.zsh b/plugins/zellij/zellij.plugin.zsh index 34245e56a..f79ff420a 100644 --- a/plugins/zellij/zellij.plugin.zsh +++ b/plugins/zellij/zellij.plugin.zsh @@ -2,36 +2,82 @@ if (( ! $+commands[zellij] )); then return fi +_omz_zellij_taken() { + (( $+aliases[$1] || $+functions[$1] || $+commands[$1] )) +} + +typeset -ga _zellij_comp_targets _zellij_all_session_targets _zellij_running_session_targets _zellij_exited_session_targets +_zellij_comp_targets=() +_zellij_all_session_targets=() +_zellij_running_session_targets=() +_zellij_exited_session_targets=() + if [[ -n ${ZSH_ZELLIJ_PREFIX_Z:-} ]]; then - _zellij_prefix=z + _zellij_short_prefix=z + if _omz_zellij_taken z; then + _zellij_root_alias=zj + else + _zellij_root_alias=z + fi else - _zellij_prefix=zj + _zellij_short_prefix=zj + _zellij_root_alias=zj fi - -if [[ -n ${ZSH_ZELLIJ_PREFIX_Z:-} ]] && (( ! $+aliases[z] && ! $+functions[z] && ! $+commands[z] )); then - alias z='zellij' -else - alias zj='zellij' +if ! _omz_zellij_taken "$_zellij_root_alias"; then + alias ${_zellij_root_alias}='zellij' + _zellij_comp_targets+=("$_zellij_root_alias") fi -# alias ${_zellij_prefix}='zellij' -alias ${_zellij_prefix}l='zellij list-sessions' -alias ${_zellij_prefix}s='zellij -s' -alias ${_zellij_prefix}da='zellij delete-all-sessions' -alias ${_zellij_prefix}ka='zellij kill-all-sessions' -[[ $_zellij_prefix != z ]] && alias ${_zellij_prefix}r='zellij run' +if ! _omz_zellij_taken "${_zellij_short_prefix}l"; then + alias ${_zellij_short_prefix}l='zellij list-sessions' + _zellij_comp_targets+=("${_zellij_short_prefix}l") +fi -eval "${_zellij_prefix}a() { command zellij attach \"\$@\"; }" -eval "${_zellij_prefix}d() { command zellij delete-session \"\$@\"; }" -eval "${_zellij_prefix}k() { command zellij kill-session \"\$@\"; }" +if ! _omz_zellij_taken "${_zellij_short_prefix}s"; then + alias ${_zellij_short_prefix}s='zellij -s' + _zellij_comp_targets+=("${_zellij_short_prefix}s") +fi + +if ! _omz_zellij_taken "${_zellij_short_prefix}da"; then + alias ${_zellij_short_prefix}da='zellij delete-all-sessions' + _zellij_comp_targets+=("${_zellij_short_prefix}da") +fi + +if ! _omz_zellij_taken "${_zellij_short_prefix}ka"; then + alias ${_zellij_short_prefix}ka='zellij kill-all-sessions' + _zellij_comp_targets+=("${_zellij_short_prefix}ka") +fi + +if [[ $_zellij_short_prefix != z ]] && ! _omz_zellij_taken "${_zellij_short_prefix}r"; then + alias ${_zellij_short_prefix}r='zellij run' + _zellij_comp_targets+=("${_zellij_short_prefix}r") +fi + +if ! _omz_zellij_taken "${_zellij_short_prefix}a"; then + eval "${_zellij_short_prefix}a() { command zellij attach \"\$@\"; }" + _zellij_all_session_targets+=("${_zellij_short_prefix}a") +fi + +if ! _omz_zellij_taken "${_zellij_short_prefix}d"; then + eval "${_zellij_short_prefix}d() { command zellij delete-session \"\$@\"; }" + _zellij_exited_session_targets+=("${_zellij_short_prefix}d") +fi + +if ! _omz_zellij_taken "${_zellij_short_prefix}k"; then + eval "${_zellij_short_prefix}k() { command zellij kill-session \"\$@\"; }" + _zellij_running_session_targets+=("${_zellij_short_prefix}k") +fi (( $+functions[zr] || $+aliases[zr] || $+commands[zr] )) || zr() { command zellij run -- "$@"; } (( $+functions[zrf] || $+aliases[zrf] || $+commands[zrf] )) || zrf() { command zellij run --floating -- "$@"; } (( $+functions[ze] || $+aliases[ze] || $+commands[ze] )) || ze() { command zellij edit "$@"; } -_ZELLIJ_COMP_FILE="${ZSH_CACHE_DIR}/completions/_zellij" -mkdir -p "${_ZELLIJ_COMP_FILE:h}" +_ZELLIJ_COMP_DIR="${ZSH_CACHE_DIR}/completions" +_ZELLIJ_COMP_FILE="${_ZELLIJ_COMP_DIR}/_zellij" + +mkdir -p "$_ZELLIJ_COMP_DIR" +(( ${fpath[(I)$_ZELLIJ_COMP_DIR]} )) || fpath=("$_ZELLIJ_COMP_DIR" $fpath) if [[ ! -s $_ZELLIJ_COMP_FILE ]]; then command zellij setup --generate-completion zsh >| "$_ZELLIJ_COMP_FILE" 2>/dev/null @@ -57,7 +103,7 @@ _omz_zellij_running_sessions() { local out local -a sessions out="$(_omz_zellij_ls_raw)" - sessions=("${(@f)$(printf '%s\n' "$out" | LC_ALL=C sed -nE '/EXITED/!s/^([^[:space:]]+).*/\1/p')}") + sessions=("${(@f)$(printf '%s\n' "$out" | LC_ALL=C sed -nE '/\(EXITED/!s/^([^[:space:]]+).*/\1/p')}") (( ${#sessions[@]} )) && compadd -Q -a sessions } @@ -66,18 +112,23 @@ _omz_zellij_exited_sessions() { local out local -a sessions out="$(_omz_zellij_ls_raw)" - sessions=("${(@f)$(printf '%s\n' "$out" | LC_ALL=C sed -nE '/EXITED/s/^([^[:space:]]+).*/\1/p')}") + sessions=("${(@f)$(printf '%s\n' "$out" | LC_ALL=C sed -nE '/\(EXITED/s/^([^[:space:]]+).*/\1/p')}") (( ${#sessions[@]} )) && compadd -Q -a sessions } if (( $+functions[compdef] )); then autoload -Uz _zellij - compdef _zellij zellij ${_zellij_prefix} ${_zellij_prefix}l ${_zellij_prefix}s - [[ $_zellij_prefix != z ]] && compdef _zellij ${_zellij_prefix}r - compdef _omz_zellij_all_sessions ${_zellij_prefix}a - compdef _omz_zellij_running_sessions ${_zellij_prefix}k - compdef _omz_zellij_exited_sessions ${_zellij_prefix}d + compdef _zellij zellij ${_zellij_comp_targets[@]} + (( ${#_zellij_all_session_targets[@]} )) && compdef _omz_zellij_all_sessions ${_zellij_all_session_targets[@]} + (( ${#_zellij_running_session_targets[@]} )) && compdef _omz_zellij_running_sessions ${_zellij_running_session_targets[@]} + (( ${#_zellij_exited_session_targets[@]} )) && compdef _omz_zellij_exited_sessions ${_zellij_exited_session_targets[@]} fi +unset _ZELLIJ_COMP_DIR unset _ZELLIJ_COMP_FILE -unset _zellij_prefix +unset _zellij_root_alias +unset _zellij_short_prefix +unset _zellij_comp_targets +unset _zellij_all_session_targets +unset _zellij_running_session_targets +unset _zellij_exited_session_targets