a
    a(                     @   s   d Z ddlZddlZddlZddlmZ er8ddlmZ dZ	dd Z
dd	 Zd
d Zdd Zd(ddZdd Zdd Zdd Zd)ddZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' ZdS )*z
Source code text utilities
    N)PY2)izip))
nt)
posix)Zmacc                 C   sZ   t D ]\}}| |dkr qVqtjdkr0d}n&tjdrBd}ntjdkrRd}nd}|S )zf
    Get text EOL characters.

    If None is found, return the eol based on the operatin system.
    r   r   linuxr   darwinr   )	EOL_CHARSfindosnamesysplatform
startswith)text	eol_charsZ_os_name r   6lib/python3.9/site-packages/spyder/utils/sourcecode.pyget_eol_chars   s    

r   c                 C   s"   t D ]\}}| |kr|  S qdS )z"Return OS name from EOL charactersNr   )r   charsos_namer   r   r   get_os_name_from_eol_chars/   s    r   c                 C   s"   t D ]\}}|| kr|  S qdS )z"Return EOL characters from OS nameNr   )r   r   r   r   r   r   get_eol_chars_from_os_name6   s    r   c                 C   s6   t | }|du rdS || |  }t|t| kS )z'Detect if text has mixed EOL charactersNF)r   join
splitlinesrepr)r   r   Zcorrect_textr   r   r   has_mixed_eol_chars=   s
    r    r   c                 C   s&   t D ]\}}||kr| ||} q| S )zUse the same eol's in text)r   replace)r   ZeolZeol_char_r   r   r   normalize_eolsF   s    r#   c                 C   s   |  d|S )zReplace tabs by spaces	)r!   )r   Zindent_charsr   r   r   fix_indentationN   s    r%   c                 C   s"   ddl m} | dd t|D v S )z<Test if passed string is the name of a Python builtin objectr   )builtinsc                 S   s   g | ]}| d st|qS )r"   )r   str).0r   r   r   r   
<listcomp>V   s   
zis_builtin.<locals>.<listcomp>)spyder.py3compatr&   dir)r   r&   r   r   r   
is_builtinS   s    r,   c                 C   s   ddl }| |jv S )z5Test if passed string is the name of a Python keywordr   N)keywordkwlist)r   r-   r   r   r   
is_keywordZ   s    r/   Tc                 C   s   d}t d| d| }|r,|d r,|d }t d| |d }|rX|d rX||d 7 }|rl|d  rld}|s|r|r| |d  dv rt| |d d	d
S |S )zReturn Python object in *source_code* at *offset*
    Periods to the left of the cursor are carried forward
      e.g. 'functools.par^tial' would yield 'functools.partial'
    Retry prevents infinite recursion: retry only once
     [^0-9a-zA-Z_.]Nr	   z\Wr      z([.F)retry)resplitisdigitget_primary_at)source_codeoffsetr3   objleftrightr   r   r   r7   `   s    r7   c                 C   s    t | }|r| |S | gS dS )z!Split source code into lines
    N)r   r5   )r8   r   r   r   r   split_sourceu   s    
r=   c                    s,   t td| }td  fdd|D S )z4Split source code into python identifier-like tokensr1   z	[a-zA-Z_]c                    s   g | ]}t  |r|qS r   )r4   match)r(   tokenZvalidr   r   r)          z#get_identifiers.<locals>.<listcomp>)setr4   r5   compile)r8   tokensr   r@   r   get_identifiers   s    
rE   c                 C   sD   g }t j| \}}|| || kr(q.|} q|| |  |S )z
    Return the individual components of a given file path
    string (for the local operating system).

    Taken from https://stackoverflow.com/q/21498939/438386
    )r   pathr5   appendreverse)rF   Z
componentsnew_pathtailr   r   r   path_components   s    

rK   c                 C   sR  g }d}d}t t| |D ]4\}\}}||kr@|dkr:d} qPn|}|| qt| t| d  }tjj|  d| d  }	t|dkrNtjj| }
t|
d }|	|d dkr&|s&t|	|d }|d dkr|d dkrt|	|d dkr|d| tjj| }	n|	|d }	n(|s2|}	nt	j
d	rN|	dkrNd
}	|	S )z
    Return the differentiated prefix of the given two iterables.

    Taken from https://stackoverflow.com/q/21498939/438386
    FN   Tr2   r   r0      r
   /)	enumerateziprG   lenr   rF   r   rK   insertr   r   r   )Zpath_components0Zpath_components1Zlongest_prefixZroot_comparisonZcommon_elmtindexZelmt0Zelmt1Zfile_name_lengthZpath_0Zlongest_path_prefixZlongest_prefix_lengthZpath_0_componentsr   r   r   differentiate_prefix   s<    
rT   c                 C   s   t j|}t| |}t|dkrt|}||krH|t| t|}tt|t|}t|}t|}|dkrt|dkr|d dkr|d dkr|d d|d g}n|d d|d g}t jj	| }|d	 | }|S )
z"Get tab title without ambiguation.r2   rM   rL   r   rN   r0   z...r	   z - )
r   rF   basenameget_same_name_filesrQ   shortest_pathremoverK   rT   r   )files_path_listfilenamefnamesame_name_filesZcompare_pathZ	diff_pathZdiff_path_lengthZpath_componentr   r   r   disambiguate_fname   s.    
r]   c                 C   s0   g }| D ]"}|t j|kr|t| q|S )zBGet a list of the path components of the files with the same name.)r   rF   rU   rG   rK   )rY   rZ   r\   r[   r   r   r   rV      s
    rV   c                 C   sR   t | dkrN| d }t | d }| D ]}t ||k r$t |}|}q$tjj| S dS )z(Shortest path between files in the list.r   N)rQ   r   rF   r   )rY   rW   Zshortest_path_lengthZ
path_elmtsr   r   r   rW      s    rW   )r   )T)__doc__r4   r   r   r*   r   	itertoolsr   rP   r   r   r   r   r    r#   r%   r,   r/   r7   r=   rE   rK   rT   r]   rV   rW   r   r   r   r   <module>   s.   	


$