B
    nôb\/€  ã               @   sX  d Z ddlmZ ddlZddlmZ ddlZddlZddl	Z	ddl
mZmZ ddlmZmZmZ ddlmZmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZmZ ddlm Z m!Z!m"Z" ddl#m$Z$ ddl%m&Z& e" 'edd¡Z(e(røddl
m)Z) nddl
m*Z* G dd„ de+ƒZ,G dd„ de+ƒZ-G dd„ de+ƒZ.G dd„ de+ƒZ/G dd„ de+ƒZ0dS )z¿Mix-in classes

These classes were created to be able to provide Spyder's regular text and
console widget features to an independant widget based on QTextEdit for the
IPython console plugin.
é    )ÚescapeN)ÚQPointÚQt)ÚQCursorÚQTextCursorÚQTextDocument)ÚQApplicationÚQToolTip)Ú
QT_VERSION)ÚgetargspecfromtextÚgetobjÚgetsignaturefromtext)Ú_)Úis_text_stringÚto_text_string)ÚencodingÚ
sourcecodeÚprograms)Úget_error_match)ÚNumpyArrayDialogz5.5z>=)ÚQRegularExpression)ÚQRegExpc               @   s   e Zd Zdd„ Zdd„ Zdd„ Zdid
d„Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdjdd„Zdd „ Zd!d"„ Zd#d$„ Zdkd%d&„Zd'd(„ Zdld+d,„Zd-d.„ Zdmd/d0„Zd1d2„ Zd3d4„ Zd5d6„ Zdnd7d8„Zd9d:„ Zd;d<„ Zd=d>„ Zd?d@„ ZdAdB„ Z dCdD„ Z!dEdF„ Z"dGdH„ Z#dIdJ„ Z$dKdL„ Z%dMdN„ Z&dOdP„ Z'dQdR„ Z(dSdT„ Z)dodUdV„Z*dWdX„ Z+dpdZd[„Z,d\d]„ Z-dqd_d`„Z.drdadb„Z/dcdd„ Z0dedf„ Z1dgdh„ Z2d	S )sÚBaseEditMixinc             C   s   d | _ d| _d S )NiX  )Ú	eol_charsÚcalltip_size)Úself© r   ú4lib/python3.7/site-packages/spyder/widgets/mixins.pyÚ__init__/   s    zBaseEditMixin.__init__c             C   s   dS )zReturn line number area widthr   r   )r   r   r   r   Úget_linenumberarea_width4   s    z&BaseEditMixin.get_linenumberarea_widthc             C   sŽ   g }|  d¡d }tj|ddt|ƒd  d}xL|D ]D}t|ƒ}| dd¡}x dD ]}| |d	| d
 ¡}qRW | |¡ q4W d |¡}||fS )Nú(r   é2   ú é   )ÚwidthZsubsequent_indentz&nbsp;)ú=ú,r    ú)Ú*z**z,<span style='color: red; font-weight: bold'>z</span>z<br>)ÚsplitÚtextwrapZwrapÚlenr   ÚreplaceÚappendÚjoin)r   ÚtextZformatted_linesÚnameZrowsÚrÚcharÚ	signaturer   r   r   Ú_format_signature;   s    


zBaseEditMixin._format_signatureFú#2D62FFNc             C   sŠ  |dkst |ƒdkrdS |dkr*|  d¡}|| _|rD|  |¡\}}n@t|tƒrXd |¡}| dd¡}t |ƒ| jkr„|d| j… d }|  	¡ }| 
¡ }	| ¡ }
d|
|	|f }d	|
|	d
kr¾|	d n|	f }|d|  d | | d }|  d¡\}}|dk	r"d}t|  ¡  |d ¡ƒ}|  |¡ ¡ }|  t||ƒ¡}| | ¡ |  ¡  ¡ | | ¡ | 
¡  d ¡ |rz| j |||¡ nt ||¡ dS )zShow calltipNr   Úcursorz
    Ú
