# SPDX-FileCopyrightText: Amolith # # SPDX-License-Identifier: Unlicense # Fallback to the configured agent command (Crush by default) when a command is not found. # Configure the prefix that marks commands for routing to the agent. if not set -q __AGENTSH_PREFIX_CHAR set -g __AGENTSH_PREFIX_CHAR "✨" end if not set -q __AGENTSH_PREFIX set -g __AGENTSH_PREFIX "$__AGENTSH_PREFIX_CHAR " end if not set -q __AGENTSH_RUNNER set -g __AGENTSH_RUNNER crush run --quiet end set -g __AGENTSH_PREFIX_ACTIVE 0 # Preserve any previously defined handler so we can delegate if needed if functions -q fish_command_not_found functions -c fish_command_not_found __agentsh_prev_fish_command_not_found end # Command not found handler function fish_command_not_found set -l missing_command $argv[1] set -l remaining_args $argv[2..-1] # Nothing to do without a command name if test -z "$missing_command" echo "fish: command not found" >&2 return 127 end set -l prefix_char $__AGENTSH_PREFIX_CHAR set -l handled false set -l effective_cmd # Check if command starts with prefix if test "$missing_command" = "$prefix_char" set handled true set effective_cmd $remaining_args else if string match -q "$prefix_char*" -- "$missing_command" set handled true set -l stripped (string replace -- "$prefix_char" "" -- "$missing_command") if test -n "$stripped" set effective_cmd $stripped $remaining_args else set effective_cmd $remaining_args end end if test "$handled" != true if functions -q __agentsh_prev_fish_command_not_found __agentsh_prev_fish_command_not_found $argv return $status end echo "fish: command not found: $missing_command" >&2 return 127 end if test (count $effective_cmd) -eq 0 echo "agentsh: nothing to run after '$prefix_char'." >&2 return 127 end if not set -q __AGENTSH_RUNNER[1] echo "agentsh: no runner configured; set __AGENTSH_RUNNER before sourcing agentsh." >&2 return 127 end set -l runner $__AGENTSH_RUNNER set -l runner_exe $runner[1] if not type -q -- $runner_exe if functions -q __agentsh_prev_fish_command_not_found __agentsh_prev_fish_command_not_found $argv return $status end echo "agentsh: $runner_exe: command not found; unable to handle '$effective_cmd[1]'." >&2 return 127 end # Build command string as single argument set -l full_cmd (string join ' ' -- $effective_cmd) $runner $full_cmd return $status end # Toggle prefix function function __agentsh_toggle_prefix set -l prefix $__AGENTSH_PREFIX set -l prefix_len (string length -- $prefix) set -l buffer (commandline) set -l cursor_pos (commandline -C) if string match -q "$prefix*" -- "$buffer" # Remove prefix set -l new_buffer (string sub --start (math $prefix_len + 1) -- $buffer) commandline -r -- $new_buffer if test $cursor_pos -gt $prefix_len commandline -C (math $cursor_pos - $prefix_len) else commandline -C 0 end set -g __AGENTSH_PREFIX_ACTIVE 0 else # Add prefix commandline -r -- "$prefix$buffer" commandline -C (math $cursor_pos + $prefix_len) set -g __AGENTSH_PREFIX_ACTIVE 1 end end # Hook to persist prefix across prompts function __agentsh_postexec --on-event fish_postexec if test $__AGENTSH_PREFIX_ACTIVE -eq 1 commandline -f repaint end end # Guard backward deletion to prevent removing prefix function __agentsh_guard_backward_delete if test $__AGENTSH_PREFIX_ACTIVE -eq 0 commandline -f backward-delete-char return end set -l prefix $__AGENTSH_PREFIX set -l prefix_len (string length -- $prefix) set -l buffer (commandline) set -l cursor_pos (commandline -C) # Don't delete if we're at or before the prefix boundary if string match -q "$prefix*" -- "$buffer"; and test $cursor_pos -le $prefix_len return end commandline -f backward-delete-char end function __agentsh_guard_backward_kill_word if test $__AGENTSH_PREFIX_ACTIVE -eq 0 commandline -f backward-kill-word return end set -l prefix $__AGENTSH_PREFIX set -l prefix_len (string length -- $prefix) set -l buffer (commandline) set -l cursor_pos (commandline -C) if string match -q "$prefix*" -- "$buffer"; and test $cursor_pos -le $prefix_len return end commandline -f backward-kill-word end # Set up key bindings if status is-interactive # Bind Ctrl+X to toggle prefix bind \cx __agentsh_toggle_prefix # Bind multiple backspace variants bind \b __agentsh_guard_backward_delete bind \x7f __agentsh_guard_backward_delete bind backspace __agentsh_guard_backward_delete # Bind Alt+Backspace variants bind \eb __agentsh_guard_backward_kill_word bind \e\x7f __agentsh_guard_backward_kill_word # Bind Ctrl+W bind \cw __agentsh_guard_backward_kill_word # Bind in insert mode too bind -M insert \b __agentsh_guard_backward_delete bind -M insert \x7f __agentsh_guard_backward_delete bind -M insert \eb __agentsh_guard_backward_kill_word bind -M insert \e\x7f __agentsh_guard_backward_kill_word bind -M insert \cw __agentsh_guard_backward_kill_word end