diff options
| -rw-r--r-- | 97-whatcmd.zsh | 256 |
1 files changed, 164 insertions, 92 deletions
diff --git a/97-whatcmd.zsh b/97-whatcmd.zsh index 4d26fab..aa41097 100644 --- a/97-whatcmd.zsh +++ b/97-whatcmd.zsh @@ -229,7 +229,7 @@ _whatcmd_demux() { ' <<< "$line" ) - [[ -n $text ]] && print -u2 -r -- "✦ $text" + [[ -n $text ]] && print -u2 -r -- "⬤ $text" ;; tool_use) @@ -290,7 +290,8 @@ _opencode_minibuffer_pre_redraw() { emulate -L zsh region_highlight=( - "P${_opencode_prompt_start} ${_opencode_prompt_end} fg=magenta,bold" + "P${_opencode_prompt_start} $((_opencode_prompt_start + 2)) fg=yellow,bold" + "P$((_opencode_prompt_start + 2)) ${_opencode_prompt_end} fg=magenta,bold" ) } @@ -419,118 +420,189 @@ _opencode_minibuffer() { } -# -# Ctrl-? widget -# -_opencode_command() { +_whatcmd_autosuggest_pause() { emulate -L zsh - local request - # - # Give the natural-language minibuffer its own history. + # Remember whether autosuggestions were already disabled before us. # - () { - local history_file="${XDG_STATE_HOME:-$HOME/.local/state}/opencode-command/history" - - mkdir -p -- "${history_file:h}" || return 1 - - # - # Push normal shell history and load our OpenCode history. - # - # -a restores the previous history automatically when this - # anonymous function returns. - # - fc -p -a "$history_file" 1000 1000 + _whatcmd_autosuggest_was_disabled=${+_ZSH_AUTOSUGGEST_DISABLED} - _opencode_minibuffer " ✦ What command " || return + if (( ${+widgets[autosuggest-disable]} )); then + zle autosuggest-disable + fi - request=$REPLY - [[ -z "${request//[[:space:]]/}" ]] && return 1 + POSTDISPLAY= +} - # - # Store the natural-language request in OpenCode history. - # - print -s -- "$request" - } || return +_whatcmd_autosuggest_resume() { + emulate -L zsh - unsetopt MONITOR + POSTDISPLAY= # - # Show a temporary ZLE status line before blocking on OpenCode. + # Don't enable it if the user already had it disabled before invoking + # whatcmd. # - local tmpdir - tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/whatcmd.XXXXXX") || return 1 + if (( !_whatcmd_autosuggest_was_disabled )) && + (( ${+widgets[autosuggest-enable]} )); then + zle autosuggest-enable + fi - local result_file="$tmpdir/result" - local status_file="$tmpdir/status" - local stderr_fifo="$tmpdir/stderr" + unset _whatcmd_autosuggest_was_disabled +} - mkfifo "$stderr_fifo" || { - rm -rf -- "$tmpdir" - return 1 - } +# +# Ctrl-? widget +# +_opencode_command() { + emulate -L zsh + + local request # - # Open the FIFO read/write in the parent so opening either end - # never blocks waiting for the other side. + # Save the outer ZLE state. History navigation inside recursive-edit + # changes HISTNO, and that can otherwise leak back into the real prompt. # - local fifo_fd - exec {fifo_fd}<>"$stderr_fifo" - - ( - whatcmd "$request" >| "$result_file" 2>"$stderr_fifo" - print -r -- "$?" >| "$status_file" - ) & - - local -a spinner=( - '⠋' '⠙' '⠹' '⠸' '⠼' - '⠴' '⠦' '⠧' '⠇' '⠏' - ) - local i=1 - local line='' - local message='Asking agent ...' - - while [[ ! -e "$status_file" ]]; do - # - # Grab an stderr line if one is available, but don't block - # longer than one animation frame. - # - if read -r -t 0.1 -u $fifo_fd line; then - [[ -n $line ]] && message=$line - fi + local saved_buffer=$BUFFER + integer saved_cursor=$CURSOR + integer saved_histno=$HISTNO - zle -R "${spinner[i]} $message" - (( i = i % ${#spinner} + 1 )) - done - - local ec - read -r ec < "$status_file" - - local result - result="$(<"$result_file")" + _whatcmd_autosuggest_pause - exec {fifo_fd}>&- - rm -rf -- "$tmpdir" - - zle -R - - if (( ec != 0 )); then - zle -I - print -u2 -r -- "✗ opencode failed: exit status $ec" - return $ec - fi - - if [[ -z "${result//[[:space:]]/}" ]]; then - zle -I - print -u2 -r -- '✗ opencode returned nothing' - return 1 - fi + { + # + # Give the natural-language minibuffer its own history. + # + () { + local history_file="${XDG_STATE_HOME:-$HOME/.local/state}/opencode-command/history" + + mkdir -p -- "${history_file:h}" || return 1 + + # + # Push normal shell history and load our OpenCode history. + # + # -a restores the previous history automatically when this + # anonymous function returns. + # + fc -p -a "$history_file" 1000 1000 + + _opencode_minibuffer " ⬤ What command " || return + + request=$REPLY + + [[ -z "${request//[[:space:]]/}" ]] && return 1 + + # + # Store the natural-language request in OpenCode history. + # + print -s -- "$request" + } + + local minibuffer_ec=$? + + # + # The anonymous function has exited, so fc -p -a has restored the + # normal shell history. Restore the outer editor's history position + # and command line. + # + # Assigning HISTNO can itself load a history entry into BUFFER, so + # restore HISTNO first and BUFFER afterward. + # + HISTNO=$saved_histno + BUFFER=$saved_buffer + CURSOR=$saved_cursor + + (( minibuffer_ec != 0 )) && return $minibuffer_ec + + unsetopt MONITOR + + local tmpdir + tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/whatcmd.XXXXXX") || return 1 + + local result_file="$tmpdir/result" + local status_file="$tmpdir/status" + local stderr_fifo="$tmpdir/stderr" + + mkfifo "$stderr_fifo" || { + rm -rf -- "$tmpdir" + return 1 + } + + # + # Open the FIFO read/write in the parent so opening either end + # never blocks waiting for the other side. + # + local fifo_fd + exec {fifo_fd}<>"$stderr_fifo" + + ( + whatcmd "$request" >| "$result_file" 2>"$stderr_fifo" + print -r -- "$?" >| "$status_file" + ) & + + local -a spinner=( + '⠋' '⠙' '⠹' '⠸' '⠼' + '⠴' '⠦' '⠧' '⠇' '⠏' + ) + local i=1 + local line='' + local message='⬤ Determining command ...' + + while [[ ! -e "$status_file" ]]; do + # + # Grab a stderr line if one is available, but don't block + # longer than one animation frame. + # + if read -r -t 0.1 -u $fifo_fd line; then + [[ -n $line ]] && message=$line + fi + POSTDISPLAY=$'\n'"${spinner[i]} $message" + + local pos=$(( ${#PREDISPLAY} + ${#BUFFER} + 1 )) + local pos_end=$(( ${#PREDISPLAY} + ${#BUFFER} + ${#POSTDISPLAY} )) + + region_highlight+=( + "P${pos} $(( pos + 1 )) fg=red,bold memo=whatcmd-spinner" + "P$((pos + 1)) $(( pos + 4 )) fg=yellow,bold memo=whatcmd-spinner" + # "P$(( pos + 4 )) ${pos_end} fg=cyan,bold memo=whatcmd-spinner" + ) + + zle -R + (( i = i % ${#spinner} + 1 )) + done + + local ec + read -r ec < "$status_file" + + local result + result="$(<"$result_file")" + + exec {fifo_fd}>&- + rm -rf -- "$tmpdir" + + zle -R + + if (( ec != 0 )); then + zle -I + print -u2 -r -- "✗ opencode failed: exit status $ec" + return $ec + fi + + if [[ -z "${result//[[:space:]]/}" ]]; then + zle -I + print -u2 -r -- '✗ opencode returned nothing' + return 1 + fi + } always { + _whatcmd_autosuggest_resume + } # - # Replace the current command line but don't execute it. + # Replace the original command line with the generated command, + # but don't execute it. # BUFFER=$result CURSOR=${#BUFFER} |