z<br>z ...z;<div style='font-family: "%s"; font-size: %spt; color: %s'>z0<div style='font-family: "%s"; font-size: %spt'>é	   r#   z<b>%s</b></div>z<hr>z</div>é   )r+   Úget_positionZcalltip_positionr4   Ú
isinstanceÚlistr.   r,   r   ÚfontZ	pointSizeÚfamilyÚget_coordinatesr   ÚdocumentÚfindBlockByNumberÚ
cursorRectÚtopÚmapToGlobalr   ZsetXÚxr   ZsetYÚyZcalltip_widgetZshow_tipr	   ZshowText)r   Útitler/   r3   ÚcolorZat_lineZat_positionZwrapped_textlinesr=   Úsizer>   Zformat1Zformat2ÚtiptextZcxZcyr6   Úpointr   r   r   Úshow_calltipK   s>    



zBaseEditMixin.show_calltipc             C   s^   t |ƒst|ƒ}t |¡}|dk	o*| jdk	}|| _|rZ|  ¡  d¡ | jdk	rZ| j |¡ dS )zASet widget end-of-line (EOL) characters from text (analyzes text)NT)	r   r   r   Zget_eol_charsr   r@   ZsetModifiedZsig_eol_chars_changedÚemit)r   r/   r   Zis_document_modifiedr   r   r   Úset_eol_chars{   s    

zBaseEditMixin.set_eol_charsc             C   s   | j dk	r| j S tjS dS )z/Return line separator based on current EOL modeN)r   ÚosÚlinesep)r   r   r   r   Úget_line_separator‡   s    
z BaseEditMixin.get_line_separatorc             C   s<   t |  ¡ ƒ}| ¡ }|  ¡ }| |¡}| d¡r8||7 }|S )zMSame as 'toPlainText', replace '
' 
        by correct end-of-line charactersr7   )r   ÚtoPlainTextÚ
splitlinesrQ   r.   Úendswith)r   ZutextÚlinesrP   Ztxtr   r   r   Úget_text_with_eolŽ   s    

zBaseEditMixin.get_text_with_eolc             C   sv   |   ¡ }|dkrn\|dkr(| tj¡ nF|dkr>| tj¡ n0|dkrT| tj¡ n|dkrj| tj¡ n|S | ¡ S )zYGet offset in character for the given subject from the start of
           text edit arear6   ÚsolÚeolÚeofÚsof)Ú
textCursorÚmovePositionr   ÚStartOfBlockÚ
EndOfBlockÚEndÚStartÚposition)r   Zsubjectr6   r   r   r   r:   ›   s    zBaseEditMixin.get_positionc             C   s:   |   |¡}|  ¡ }| |¡ |  |¡ ¡ }| ¡ | ¡ fS )N)r:   r[   ÚsetPositionrB   ÚcenterrE   rF   )r   ra   r6   rK   r   r   r   r?   ®   s
    

zBaseEditMixin.get_coordinatesc             C   s   |   ¡ }| ¡ | ¡ fS )z$Return cursor (line, column) numbers)r[   ÚblockNumberZcolumnNumber)r   r6   r   r   r   Úget_cursor_line_columnµ   s    z$BaseEditMixin.get_cursor_line_columnc             C   s   |   ¡  ¡ d S )zReturn cursor line numberr#   )r[   rd   )r   r   r   r   Úget_cursor_line_numberº   s    z$BaseEditMixin.get_cursor_line_numberc             C   s2   |   |¡}|  ¡ }| |¡ |  |¡ |  ¡  dS )zSet cursor positionN)r:   r[   rb   ÚsetTextCursorZensureCursorVisible)r   ra   r6   r   r   r   Úset_cursor_position¾   s
    


z!BaseEditMixin.set_cursor_positionr   c             C   s<   |dkrt jnt j}x"tt|ƒƒD ]}|  |t j¡ q"W dS )z/Move cursor to left or right (unit: characters)r   N)r   ÚRightZLeftÚrangeÚabsÚ
moveCursorÚ
MoveAnchor)r   ÚcharsÚ	directionZ_ir   r   r   Úmove_cursorÆ   s    zBaseEditMixin.move_cursorc             C   s   |   ¡ }| tj¡ | ¡ S )z*Return True if cursor is on the first line)r[   r\   r   r]   ZatStart)r   r6   r   r   r   Úis_cursor_on_first_lineÌ   s    z%BaseEditMixin.is_cursor_on_first_linec             C   s   |   ¡ }| tj¡ | ¡ S )z)Return True if cursor is on the last line)r[   r\   r   r^   ÚatEnd)r   r6   r   r   r   Úis_cursor_on_last_lineÒ   s    z$BaseEditMixin.is_cursor_on_last_linec             C   s   |   ¡  ¡ S )z/Return True if cursor is at the end of the text)r[   rr   )r   r   r   r   Úis_cursor_at_endØ   s    zBaseEditMixin.is_cursor_at_endc             C   sH   |   |¡| }|  ¡ }| tj¡ || ¡ k rD| |¡ |  ¡ |k S dS )z*Return True if cursor is before *position*N)r:   r[   r\   r   r_   ra   rb   )r   ra   Zchar_offsetr6   r   r   r   Úis_cursor_beforeÜ   s    
zBaseEditMixin.is_cursor_beforec             C   s¶   |dkst ‚|dkrD|dkr,|  tj|¡ q²|dkr²|  tj|¡ nn|dkr||dkrd|  tj|¡ q²|dkr²|  tj|¡ n6|dkr²|dkrœ|  tj|¡ n|dkr²|  tj|¡ d S )	N)Ú	characterÚwordÚlinerv   ÚleftÚrightrw   rx   ZdownZup)	ÚAssertionErrorrl   r   ÚPreviousCharacterÚNextCharacterÚPreviousWordÚNextWordZ	NextBlockZPreviousBlock)r   Úwhatro   Z	move_moder   r   r   Z__move_cursor_anchorå   s     z"BaseEditMixin.__move_cursor_anchorrw   ry   c             C   s   |   ||tj¡ dS )zs
        Move cursor to next *what* ('word' or 'character')
        toward *direction* ('left' or 'right')
        N)Ú"_BaseEditMixin__move_cursor_anchorr   rm   )r   r€   ro   r   r   r   Úmove_cursor_to_next÷   s    z!BaseEditMixin.move_cursor_to_nextc             C   s   |   ¡ }| ¡  |  |¡ dS )zClear current selectionN)r[   ZclearSelectionrg   )r   r6   r   r   r   Úclear_selection   s    zBaseEditMixin.clear_selectionc             C   s   |   ||tj¡ dS )zx
        Extend selection to next *what* ('word' or 'character')
        toward *direction* ('left' or 'right')
        N)r   r   Ú
KeepAnchor)r   r€   ro   r   r   r   Úextend_selection_to_next  s    z&BaseEditMixin.extend_selection_to_nextc             C   s8   |   |¡}|   |¡}|  ¡ }| |¡ | |tj¡ |S )N)r:   r[   rb   r   r„   )r   Úposition_fromÚposition_tor6   r   r   r   Z__select_text  s    


zBaseEditMixin.__select_textc             C   s2   yt |  ¡ ƒ ¡ | S  tk
r,   |  ¡ S X dS )z)Return text line at line number *line_nb*N)r   rR   rS   Ú
IndexErrorrQ   )r   Zline_nbr   r   r   Úget_text_line  s    zBaseEditMixin.get_text_linec             C   sl   |   ||¡}t| ¡ ƒ}|dko&|dk}|rh|shx| d¡rJ|dd… }q2W x| d¡rf|dd… }qNW |S )z”
        Return text between *position_from* and *position_to*
        Positions may be positions or 'sol', 'eol', 'sof', 'eof' or 'cursor'
        rZ   rY   r7   Néÿÿÿÿu   â€©)Ú_BaseEditMixin__select_textr   ÚselectedTextrT   )r   r†   r‡   r6   r/   Zall_textr   r   r   Úget_text!  s    zBaseEditMixin.get_textc             C   s\   |   |¡| }|  ¡ }| tj¡ || ¡ k rT| |¡ | tjtj¡ t	| 
