feat(zellij): add session functions, convenience commands, and smart completions

- Use functions for attach/delete/kill to enable session-aware completions
- Add zr, zrf, ze convenience functions with conflict detection
- Improve z prefix collision check (aliases, functions, commands)
- Cache completions synchronously on first load, background on updates
- Update README to document new functions and completion behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hobeom 2026-03-09 22:57:30 +09:00
commit e564461958
2 changed files with 100 additions and 34 deletions

View file

@ -1,7 +1,8 @@
# zellij # zellij
This plugin provides aliases and completions for [zellij](https://zellij.dev/), the terminal workspace This plugin provides aliases, functions, and completions for [zellij](https://zellij.dev/),
(multiplexer). To use it, add `zellij` to the plugins array in your zshrc file. the terminal workspace (multiplexer). To use it, add `zellij` to the plugins array in your
zshrc file.
```zsh ```zsh
plugins=(... zellij) plugins=(... zellij)
@ -16,25 +17,42 @@ variable before oh-my-zsh is sourced:
ZSH_ZELLIJ_PREFIX_Z=true ZSH_ZELLIJ_PREFIX_Z=true
``` ```
> **Note:** If `z` is already aliased by another plugin (e.g., zoxide), the prefix stays `zj` > **Note:** If `z` is already defined as an alias, function, or command by another plugin
> even when `ZSH_ZELLIJ_PREFIX_Z` is set. > (e.g., zoxide), the `zj` prefix is used for the main `zellij` alias even when
> `ZSH_ZELLIJ_PREFIX_Z` is set.
## Aliases ## Aliases
| Alias (default) | Alias (with `z`) | Command | Description | | Alias (default) | Alias (with `z`) | Command | Description |
| ---------------- | ---------------- | ---------------------------- | ------------------------ | | ---------------- | ---------------- | ---------------------------- | ------------------------ |
| `zj` | `z` | `zellij` | Zellij command | | `zj` | `z` | `zellij` | Zellij command |
| `zja` | `za` | `zellij attach` | Attach to a session |
| `zjd` | `zd` | `zellij delete-session` | Delete a session |
| `zjda` | `zda` | `zellij delete-all-sessions` | Delete all sessions |
| `zjk` | `zk` | `zellij kill-session` | Kill a session |
| `zjka` | `zka` | `zellij kill-all-sessions` | Kill all sessions |
| `zjl` | `zl` | `zellij list-sessions` | List sessions | | `zjl` | `zl` | `zellij list-sessions` | List sessions |
| `zjr` | `zr` | `zellij run` | Run a command in a pane |
| `zjs` | `zs` | `zellij -s` | Start a named session | | `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 |
## 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 |
The following convenience functions are always available (unless the name is already taken):
| Function | Command | Description |
| -------- | ---------------------------- | ---------------------------------- |
| `zr` | `zellij run --` | Run a command in a pane |
| `zrf` | `zellij run --floating --` | Run a command in a floating pane |
| `ze` | `zellij edit` | Edit a file in a pane |
## Completions ## Completions
This plugin caches the zellij completion script in the background (using the same approach as This plugin caches the zellij completion script. On first load the cache is generated
the [gh](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/gh) plugin). On first load the synchronously; subsequent updates (when the `zellij` binary is newer than the cache) happen in
cache is generated; completions become available in the next shell session. the background.
Session-aware completions are provided for `attach`, `delete-session`, and `kill-session`
functions — only relevant sessions (all, running, or exited) are offered.

View file

@ -2,34 +2,82 @@ if (( ! $+commands[zellij] )); then
return return
fi fi
# Dynamic prefix: use "zj" by default, use "z" if ZSH_ZELLIJ_PREFIX_Z is set and "z" is available if [[ -n ${ZSH_ZELLIJ_PREFIX_Z:-} ]]; then
if [[ -n "$ZSH_ZELLIJ_PREFIX_Z" ]] && (( ! $+aliases[z] )); then _zellij_prefix=z
_zellij_prefix="z"
else else
_zellij_prefix="zj" _zellij_prefix=zj
fi fi
# Aliases
alias ${_zellij_prefix}='zellij' if [[ -n ${ZSH_ZELLIJ_PREFIX_Z:-} ]] && (( ! $+aliases[z] && ! $+functions[z] && ! $+commands[z] )); then
alias ${_zellij_prefix}a='zellij attach' alias z='zellij'
alias ${_zellij_prefix}d='zellij delete-session' else
alias ${_zellij_prefix}da='zellij delete-all-sessions' alias zj='zellij'
alias ${_zellij_prefix}k='zellij kill-session' fi
alias ${_zellij_prefix}ka='zellij kill-all-sessions'
# alias ${_zellij_prefix}='zellij'
alias ${_zellij_prefix}l='zellij list-sessions' alias ${_zellij_prefix}l='zellij list-sessions'
alias ${_zellij_prefix}r='zellij run'
alias ${_zellij_prefix}s='zellij -s' 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'
unset _zellij_prefix eval "${_zellij_prefix}a() { command zellij attach \"\$@\"; }"
eval "${_zellij_prefix}d() { command zellij delete-session \"\$@\"; }"
eval "${_zellij_prefix}k() { command zellij kill-session \"\$@\"; }"
# Completion caching (same pattern as gh plugin) (( $+functions[zr] || $+aliases[zr] || $+commands[zr] )) || zr() { command zellij run -- "$@"; }
# On first load, _zellij may not exist in fpath — autoload fails silently. (( $+functions[zrf] || $+aliases[zrf] || $+commands[zrf] )) || zrf() { command zellij run --floating -- "$@"; }
# The background command generates the cache file for subsequent sessions. (( $+functions[ze] || $+aliases[ze] || $+commands[ze] )) || ze() { command zellij edit "$@"; }
# Load order: plugin loads → compinit runs → next session picks up cached file.
if [[ ! -f "$ZSH_CACHE_DIR/completions/_zellij" ]]; then _ZELLIJ_COMP_FILE="${ZSH_CACHE_DIR}/completions/_zellij"
typeset -g -A _comps mkdir -p "${_ZELLIJ_COMP_FILE:h}"
autoload -Uz _zellij
_comps[zellij]=_zellij if [[ ! -s $_ZELLIJ_COMP_FILE ]]; then
command zellij setup --generate-completion zsh >| "$_ZELLIJ_COMP_FILE" 2>/dev/null
elif [[ $commands[zellij] -nt $_ZELLIJ_COMP_FILE ]]; then
command zellij setup --generate-completion zsh >| "$_ZELLIJ_COMP_FILE" 2>/dev/null &!
fi fi
zellij setup --generate-completion zsh >| "$ZSH_CACHE_DIR/completions/_zellij" &| _omz_zellij_ls_raw() {
command zellij list-sessions --no-formatting 2>/dev/null || command zellij list-sessions 2>/dev/null
}
_omz_zellij_all_sessions() {
emulate -L zsh
local out
local -a sessions
out="$(_omz_zellij_ls_raw)"
sessions=("${(@f)$(printf '%s\n' "$out" | LC_ALL=C sed -nE 's/^([^[:space:]]+).*/\1/p')}")
(( ${#sessions[@]} )) && compadd -Q -a sessions
}
_omz_zellij_running_sessions() {
emulate -L zsh
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[@]} )) && compadd -Q -a sessions
}
_omz_zellij_exited_sessions() {
emulate -L zsh
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[@]} )) && 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
fi
unset _ZELLIJ_COMP_FILE
unset _zellij_prefix