Bash · 3211 bytes Raw Blame History
1 #!/bin/bash
2
3 # Parrot shell hook - source this in your .bashrc or .zshrc
4
5 # Path to parrot binary - update this if needed
6 PARROT_BIN="parrot"
7
8 # Function to check if parrot binary exists
9 parrot_check() {
10 if ! command -v "$PARROT_BIN" &> /dev/null; then
11 echo "⚠️ Parrot binary not found. Make sure 'parrot' is in your PATH."
12 return 1
13 fi
14 return 0
15 }
16
17 # Function called after each command in bash
18 parrot_prompt_command() {
19 local exit_code=$?
20 local last_cmd=$(history 1 | sed 's/^[ ]*[0-9]*[ ]*//')
21
22 # Only mock if command failed and we have a command
23 if [ $exit_code -ne 0 ] && [ -n "$last_cmd" ] && parrot_check; then
24 # Run parrot in background to avoid blocking shell if PARROT_ASYNC is set
25 if [ "${PARROT_ASYNC:-}" = "true" ]; then
26 "$PARROT_BIN" mock "$last_cmd" "$exit_code" &
27 else
28 "$PARROT_BIN" mock "$last_cmd" "$exit_code"
29 fi
30 fi
31 }
32
33 # Function called before each command in zsh
34 parrot_preexec() {
35 PARROT_LAST_CMD="$1"
36 }
37
38 # Function called after each command in zsh
39 parrot_precmd() {
40 local exit_code=$?
41
42 # Only mock if command failed and we have a command
43 if [ $exit_code -ne 0 ] && [ -n "$PARROT_LAST_CMD" ] && parrot_check; then
44 # Run parrot in background to avoid blocking shell if PARROT_ASYNC is set
45 if [ "${PARROT_ASYNC:-}" = "true" ]; then
46 "$PARROT_BIN" mock "$PARROT_LAST_CMD" "$exit_code" &
47 else
48 "$PARROT_BIN" mock "$PARROT_LAST_CMD" "$exit_code"
49 fi
50 fi
51 }
52
53 # Setup based on shell type (only show messages if not already initialized)
54 if [ -z "$PARROT_INITIALIZED" ]; then
55 if [ -n "$BASH_VERSION" ]; then
56 # Bash setup
57 PROMPT_COMMAND="parrot_prompt_command${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
58 # Only show message in interactive shells
59 if [[ $- == *i* ]]; then
60 echo "🦜 Parrot is now watching your bash commands..."
61 fi
62 elif [ -n "$ZSH_VERSION" ]; then
63 # Zsh setup
64 autoload -Uz add-zsh-hook
65 add-zsh-hook preexec parrot_preexec
66 add-zsh-hook precmd parrot_precmd
67 # Only show message in interactive shells
68 if [[ -o interactive ]]; then
69 echo "🦜 Parrot is now watching your zsh commands..."
70 fi
71 else
72 echo "⚠️ Parrot: Unsupported shell. Only bash, zsh, and fish are supported."
73 echo "💡 For fish shell, use parrot-hook.fish instead."
74 fi
75
76 # Show performance tip only in interactive shells
77 if [[ $- == *i* ]] || [[ -o interactive ]] 2>/dev/null; then
78 if [ "${PARROT_ASYNC:-}" != "true" ]; then
79 echo "💡 Tip: Set PARROT_ASYNC=true to prevent terminal hangs on slow networks"
80 fi
81 fi
82
83 # Mark as initialized for this shell session
84 export PARROT_INITIALIZED=1
85 else
86 # Silent re-initialization (e.g., when sourcing .zshrc again)
87 if [ -n "$BASH_VERSION" ]; then
88 PROMPT_COMMAND="parrot_prompt_command${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
89 elif [ -n "$ZSH_VERSION" ]; then
90 autoload -Uz add-zsh-hook
91 add-zsh-hook preexec parrot_preexec
92 add-zsh-hook precmd parrot_precmd
93 fi
94 fi