¡ ƒS dS dS )z5Return character at *position* with the given offset.Ú N)r:   r[   r\   r   r_   ra   rb   ri   r„   r   rŒ   )r   ra   Úoffsetr6   r   r   r   Úget_character0  s    
zBaseEditMixin.get_characterc             C   s   |   ¡ s|  ¡  |¡ dS )zInsert text at cursor positionN)Z
isReadOnlyr[   Ú
insertText)r   r/   r   r   r   Úinsert_text=  s    zBaseEditMixin.insert_textc             C   s"   |   ||¡}| ¡  | |¡ d S )N)r‹   ÚremoveSelectedTextr‘   )r   r†   r‡   r/   r6   r   r   r   Úreplace_textB  s    zBaseEditMixin.replace_textc             C   s   |   ||¡}| ¡  d S )N)r‹   r“   )r   r†   r‡   r6   r   r   r   Úremove_textG  s    zBaseEditMixin.remove_textc                s”   ˆ   ¡ }| ¡ r,| t| ¡ | ¡ gƒ¡ n0‡ fdd„}|tjƒr\|tjƒrPdS | 	tj
¡ | tj¡ t| ¡ ƒ}t d|tj¡}|r|d S dS )z1Return current word, i.e. word at cursor positionc                s(   ˆ   ¡ }| | tj¡ t| ¡ ƒ ¡  S )N)r[   r\   r   r„   r   rŒ   Ústrip)ÚmoveZcurs)r   r   r   Úis_space]  s    z0BaseEditMixin.get_current_word.<locals>.is_spaceNz([^\d\W]\w*)r   )r[   ZhasSelectionrb   ÚminÚselectionStartÚselectionEndr   r}   r|   r\   ZWordLeftÚselectÚWordUnderCursorr   rŒ   ÚreÚfindallÚUNICODE)r   r6   r˜   r/   Úmatchr   )r   r   Úget_current_wordK  s    

zBaseEditMixin.get_current_wordc             C   s    |   ¡ }| tj¡ t| ¡ ƒS )zReturn current line's text)r[   rœ   r   ÚBlockUnderCursorr   rŒ   )r   r6   r   r   r   Úget_current_linem  s    zBaseEditMixin.get_current_linec             C   s   |   | jd¡S )z!Return text from prompt to cursorr6   )r   Úcurrent_prompt_pos)r   r   r   r   Úget_current_line_to_cursors  s    z(BaseEditMixin.get_current_line_to_cursorc             C   s   |   |¡}| ¡ d S )z,Return line number at *coordinates* (QPoint)r#   )ÚcursorForPositionrd   )r   Úcoordinatesr6   r   r   r   Úget_line_number_atw  s    
z BaseEditMixin.get_line_number_atc             C   s*   |   |¡}| tj¡ t| ¡ ƒ dd¡S )z%Return line at *coordinates* (QPoint)u   â€©rŽ   )r§   rœ   r   r£   r   rŒ   r,   )r   r¨   r6   r   r   r   Úget_line_at|  s    
zBaseEditMixin.get_line_atc             C   s"   |   |¡}| tj¡ t| ¡ ƒS )z%Return word at *coordinates* (QPoint))r§   rœ   r   r   r   rŒ   )r   r¨   r6   r   r   r   Úget_word_at‚  s    
zBaseEditMixin.get_word_atc             C   s<   t |  ¡  |¡ ¡ ƒ}| dd| j ¡}t|ƒt| ¡ ƒ S )z*Return line indentation (character number)ú	r"   )r   r@   rA   r/   r,   Ztab_stop_width_spacesr+   Úlstrip)r   Zblock_nbr/   r   r   r   Úget_block_indentationˆ  s    z#BaseEditMixin.get_block_indentationc             C   sJ   |   ¡ }| ¡ | ¡  }}|  ¡  |¡}|  ¡  |¡}t| ¡ | ¡ gƒS )z'Return selection bounds (block numbers))r[   rš   r›   r@   Z	findBlockÚsortedrd   )r   r6   ÚstartÚendZblock_startZ	block_endr   r   r   Úget_selection_boundsŽ  s
    z"BaseEditMixin.get_selection_boundsc             C   s   t t|  ¡  ¡ ƒƒS )z%Returns True if some text is selected)Úboolr   r[   rŒ   )r   r   r   r   Úhas_selected_text˜  s    zBaseEditMixin.has_selected_textc             C   s   t |  ¡  ¡ ƒ d|  ¡ ¡S )uÞ   
        Return text selected by current text cursor, converted in unicode
        
        Replace the unicode line separator character â€© by 
        the line separator characters returned by get_line_separator
        u   â€©)r   r[   rŒ   r,   rQ   )r   r   r   r   Úget_selected_textœ  s    zBaseEditMixin.get_selected_textc             C   s   |   ¡  ¡  dS )zDelete selected textN)r[   r“   )r   r   r   r   Úremove_selected_text¦  s    z"BaseEditMixin.remove_selected_textc             C   sd   |   ¡ }| ¡  |dk	r$t| ¡ ƒ}| ¡  |dk	rNt t|ƒt|ƒt|ƒ¡}| |¡ | ¡  dS )zŒReplace selected text by *text*
        If *pattern* is not None, replacing selected text using regular
        expression text substitutionN)	r[   ÚbeginEditBlockr   rŒ   r“   rž   Úsubr‘   ÚendEditBlock)r   r/   Úpatternr6   Zseltxtr   r   r   r,   ª  s    

zBaseEditMixin.replacec             C   sì   t | ¡ ƒ}t |  ¡ ƒ}yt |¡}W n tjk
r<   dS X |tj@ r”t	| 
¡ | ¡ gƒ}|d|… }dd„ | |d|¡D ƒ}|rŽ|d }	q´dS n t| 
¡ | ¡ gƒ}| ||¡}	|	rè|	 ¡ \}
}|  ¡ }| |
¡ | |tj¡ |S dS )zhReimplement QTextDocument's find method
        
        Add support for *multiline* regular expressionsNc             S   s   g | ]}|‘qS r   r   )Ú.0Ú_mr   r   r   ú
<listcomp>É  s    z8BaseEditMixin.find_multiline_pattern.<locals>.<listcomp>r   rŠ   )r   rº   rR   rž   ÚcompileÚsre_constantsÚerrorr   ÚFindBackwardr™   r›   rš   ÚfinditerÚmaxÚsearchÚspanr[   rb   r   r„   )r   Úregexpr6   Úfindflagrº   r/   Úregobjr   Zmatchesr¡   Zpos1Zpos2Zfcursorr   r   r   Úfind_multiline_pattern»  s*    


z$BaseEditMixin.find_multiline_patternTc             C   st  |   ¡ }t ¡ }|s|tjB }|r,|tjB }tjg}	|r†|	tjtjg7 }	|r’t	| 
¡ ƒrxt| ¡ | ¡ gƒ}
| |
¡ q’| tj¡ n|	tjg7 }	|r t	|ƒ}nt t	|ƒ¡}trÚt|rÂd |¡n|ƒ}|rØ| tj¡ n(t|rêd |¡n||rötjntjtjƒ}xl|	D ]d}| |¡ |r6d|kr6|  |||¡}n|  ¡   |||¡}|dk	r| !¡ s|  "|¡ dS qW dS )z	Find textz\b{}\bz\nNTF)#r[   r   ZFindFlagrÁ   ZFindCaseSensitivelyr   ZNoMover   r`   r   rŒ   r™   rš   r›   rb   r\   r~   r_   rž   r   ÚQT55_VERSIONr   ÚformatZsetPatternOptionsZCaseInsensitiveOptionr   r   ZCaseSensitiveZCaseInsensitiveZRegExp2rÉ   r@   ÚfindZisNullrg   )r   r/   ZchangedZforwardÚcaseZwordsrÆ   r6   rÇ   ZmovesZnew_positionrº   r—   Zfound_cursorr   r   r   Ú	find_textÙ  sL    







zBaseEditMixin.find_textc             C   s   dS )z>Needs to be overloaded in the codeeditor where it will be TrueFr   )r   r   r   r   Ú	is_editor  s    zBaseEditMixin.is_editorrŽ   c             C   sŒ   t |ƒ}|sdS |st |¡}|s.t |  ¡ ƒ}y"|r@t |¡}nt |tj¡}W n tjk
rf   dS X d}x| |¡D ]}|d7 }qxW |S )z0Get the number of matches for the searched text.r   Nr#   )	r   rž   r   rR   r¾   Ú
IGNORECASEr¿   rÀ   rÂ   )r   rº   Úsource_textrÍ   rÆ   rÈ   Znumber_matchesr¡   r   r   r   Úget_number_matches  s"    
z BaseEditMixin.get_number_matchesc             C   s0   |   ¡  ¡ }| jd|d}| j||||d}|S )z.Get number of the match for the searched text.rZ   )r†   r‡   )rÑ   rÍ   rÆ   )r[   ra   r   rÒ   )r   rº   rÍ   rÆ   ra   rÑ   Zmatch_numberr   r   r   Úget_match_number1  s    
zBaseEditMixin.get_match_numberc             C   s   |   d¡ dS )r"   TN)Ú_enter_array)r   r   r   r   Úenter_array_inline;  s    z BaseEditMixin.enter_array_inlinec             C   s   |   d¡ dS )r"   FN)rÔ   )r   r   r   r   Úenter_array_table?  s    zBaseEditMixin.enter_array_tablec             C   sî   |   d¡|   d¡ }|  ¡ }t| ||ƒ}| ¡ }||  ¡  d }| ¡ | ¡ | ¡  d  }|| ¡ d  d }t||ƒ}| 	|  
|¡¡ |  ¡ r |  ¡ }d}	nd}d}	|rê| ¡ rê| ¡ |	 }
|
dkrê|  ¡ }| ¡  | |
¡ | ¡  d	S )
r"   r6   rW   é   é   é   r7   TrŽ   N)r:   rB   r   ry   r   rC   ZbottomZheightr   r—   rD   rÏ   Zis_python_likeZexec_r/   r[   r·   r‘   r¹   )r   Zinliner   ZrectZdlgrE   rF   ÚposZpython_like_checkÚsuffixr/   r6   r   r   r   rÔ   C  s*    

zBaseEditMixin._enter_array)Fr5   NN)r   )r   )rw   ry   )rw   ry   )r   )N)TTFFF)rŽ   FF)FF)3Ú__name__Ú
__module__Ú__qualname__r   r   r4   rL   rN   rQ   rV   r:   r?   re   rf   rh   rp   rq   rs   rt   ru   r   r‚   rƒ   r…   r‹   r‰   r   r   r’   r”   r•   r¢   r¤   r¦   r©   rª   r«   r®   r²   r´   rµ   r¶   r,   rÉ   rÎ   rÏ   rÒ   rÓ   rÕ   rÖ   rÔ   r   r   r   r   r   -   sf    
/

	
	
	

"


 
8 


r   c               @   s8   e Zd ZdZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Z	dS )ÚTracebackLinksMixinr"   Nc             C   s   d| _ |  d¡ d S )NFT)Ú$_TracebackLinksMixin__cursor_changedZsetMouseTracking)r   r   r   r   r   i  s    zTracebackLinksMixin.__init__c             C   sF   | j  | |¡ |  | ¡ ¡}t|ƒrB|  ¡ sB| jdk	rB| j |¡ dS )zGo to errorN)ÚQT_CLASSÚmouseReleaseEventrª   rÚ   r   r´   Úgo_to_errorrM   )r   Úeventr/   r   r   r   râ   n  s
    
