Skip to content

ZSH widget: Add toggle, fix keybindings, add timeout for robustness #83

@noahgift

Description

@noahgift

Overview

The current ZSH widget has several UX and robustness issues that can cause shell breakage.


🔴 Critical Issues

1. No way to toggle on/off

If something goes wrong, users must edit ~/.zshrc to disable. Need an environment variable toggle:

_aprender_suggest() {
    # Quick disable check
    [[ "$APRENDER_DISABLED" == "1" ]] && return

    # ... rest of function
}

Users can then:

export APRENDER_DISABLED=1  # disable
unset APRENDER_DISABLED     # re-enable

2. Tab key hijacking breaks normal completion

Current code:

bindkey '^I' _aprender_accept      # Tab

This completely breaks ZSH's native tab completion. Users can't complete filenames, commands, etc.

Fix: Use a different key or only accept when suggestion exists:

_aprender_accept_or_complete() {
    if [[ -n "$POSTDISPLAY" ]]; then
        BUFFER="${BUFFER}${POSTDISPLAY# }"
        POSTDISPLAY=""
        CURSOR=$#BUFFER
        zle redisplay
    else
        zle expand-or-complete  # Fall back to normal tab
    fi
}
zle -N _aprender_accept_or_complete
bindkey '^I' _aprender_accept_or_complete

3. Right arrow hijacking breaks cursor movement

bindkey '^[[C' _aprender_accept    # Right arrow

This breaks normal cursor-right navigation. User can't move through their command.

Fix: Only accept at end of line:

_aprender_accept_or_forward() {
    if [[ -n "$POSTDISPLAY" && $CURSOR -eq $#BUFFER ]]; then
        # At end of line with suggestion - accept
        BUFFER="${BUFFER}${POSTDISPLAY# }"
        POSTDISPLAY=""
        CURSOR=$#BUFFER
    else
        zle forward-char  # Normal right arrow
    fi
    zle redisplay
}

🟡 Medium Issues

4. No timeout - hung process freezes shell

If aprender-shell suggest hangs (disk I/O, corrupted model), the shell freezes on every keystroke.

Fix: Add timeout:

suggestion=$(timeout 0.1 aprender-shell suggest "$BUFFER" 2>/dev/null | head -1 | cut -f1)

5. No graceful degradation message

If binary is missing or model doesn't exist, users get silent failure with no indication why suggestions aren't working.

Fix: Add init check:

# At widget load time
if ! command -v aprender-shell &>/dev/null; then
    echo "aprender-shell: binary not found, suggestions disabled" >&2
    return
fi

if [[ ! -f ~/.aprender-shell.model ]]; then
    echo "aprender-shell: no model found, run 'aprender-shell train' first" >&2
fi

Suggested Complete Widget

See comment below for full implementation.


Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions