
    iM                        d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZmZ erddlmZ ddd	ed
efdZded
efdZded
efdZded
efdZdeeedf   ef   d	eddd
ee   fdZdeeedf   ef   d
ee   fdZdeeedf   ef   d	eddd
ee   fdZdeeedf   ef   deedf   dedeedf   deedf   d
ee   fdZded
ee   fdZd
efdZdee   ded
ee   fdZy) zBash completion script generator.

Generates static bash completion scripts using COMPREPLY and compgen.
Targets bash 3.2+ with no external dependencies.
    N)TYPE_CHECKING)is_iterable_type)CompletionActionCompletionDataclean_choice_textescape_for_shell_patternextract_completion_dataget_completion_action)Appappr   	prog_namereturnc                    |rt        j                  d|      st        d|d      |j                  dd      }t	        |       }d| ddd| d	d
dg}|j                  t        |||              |j                  dg       |j                  d       |j                  d| d|        |j                  d       dj                  |      S )a  Generate bash completion script.

    Parameters
    ----------
    app : App
        The Cyclopts application to generate completion for.
    prog_name : str
        Program name (alphanumeric with hyphens/underscores).

    Returns
    -------
    str
        Complete bash completion script.

    Raises
    ------
    ValueError
        If prog_name contains invalid characters.
    z^[a-zA-Z0-9_-]+$zInvalid prog_name: z0. Must be alphanumeric with hyphens/underscores.-_z# Bash completion for z# Generated by Cyclopts z() {z  local cur prev}zcomplete -F _ 
)	rematch
ValueErrorreplacer	   extend"_generate_completion_function_bodyappendjoin)r   r   	func_namecompletion_dataliness        ~/home/jay/workspace/.worktrees/task-2116-dev1/scripts/.codegraph-venv/lib/python3.12/site-packages/cyclopts/completion/bash.pygenerate_completion_scriptr"      s    ( BHH%8)D.ym;klmm!!#s+I-c2O !,!

I;e
E 
LL3OYPSTU	LL#	LL	LL=1YK89	LL99U    choicec                 &    | j                  dd      S )z&Escape single quotes for bash strings.'z'\''r   )r$   s    r!   _escape_bash_choicer(   E   s    >>#w''r#   textc                 N    | j                  dd      } | j                  dd      } | S )z*Escape description text for bash comments.r   r   r'   )r)   s    r!   _escape_bash_descriptionr,   J   s'    <<c"D<<c"DKr#   actionc                 T    | t         j                  k(  ry| t         j                  k(  ryy)zMap completion action to bash compgen flags.

    Parameters
    ----------
    action : CompletionAction
        Completion action type.

    Returns
    -------
    str
        Compgen flags ("-f", "-d", or "").
    z-fz-dr   )r   FILESDIRECTORIES)r-   s    r!   _map_completion_action_to_bashr1   Q   s+     !'''	#//	/r#   r   .c                     g }|j                  d       |j                  d       |j                  d       |j                  t        |              |j                  d       |j                  t        | ||             |S )aR  Generate the body of the bash completion function.

    Parameters
    ----------
    completion_data : dict
        All extracted completion data.
    prog_name : str
        Program name.
    app : App
        Application instance.

    Returns
    -------
    list[str]
        Lines of bash code for the completion function body.
    z!  cur="${COMP_WORDS[COMP_CWORD]}"z$  prev="${COMP_WORDS[COMP_CWORD-1]}"r   )r   r    _generate_command_path_detection_generate_completion_logic)r   r   r   r    s       r!   r   r   e   sh    * E	LL45	LL78	LL	LL1/BC	LL	LL+OYLMLr#   c                 <
   t               }t               }| j                         D ]  }|j                  D ]h  }|j                         r|j                  j
                  s+|j                  j
                  D ]%  }|j                  d      s|j                  |       ' j |j                  D ]6  }|j                  D ]%  }|j                  d      r|j                  |       ' 8  g }|j                  d       |rHt        |      D 	cg c]  }	t        |	       }
}	dj                  |
      }|j                  d| d       n|j                  d       |j                  d       |j                  d       |rHt        |      D cg c]  }t        |       }}dj                  |      }|j                  d	| d       n|j                  d
       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d        |j                  d!       |j                  d"       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d#       |j                  d$       |j                  d%       |j                  d&       |j                  d'       |j                  d(       |j                  d)       |j                  d       |j                  d       |j                  d       |S c c}	w c c}w )*a[  Generate bash code to detect the current command path.

    This function generates two passes through COMP_WORDS:
    1. First pass builds cmd_path by identifying valid command names
    2. Second pass counts positionals (non-option words after the command path)

    The two-pass approach is necessary because we need to know the full command
    path length before we can correctly identify which words are positionals.

    Note: all_commands is built globally across all command levels. If a positional
    argument value happens to match a command name from a different level, it could
    be incorrectly classified (though this represents poor CLI design).

    Parameters
    ----------
    completion_data : dict
        All extracted completion data.

    Returns
    -------
    list[str]
        Lines of bash code for command path detection.
    r   zD  # Build list of options that take values (to skip their arguments)r   z  local options_with_values='r&   z  local options_with_values=''r   zK  # Build list of all valid command names (to distinguish from positionals)z  local all_commands='z  local all_commands=''z>  # Detect command path by collecting valid command words onlyz  local -a cmd_path=()z  local i skip_next=0z$  for ((i=1; i<COMP_CWORD; i++)); doz!    local word="${COMP_WORDS[i]}"z#    if [[ $skip_next -eq 1 ]]; thenz      skip_next=0z      continuez    fiz    if [[ $word =~ ^- ]]; thenz*      # Check if this option takes a valuez:      if [[ " $options_with_values " =~ " $word " ]]; thenz        skip_next=1z      fiz    elsezF      # Non-option word - only add to cmd_path if it's a valid commandz3      if [[ " $all_commands " =~ " $word " ]]; thenz        cmd_path+=("$word")z  donez;  # Count positionals (non-option words after command path)z  local positional_count=0z$  local cmd_path_len=${#cmd_path[@]}z  skip_next=0z  local cmd_depth=0z      # Non-option wordz1      if [[ $cmd_depth -lt $cmd_path_len ]]; thenz        # Still in command pathz        ((cmd_depth++))z
      elsez1        # Past command path, this is a positionalz        ((positional_count++)))setvalues	argumentsis_flag	parametername
startswithaddcommandsnamesr   sortedr(   r   )r   options_with_valuesall_commandsdataargumentr;   registered_commandcmd_namer    optescaped_optsopts_strcmdescaped_cmdscmds_strs                  r!   r3   r3      s%   0 %5L&&( 
/ 	6H##%(*<*<*A*A$..33 6Ds++//56	6 #'-- 	/.44 /**3/ $$X./	/
/ E	LLWX<BCV<WXS+C0XX88L)4XJa@A56	LL	LL^_<B<<PQS+C0QQ88L)-hZq9:./	LL	LLQR	LL)*	LL()	LL78	LL45	LL67	LL$%	LL!"	LL	LL12	LL=>	LLMN	LL&'	LL	LL	LLYZ	LLFG	LL./	LL	LL	LL	LL	LLNO	LL-.	LL78	LL!	LL&'	LL78	LL45	LL67	LL$%	LL!"	LL	LL12	LLMN	LL&'	LL	LL	LL*+	LLDE	LL23	LL*+	LL	LLDE	LL12	LL	LL	LLLA Y Rs   TTc                 2   g }|j                   rt        |j                         nd}|j                  rt        |j                        nd}|j                  d       |j                  d       t	        d | j                         D              }t        |dz         D ]=  }| j                         D cg c]  }t        |      |k(  s| }	}|	s3|j                  d| d       |dk(  r|j                  t        | dd	||             n|j                  d
       t        |	      D ]o  }|D 
cg c]  }
t        |
       }}
dj                  |      }|j                  d| d       |j                  t        | |d||             |j                  d       q |j                  d       |j                  d       |j                  d       |j                  d       @ |j                  d       |j                  d       |j                  d       |S c c}w c c}
w )aM  Generate the main completion logic using case statements.

    Parameters
    ----------
    completion_data : dict
        All extracted completion data.
    prog_name : str
        Program name.
    app : App
        Application instance.

    Returns
    -------
    list[str]
        Lines of bash code for completion logic.
     z4  # Determine command level and generate completionsz  case "${#cmd_path[@]}" inc              3   2   K   | ]  }t        |        y wN)len).0paths     r!   	<genexpr>z-_generate_completion_logic.<locals>.<genexpr>  s     A$CIAs          )r   z      z      case "${cmd_path[@]}" inr   z	        "z")z
          z          ;;z
        *)z
      esacz      ;;z    *)z  esac)
help_flagstupleversion_flagsr   maxkeysrangerQ   r   _generate_completions_for_pathr@   r   r   )r   r   r   r    rX   rZ   	max_depthdepthrS   relevant_pathsrJ   escaped_pathpath_strs                r!   r4   r4      s   * E*-..s~~&bJ030A0AE#++,rM	LLGH	LL./A/*>*>*@AAIy1}% !+:+?+?+AX4SYRWEW$XXtE7!_%A:LL7XWacpqrLL9:~. -IMN# 8 =NN88L1y
"562?D,Xbdqr ^,- LL&LL(LL&Z 1!4 
LL	LL	LLL; Y  Os   /HH(Hcommand_pathindentrX   rZ   c                    || vr| dgS | |   }g }g }|j                   D cg c]"  }|j                         r|j                  s!|$ }	}|	D ]x  }
|
j                  j                  xs g D ]%  }|j                  d      s|j                  |       ' |
j                  D ]%  }|j                  d      s|j                  |       ' z g }|j                  D ]6  }|j                  D ]%  }|j                  d      s|j                  |       ' 8 |D ]/  }|j                  d      s||vs||vs|j                  |       1 |D ]/  }|j                  d      s||vs||vs|j                  |       1 |j                  |       g }|j                  D ]6  }|j                  D ]%  }|j                  d      r|j                  |       ' 8 |j                   D cg c]  }|j                  |j                  s|  }}|j                  d        |j                  | d       |rA|D cg c]  }t        |       }}dj                  |      }|j                  | d| d       n|j                  | d	       |j                  | d
       t        |j                         }|r-t!        |j                   ||| d      }|j                  |       nx|rA|D cg c]  }t        |       }}dj                  |      }|j                  | d| d       n5|r|j                  t#        || d             n|j                  | d	       |j                  | d       |S c c}w c c}w c c}w c c}w )a  Generate completions for a specific command path.

    Parameters
    ----------
    completion_data : dict
        All extracted completion data.
    command_path : tuple[str, ...]
        Current command path.
    indent : str
        Indentation string.
    help_flags : tuple[str, ...]
        Help flag names.
    version_flags : tuple[str, ...]
        Version flag names.

    Returns
    -------
    list[str]
        Lines of bash code for completions at this command path.
    COMPREPLY=()r   c                 6    | j                   | j                   S dS )Nr   )index)as    r!   <lambda>z0_generate_completions_for_path.<locals>.<lambda>w  s    !''2Eqww 1 r#   )keyzif [[ ${cur} == -* ]]; thenr   z  COMPREPLY=( $(compgen -W '' -- "${cur}") )z  COMPREPLY=()else  fi)r8   is_positional_onlyshowr:   r;   r<   r   	negativesr>   r?   r   ri   sortr(   r   _check_if_prev_needs_value#_generate_value_completion_for_prev_generate_positional_completion)r   rd   re   rX   rZ   rC   r    optionsargkeyword_argsrD   r;   flag_commandsrE   flagr>   rF   positional_argsrG   escaped_optionsoptions_strneeds_value_completionvalue_completion_linesrJ   escaped_commandscommands_strs                             r!   r^   r^   3  s   6 ?*(,'((<(DEG#'>>_C9O9O9QVYV^V^C_L_  %&&++1r 	%Ds#t$	% && 	%Ds#t$	%% M"mm +&,, 	+Ds#$$T*	++
  !??3D$7D<UNN4 !  !??3D$7D<UNN4 ! NN=!H"mm **00 	*H&&s+)	**
 '+nn[s		8MRURZRZs[O[LM	LLF889:?FG.s3GGhh/x;K=H\]^x~./	LLF84!7G!DNNHo&}"
 	+,	@HI/4IIxx 01x;L>I]^_	4_PRmTUx~./	LLF82LC `B \ H  Js.   M&M&M&M+/M+<M+/M0M5c           	         g }t        |       dk(  r| d   j                  d      }t        | d   j                        }|rK|D cg c]  }t	        t        |             }}dj                  |      }|j                  | d| d       |S t        |      }|r|j                  | d| d	       |S |j                  | d
       |S |j                  | d       t        |       D ]  \  }	}
|
j                  d      }t        |
j                        }|j                  | d|	 d       |rJ|D cg c]  }t	        t        |             }}dj                  |      }|j                  | d| d       n9t        |      }|r|j                  | d| d	       n|j                  | d       |j                  | d        t        d | D        d      }|j                  | d       |r|j                  d      }t        |j                        }|rJ|D cg c]  }t	        t        |             }}dj                  |      }|j                  | d| d       nNt        |      }|r|j                  | d| d	       n)|j                  | d       n|j                  | d       |j                  | d       |j                  | d       |S c c}w c c}w c c}w )aE  Generate position-aware positional argument completion.

    Parameters
    ----------
    positional_args : list
        List of positional arguments sorted by index.
    indent : str
        Indentation string.

    Returns
    -------
    list[str]
        Lines of bash code for position-aware positional completion.
    rU   r   Tforcer   COMPREPLY=( $(compgen -W 'rm   zCOMPREPLY=( $(compgen  -- "${cur}") )rg   zcase ${positional_count} inro   rW       COMPREPLY=( $(compgen -W '    COMPREPLY=( $(compgen     COMPREPLY=()    ;;c              3   L   K   | ]  }t        |j                        s|  y wrP   )r   hint)rR   ry   s     r!   rT   z2_generate_positional_completion.<locals>.<genexpr>  s     ZS?OPSPXPX?YSZs   $$N  *)esac)rQ   get_choicesr
   r   r(   r   r   r   r1   	enumeratenext)r}   re   r    choicesr-   cescaped_choiceschoices_strcompgen_flagidxrD   iterable_args               r!   rw   rw     s    E
?q !!$00t0<&q'9'>'>?RYZQ23DQ3GHZOZ((?3KLLF8#=k]J^_`b L_ :&ALx'=l^K\]^Z LW x|45V LQ 	x<=>&7 	,MC***6G*8==9FLLF82cU!,-V]"^QR#67H7K#L"^"^!hh7x'Ek]Rfgh=fELLF8+El^Sd!efLLF8+;!<=LLF86*+	,$ ZOZ\`axt_%"..T.:G*<+<+<=FV]"^QR#67H7K#L"^"^!hh7x'Ek]Rfgh=fELLF8+El^Sd!efLLF8+;!<=LLF8#345xv&'xt_%Lg [$ #_& #_s   K0KK#c                     | D ]F  }|j                         r|j                  j                  xs g D ]  }|j                  d      s  y H y)a  Check if any options take values, requiring prev-word completion logic.

    Parameters
    ----------
    arguments : ArgumentCollection
        Arguments to check.

    Returns
    -------
    bool
        True if any option (starts with -) takes a value (is not a flag).
    r   TF)r9   r:   r;   r<   )r8   rD   r;   s      r!   ru   ru     sS       ! **//52  ??3'  
 r#   r>   c           
      ,   g }|j                  | d       d}| D ]0  }|j                         r|j                  j                  xs g D cg c]  }|j	                  d      s| }}|sQd}|j                  d      }	t        |j                        }
|D ]  }|j                  | d| d       |	rJ|	D cg c]  }t        t        |             }}dj                  |      }|j                  | d	| d
       n9t        |
      }|r|j                  | d| d       n|j                  | d       |j                  | d        3 |r|j                  | d       |rA|D cg c]  }t        |       }}dj                  |      }|j                  | d	| d
       n5|r|j                  t        || d             n|j                  | d       |j                  | d       |j                  | d       |S g }|rB|D cg c]  }t        |       }}dj                  |      }|j                  | d| d
       |S |r|j                  t        ||             |S |j                  | d       |S c c}w c c}w c c}w c c}w )a  Generate value completion based on previous word.

    Parameters
    ----------
    arguments : ArgumentCollection
        Arguments with potential values.
    commands : list[str]
        Available commands at this level.
    positional_args : list
        List of positional arguments sorted by index.
    indent : str
        Indentation string.

    Returns
    -------
    list[str]
        Lines of bash code for value completion.
    zcase "${prev}" inFr   Tr   ro   rW   r   r   rm   r   r   r   r   r   rV   r   r   rg   )r   r9   r:   r;   r<   r   r
   r   r(   r   r   r1   r   rw   )r8   r>   r}   re   r    	has_casesrD   r;   r?   r   r-   r   r   r   r   rJ   r   r   s                     r!   rv   rv     s   & E	LLF8./0I ,#+#5#5#:#:#@bZ$T__UXEYZZ	&&T&2&x}}5 	,DLLF82dV1-.V]"^QR#67H7K#L"^"^!hh7x'Ek]Rfgh=fELLF8+El^Sd!efLLF8+;!<=LLF86*+	,,8 xt_%DLMS 3C 8MM88$45LLLF8#A,OcdeLL8VHTX/Z[LLF8#345xv&'xt_% L DLMS 3C 8MM88$45LLLF8#=l^K_`a L LL8&QR L LLF8<01L_ [ #_  N  Ns   J#J7J+JJ)__doc__r   typingr   cyclopts.annotationsr   cyclopts.completion._baser   r   r   r   r	   r
   cycloptsr   strr"   r(   r,   r1   dictrY   listr   r3   r4   r^   rw   boolru   rv   rN   r#   r!   <module>r      s   
   1  *E *c *c *Z( ( (
3 3 +;  (%S/>9: 
 
#Y	Djd5c?N;Z6[ j`deh`i jZ<%S/>9:<< 
< 
#Y	<~c%S/>9:cS/c c c3h	c
 c?c 
#YcLIS IT#Y IXT *JT#Y Jad Jimnqir Jr#   