z%TracebackLinksMixin.mouseReleaseEventc             C   sd   |   | ¡ ¡}t|ƒr>| js2t ttjƒ¡ d| _| 	¡  dS | jrRt 
¡  d| _| j | |¡ dS )z+Show Pointing Hand Cursor on error messagesTNF)rª   rÚ   r   rà   r   ZsetOverrideCursorr   r   ZPointingHandCursorZacceptÚrestoreOverrideCursorrá   ÚmouseMoveEvent)r   rä   r/   r   r   r   ræ   v  s    z"TracebackLinksMixin.mouseMoveEventc             C   s&   | j rt ¡  d| _ | j | |¡ dS )z.If cursor has not been restored yet, do it nowFN)rà   r   rå   rá   Ú
leaveEvent)r   rä   r   r   r   rç   „  s    zTracebackLinksMixin.leaveEvent)
rÜ   rÝ   rÞ   Ú__doc__rá   rã   r   râ   ræ   rç   r   r   r   r   rß   d  s   rß   c               @   s@   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zdd
d„Zddd„ZdS )ÚGetHelpMixinc             C   s   d | _ d| _d S )NF)ÚhelpÚhelp_enabled)r   r   r   r   r     s    zGetHelpMixin.__init__c             C   s
   || _ dS )zSet Help DockWidget referenceN)rê   )r   Zhelp_pluginr   r   r   Úset_help‘  s    zGetHelpMixin.set_helpc             C   s
   || _ d S )N)rë   )r   Ústater   r   r   Úset_help_enabled•  s    zGetHelpMixin.set_help_enabledc             C   s†   d}|   dd¡}t d|¡}|r:| |d ¡r:||d 7 }|   dd¡}t d|¡}|rp| |d ¡rp||d 7 }|r‚| j|d	d
 d S )NrŽ   rW   r6   z([a-zA-Z_]+[0-9a-zA-Z_\.]*)rŠ   rX   z ([0-9a-zA-Z_\.]+[0-9a-zA-Z_\.]*)r   T)Úforce)r   rž   rŸ   rT   Ú
startswithÚshow_object_info)r   r/   Ztext1Ztl1Ztext2Ztl2r   r   r   Úinspect_current_object˜  s    z#GetHelpMixin.inspect_current_objectFc             C   sj  t |ƒ}| jp|}|r:| jdk	r:| jj d¡ | jj ¡  |r”| jdk	r”| jj ¡ r”t| dƒrl| j | ¡ n| j |  	¡ ¡ | jj
|dd |  ¡  |rf| jrf|  |¡}|dk	rf|rf|  |¡}| d¡d }d }}	t|tƒrêg }|rd	d |¡ d
 }n,|  |¡}
|
dk	r0t|
ƒ}|s0t|
|ƒ}	|s<|	rf|rL|| }n|	}| jtdƒ|ddd dS )z:Show signature calltip and/or docstring in the Help pluginNTZget_docF)Zignore_unknownÚ.rŠ   rŽ   r    r'   Z	Argumentsz#2D62FF)r3   rH   )r   rë   rê   Z
dockwidgetZ
setVisibleZraise_Z	isVisibleÚhasattrZ	set_shellÚparentZset_object_textZsetFocusZcalltipsÚ
iscallableZget_arglistr)   r;   r³   r.   Z
get__doc__r   r   rL   r   )r   r/   Zcallrï   rë   rö   Zarglistr0   Zargspecr3   ÚdocrJ   r   r   r   rñ   ¥  sD    









zGetHelpMixin.show_object_infoc             C   s   t |  ¡ |dS )zB
        Return the last valid object on the current line
        )Úlast)r   r¦   )r   rø   r   r   r   Úget_last_objÙ  s    zGetHelpMixin.get_last_objN)FF)F)	rÜ   rÝ   rÞ   r   rì   rî   rò   rñ   rù   r   r   r   r   ré   Œ  s   
