diff --git a/README.md b/README.md index 857891b..cf64992 100644 --- a/README.md +++ b/README.md @@ -85,14 +85,24 @@ module load keep keep --status # Source the shell profile (optional, for shell integration) -source $KEEP_BASH_PROFILE +source $KEEP_BASH_PROFILE # bash +source $KEEP_ZSH_PROFILE # zsh +source $KEEP_SH_PROFILE # sh/dash/ksh +source $KEEP_CSH_PROFILE # csh/tcsh ``` -The modulefile prepends `keep/bin` to `PATH` and sets `KEEP_BASH_PROFILE` pointing to `profile.bash`. +The modulefile prepends `keep/bin` to `PATH` and sets shell-specific profile variables: + +| Variable | Profile | Shell | +|----------|---------|-------| +| `KEEP_BASH_PROFILE` | `profile.bash` | bash | +| `KEEP_ZSH_PROFILE` | `profile.zsh` | zsh | +| `KEEP_SH_PROFILE` | `profile.sh` | sh, dash, ksh93, pdksh, mksh | +| `KEEP_CSH_PROFILE` | `profile.csh` | csh, tcsh | ### Shell Completion -Tab completion is available for `bash`, `zsh`, `fish`, `elvish`, and `powershell`. +Tab completion is available for `bash`, `zsh`, `fish`, `elvish`, and `powershell`. Completions for `@` (save) and `@@` (get) are available for `bash` and `zsh` only. **Bash** — add to `~/.bashrc`: @@ -106,7 +116,7 @@ Tab completion is available for `bash`, `zsh`, `fish`, `elvish`, and `powershell . <(keep --generate-completion zsh) ``` -**With `profile.bash`**: Completions for `keep`, `@` (save), and `@@` (get) are loaded automatically when sourcing `profile.bash`. +**With `profile.bash` or `profile.zsh`**: Completions for `keep`, `@` (save), and `@@` (get) are loaded automatically when sourcing the profile. ### Build with Server/Client Features @@ -848,20 +858,41 @@ The server applies the following security measures: ## Shell Integration -Source `profile.bash` to enable shell integration: +Profile scripts are provided for several shells. Source the appropriate one to enable shell integration: + +| Profile | Shells | Features | +|---------|--------|----------| +| `profile.bash` | bash | Preexec hook, wrapper function, `@`/`@@` aliases, tab completions | +| `profile.zsh` | zsh | Preexec hook, wrapper function, `@`/`@@` aliases, tab completions | +| `profile.sh` | sh, dash, ksh93, pdksh, mksh | Wrapper function, `@`/`@@` aliases | +| `profile.csh` | csh, tcsh | Alias-based `keep` wrapper, `@`/`@@` aliases | ```sh +# bash source /path/to/keep/profile.bash + +# zsh +source /path/to/keep/profile.zsh + +# sh, dash, ksh +source /path/to/keep/profile.sh + +# csh/tcsh +source /path/to/keep/profile.csh ``` -This provides: +All profiles provide: -- **`keep` function** — Captures the current command in metadata automatically - **`@` alias** — Shorthand for `keep --save` - **`@@` alias** — Shorthand for `keep --get` +Bash and zsh profiles additionally provide: + +- **`keep` function** — Captures the current command in metadata automatically +- **Tab completion** — For `keep`, `@`, and `@@` + ```sh -# Save with automatic command capture +# Save with automatic command capture (bash/zsh) curl -s api.example.com | @ api-response # Quick retrieve diff --git a/modulefile b/modulefile index 96b615c..6daf9ce 100644 --- a/modulefile +++ b/modulefile @@ -15,3 +15,6 @@ module-whatis Keep prepend-path PATH $mydir/bin setenv KEEP_BASH_PROFILE ${mydir}/profile.bash +setenv KEEP_ZSH_PROFILE ${mydir}/profile.zsh +setenv KEEP_SH_PROFILE ${mydir}/profile.sh +setenv KEEP_CSH_PROFILE ${mydir}/profile.csh diff --git a/profile.bash b/profile.bash index bffe126..3413c44 100755 --- a/profile.bash +++ b/profile.bash @@ -6,18 +6,10 @@ function __keep_preexec { } function __keep_preexec_init { - local found=false - local f for f in "${preexec_functions[@]}"; do - if [[ $f = __keep_preexec ]]; then - found=true - break - fi + [[ $f = __keep_preexec ]] && return done - - if [[ $found = false ]]; then - preexec_functions+=(__keep_preexec) - fi + preexec_functions+=(__keep_preexec) } function keep { @@ -43,17 +35,15 @@ function @@ { # Shell completions . <(command keep --generate-completion bash) -___keep_save_completion() { - COMP_WORDS=(keep --save "${COMP_WORDS[@]:1}") +___keep_complete() { + local mode="$1" + COMP_WORDS=(keep "$mode" "${COMP_WORDS[@]:1}") COMP_CWORD=$((COMP_CWORD + 1)) _keep } -___keep_get_completion() { - COMP_WORDS=(keep --get "${COMP_WORDS[@]:1}") - COMP_CWORD=$((COMP_CWORD + 1)) - _keep -} +___keep_save_completion() { ___keep_complete --save; } +___keep_get_completion() { ___keep_complete --get; } complete -F ___keep_save_completion @ complete -F ___keep_get_completion @@ diff --git a/profile.csh b/profile.csh new file mode 100644 index 0000000..725af9e --- /dev/null +++ b/profile.csh @@ -0,0 +1,11 @@ +#!/bin/csh +# Profile for csh and tcsh. +# Preexec hooks are not available; KEEP_META_command is not set. + +if ( ! $?KEEP_META_tty ) then + setenv KEEP_META_tty `tty` +endif + +alias keep 'env KEEP_META_tty=${KEEP_META_tty} command keep \!*' +alias @ 'keep --save \!*' +alias @@ 'keep --get \!*' diff --git a/profile.sh b/profile.sh new file mode 100644 index 0000000..3086e36 --- /dev/null +++ b/profile.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# POSIX-compatible profile for sh, dash, ksh93, pdksh, mksh, and other POSIX shells. +# Preexec hooks are not available in these shells; KEEP_META_command is not set. + +KEEP_META_tty=${KEEP_META_tty:-$(tty)} + +keep() { + export KEEP_META_tty + command keep "$@" +} + +alias @='keep --save' +alias @@='keep --get' diff --git a/profile.zsh b/profile.zsh new file mode 100644 index 0000000..b0d9e66 --- /dev/null +++ b/profile.zsh @@ -0,0 +1,38 @@ +#!/bin/zsh + +autoload -U add-zsh-hook + +__keep_preexec() { + KEEP_META_command="$1" + KEEP_META_tty=${KEEP_META_tty:-$(tty)} +} + +add-zsh-hook preexec __keep_preexec + +keep() { + if [[ $ZSH_SUBSHELL -le 2 ]]; then + export KEEP_META_command + fi + export KEEP_META_tty + command keep "$@" +} + +alias @='keep --save' +alias @@='keep --get' + +# Shell completions +. <(command keep --generate-completion zsh) + +___keep_complete() { + local mode="$1" + local -a words + words=(keep "$mode" "${words[@]:1}") + ((CURRENT++)) + _keep +} + +___keep_save_completion() { ___keep_complete --save; } +___keep_get_completion() { ___keep_complete --get; } + +compdef ___keep_save_completion @ +compdef ___keep_get_completion @@