4ré   c               @   s6   e Zd ZdZdZg ZdZd	dd„Zdd„ Zdd„ Z	dS )
ÚSaveHistoryMixinNrŽ   c             C   s   || _ |  ¡  d S )N)Úhistory_filenameÚcreate_history_filename)r   rû   r   r   r   r   è  s    zSaveHistoryMixin.__init__c             C   s@   | j r<t | j ¡s<yt | j| j ¡ W n tk
r:   Y nX dS )z=Create history_filename with INITHISTORY if it doesn't exist.N)rû   ÚospÚisfiler   Ú
writelinesÚINITHISTORYÚEnvironmentError)r   r   r   r   rü   ì  s
    z(SaveHistoryMixin.create_history_filenamec             C   sÞ   t |ƒ}|dks| d¡rdS | d¡r4|dd… }d| _t| jƒdkrZ| jd |krZdS | j |¡ tj| }| j	| j
kr”| j
 | j	¡ | j| }ytj|| j	dd W n tk
r¾   Y nX | jdk	rÚ| j | j	|¡ dS )	zAdd command to history)rŽ   r7   Z	TracebackNr7   rŠ   r   Zab)Úmode)r   rð   rT   Úhistidxr+   Úhistoryr-   rO   rP   rû   ÚHISTORY_FILENAMESÚ	SEPARATORr   Úwriter  Úappend_to_historyrM   )r   Zcommandr/   r   r   r   Úadd_to_historyô  s&    



zSaveHistoryMixin.add_to_history)rŽ   )
rÜ   rÝ   rÞ   r   r  r  r  r   rü   r	  r   r   r   r   rú   à  s   
rú   c               @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚBrowseHistoryMixinc             C   s   g | _ d | _d| _d S )NF)r  r  Úhist_wholeline)r   r   r   r   r     s    zBrowseHistoryMixin.__init__c             C   s   |   | jd¡ dS )z4Clear current line (without clearing console prompt)rY   N)r•   r¥   )r   r   r   r   Ú
clear_line  s    zBrowseHistoryMixin.clear_linec             C   s„   |   d¡r| jrd| _|  ¡ }|  || j|¡\}| _|dk	r€| jrV|  ¡  |  |¡ n*|  d¡}|  dd¡ |  |¡ |  	|¡ dS )zBrowse historyrX   FNr6   )
ru   r  r¦   Úfind_in_historyr  r  r’   r:   r•   rh   )r   ÚbackwardÚtocursorr/   Zcursor_positionr   r   r   Úbrowse_history  s    


z!BrowseHistoryMixin.browse_historyc             C   sì   |dkrt | jƒ}|rdnd}|}t |ƒdks4| jr†||7 }|t | jƒksXt | jƒdkrfdt | jƒfS |dk rrd}d| _| j| |fS x`tt | jƒƒD ]F}|||d   t | jƒ }| j| }| |¡r–|t |ƒd… |fS q–W d|fS dS )z7Find text 'tocursor' in history, from index 'start_idx'NrŠ   r#   r   rŽ   T)r+   r  r  rj   rð   )r   r  Z	start_idxr  ÚstepÚidxÚindexÚentryr   r   r   r  .  s$    


z"BrowseHistoryMixin.find_in_historyc             C   s
   d| _ dS )z3Reset the position from which to search the historyN)r  )r   r   r   r   Úreset_search_posF  s    z#BrowseHistoryMixin.reset_search_posN)rÜ   rÝ   rÞ   r   r  r  r  r  r   r   r   r   r
    s
   r
  )1rè   Zxml.sax.saxutilsr   rO   Úos.pathÚpathrý   rž   r¿   r*   Zqtpy.QtCorer   r   Z
qtpy.QtGuir   r   r   Zqtpy.QtWidgetsr   r	   Zqtpyr
   Zspyder_kernels.utils.dochelpersr   r   r   Zspyder.config.baser   Zspyder.py3compatr   r   Zspyder.utilsr   r   r   Zspyder.utils.miscr   Zspyder.widgets.arraybuilderr   Zcheck_versionrÊ   r   r   Úobjectr   rß   ré   rú   r
  r   r   r   r   Ú<module>   s:       ;(T0