
    Je                        d 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Zddl	m
Z
 ddlmZ ddlmZmZmZmZ ddlmZ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 ddl m!Z!m"Z" ddl m#Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* g dZ+ G d de,      Z- G d de,      Z. G d de,      Z/ G d de,      Z0 G d de,      Z1 G d de1      Z2y)zMix-in classes

These classes were created to be able to provide Spyder's regular text and
console widget features to an independent widget based on QTextEdit for the
IPython console plugin.
    N)parse)
QT_VERSION)QPointQRegularExpressionQtQUrl)QDesktopServicesQTextCursorQTextDocument)QApplication)getargspecfromtextgetobjgetsignaturefromtext)CONF)to_text_string)encoding
sourcecode)syntaxhighlighters)get_error_match)QStylePalette)ArrayBuilderDialog)

r   r      u        c                      e Zd Zej                  Zej                  Zej                  Zej                  Z	dZ
dZdZdZdZdZdZdZdZ e       Zd Zd	 Zd
 ZdNdZd Zd Zddddddedddf
dZdeeee
fdZddee
fdZdde
eedfdZddddedddeeddddfdZeeddfdZ d Z!dOdZ"dNdZ#d Z$d Z%d Z&d Z'd Z(d Z)d Z*d  Z+dOd!Z,d" Z-d# Z.d$ Z/dPd%Z0d& Z1d' Z2d( Z3dPd)Z4d* Z5dQd+Z6dQd,Z7d- Z8d. Z9d/ Z:dRd0Z;dPd1Z<dRd2Z=d3 Z>d4 Z?d5 Z@	 	 dSd6ZA	 	 dSd7ZBd8 ZCd9 ZDd: ZEd; ZFd< ZGd= ZHd> ZId? ZJdOd@ZKdOdAZLdB ZMdOdCZNdD ZOdOdEZPdF ZQ	 	 dTdGZRdH ZS	 	 dUdIZTdVdJZUdK ZVdL ZWdM ZXy)WBaseEditMixinpython
   <   4      U   Nc                      d | _         d| _        y )NiX  )	eol_charscalltip_sizeselfs    7/usr/lib/python3/dist-packages/spyder/widgets/mixins.py__init__zBaseEditMixin.__init__P   s        c                      y)zReturn line number area widthr    r-   s    r/   get_linenumberarea_widthz&BaseEditMixin.get_linenumberarea_widthU   s     r1   c                     |S )z
        Add offset to a point, to take into account the Editor panels.

        This is reimplemented in CodeEditor, in other widgets it returns
        the same point.
        r3   )r.   points     r/   calculate_real_positionz%BaseEditMixin.calculate_real_positionZ   s	     r1   c                    | j                         }|]| j                         j                         dz  dz   }t        |j	                         |z
        }t        |j                         |z
        }n|Xd}|dz
  }t        | j                         j                  |            }t        | j                  |      j                               }n>| j                  d      \  }}t        |      }t        ||j                         dz  z
        }t        j                  dk(  r#t        |j                         dz  dz  dz         }	nXt        j                  d	k(  r#t        |j                         dz  d
z        dz   }	n"t        |j                         dz  dz        dz   }	| j!                  t#        ||            }
| j%                  |
      }
|
j'                  |
j                         |	z          |
S )z
        Calculate a global point position `QPoint(x, y)`, for a given
        line, local cursor position, or local point.
                 cursordarwing333333?g\(\?g      @ntg?   )fontdocumentdocumentMarginintxyr
   findBlockByNumber
cursorRecttopget_coordinates	pointSizesysplatformosnamemapToGlobalr   r7   setY)r.   at_lineat_pointr@   margincxcyliner<   deltar6   s              r/   _calculate_positionz!BaseEditMixin._calculate_positiond   s   
 yy{mmo446:a?FXZZ\F*+BXZZ\F*+B BQ;D !B!B4!HIFT__V,0023B ))(3FBRBR$..*Q../B <<8#)D0T9C?@EWW_)D0T9:Q>E)D0T9:Q>E   B0,,U3

5779u$%r1   c                 R   t        |      | j                  v ry| j                  j                  t        |             t        j                  }t        j
                  }|j                  j                  }|j                  |       dj                  |||      }|j                  |       y)z4Update the background stylesheet to make it lighter.Nzs
            {0}#{0} {{
                background-color:{1};
                border: 1px solid {2};
            }})id_styled_widgetsaddr   COLOR_BACKGROUND_4COLOR_TEXT_4	__class____name__setObjectNameformatsetStyleSheet)r.   widget
backgroundborderrN   csss         r/   _update_stylesheetz BaseEditMixin._update_stylesheet   s     f:---  F,"55
++((T" &z62	 	
 	S!r1   c                     t        j                  dd      }|r%t        j                  dk(  r|j	                  dd      }|S )zT
        Queries the editor's config to get the current "Inspect" shortcut.
        	shortcutszeditor/inspect current objectr=   CtrlCmd)r   getrK   rL   replace)r.   values     r/   _get_inspect_shortcutz#BaseEditMixin._get_inspect_shortcut   s9     &EF||x'fe4r1   Fc                 x   d}| j                         }|j                         }|j                         }|dkD  r|dz
  n|}| j                  }d}|r!||j	                  ||||      z  }|s|r|dz  }|r)|j                  d      }||j	                  ||||      z  }|#|j                         r|j                         d	k(  rd
}n|j                         }|
s|j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      j                  dd      j                  dd       j                  d!d      j                  dd      j                  d"d!      j                         }g }|D ][  }t        j                  ||#      }|D cg c]  }|j                         s| }}d!j                  |      }|j                  |       ] d!j                  |      }|j                  d      }|j                         }t        |      d$kD  rH|d$   j                         s5|dd }n/|j                  d!      D cg c]  }|j                         s| }}|r7t        |      |kD  rd!j                  |d|       d%z   }nd!j                  |      }|j                  d!d&      }|	r|rd&|z   }||j	                  ||||      z  }d}|rO|rd'j	                  ||(      }n9| j                         }|r'd)t        j                    d*t        j"                   d+}d}|r?|r=|r0|d,t        j$                   d-j	                  ||.      |z   d/z   z  }|S |d0|z   d1z   z  }|S c c}w c c}w )2ay  
        Create HTML template for calltips and tooltips.

        This will display title and text as separate sections and add `...`

        ----------------------------------------
        | `title` (with `title_color`)         |
        ----------------------------------------
        | `signature`                          |
        |                                      |
        | `text` (ellided to `max_lines`)      |
        |                                      |
        ----------------------------------------
        | Link or shortcut with `inspect_word` |
        ----------------------------------------
        z
            <div style='font-family: "{font_family}";
                        font-size: {size}pt;
                        color: {color}'>
                {main_text}
            </div>
        	   r:    )font_familysizecolor	main_textz<hr>r   Nz<no docstring>z!<i>No documentation available</i>     z

z<!DOUBLE_ENTER!>z.
z.<!SINGLE_ENTER!>z
-z<!SINGLE_ENTER!>-z-
z-<!SINGLE_ENTER!>z
=z<!SINGLE_ENTER!>=z=
z=<!SINGLE_ENTER!>z
*z<!SINGLE_ENTER!>*z*
z*<!SINGLE_ENTER!>z
 z<!SINGLE_ENTER!> z 
z <!SINGLE_ENTER!>r   z<!SINGLE_ENTER!>)widthr   z ...<br>z}<span style="font-family: '{font_family}';font-size:{font_size}pt;">Click anywhere in this tooltip for additional help</span>)	font_sizert   zbackground-color:z;color:z;font-size:11px;z*<hr><div align="left"><span style="color: zI;text-decoration:none;font-family:"{font_family}";font-size:{size}pt;><i>)rt   ru   z</i></span></div>zF<hr><div align="left"><span style="color:white;text-decoration:none;">z</span></div>)r@   familyrJ   _DEFAULT_TEXT_COLORrb   striprn   
splitlinestextwrapwrapjoinappendlensplitrp   r   r]   COLOR_TEXT_1COLOR_ACCENT_4)r.   title	signaturetextinspect_wordtitle_color	max_lines	max_widthdisplay_linktext_new_linewith_html_formatBASE_TEMPLATEr@   rt   
title_size	text_size
text_colortemplate
paragraphsnew_paragraphs	paragraphnew_paragraphllines	help_textshortcut
base_styles                              r/   _format_textzBaseEditMixin._format_text   s   ( yy{kkm^^%
&01nJN*	--
,,'!	 -  H yF"!/I,,' #	 -  H L



 006D::<D "77D1"76+=>"75*=>"75*=>"75*=>"75*=>"75*=>"75*=>"75*=>"75*=>"75*=>"74-"7#5v>"7#5t<ZZ\   N' 5	 (iy I -: GqQWWY G G !%		- 8 %%m45 >2J#))&1J))+E 5zA~eAhnn&6ab	 $

4 0>1AGGIQ>E> 5zI%yyz	!23f<yy'||D&)YD=DM((#	 ) 
 	
 	 %f"+$/ % 	   557+M,L,L+M N!!.!;!; < =** 
 !#I ++8+G+G*H I
 v+#,  .!" %88 8"   ## &55 k !H" ?s   (N2>N2N7*N7c                    t        | d|      j                         }ddj                  | j                        dz   }fd}t	        |t
              s|g}g }	|D ]  }
dj                  |
j                               }
|
j                  dd      }
rn|d	k(  rig d
}g d}}||z   D ]O  }||v r%dj                  |      }|j                  ||      },|j                  |d      }j                  |d      Q d|z   dz   }g }|
j                  d      d   }dt        |      dz   z  }t        j                  |
||      }|D ]  }r|d	k(  rt        j                  ||      }|j                  dd      }|j                  dd      }|j                  dd      }|r0|d	k(  r+dD ]&  }|j                  |      }|j                  ||      }( |j                  |        dj                  |      }| j                         }|j!                         }|j#                         }r|d	k(  r|j                  |||      }n|}|	j                  |        dj                  |	      S )z
        Create HTML template for signature.

        This template will include indent after the method name, a highlight
        color for the active parameter and highlights for special chars.

        Special chars depend on the language.
        languagezi<span style='font-family:"{font_family}";font-size:{font_size}pt;color:{color}'><b>{parameter}</b></span>z<span style="color:{0};zfont-weight:bold">{char}</span>c                 N    | j                  d      }|j                        }|S )z
            Handle substitution of active parameter template.

            This ensures the correct highlight of the active parameter.
            r   )grouprn   )matchobjmatchnewactive_parameter_template	parameters      r/   
handle_subz3BaseEditMixin._format_signature.<locals>.handle_subq  s)     NN1%E--	+DECJr1   ry   z( (r$   )|.^$*+)r   ){}[]z\{char})charrs   z[\*|\(|\[|\s](z)[,|\)|\]|\s|=]r   r:   )rz   subsequent_indentz&nbsp;z
span&nbsp;zspan z{}z{{}})r   r   ,r   z**r{   )r|   rt   rv   r   )getattrlowerrb   _CHAR_HIGHLIGHT_COLOR
isinstancelistr   r   rn   r   r   r   resubr   r@   rJ   r}   )r.   
signaturesr   r   parameter_color
char_colorr   chars_templater   new_signaturesr   escape_regex_charsremove_regex_charsregex_parameter
regex_charescape_charpatternformatted_linesrN   indentrowsrowr   new_chartitle_templater@   r|   rt   r   r   s     `                          @r/   _format_signaturezBaseEditMixin._format_signatureV  s    4X6<<> 	" &,,T-G-GH 		 *d+$J# @	)I!23I "))$4I X1 &D"%C""+"47I"I FJ!%77&0&7&7Z&7&H*9*A*A*BM+O +:*A*A*BD+F$-$5$5j"$E	F ->-. !O??3'*DCIM*F==)39;D ,X!5&&*c:Ckk#x0kk,8kk$/H 4 : :#1#8#8d#8#C!kk$9:  &&s+, $[[9N 99;D(I++-K X1&--' +)'	 .  '!!%(A@	)D {{>**r1   c                 h   d}d}d}t        | d|      j                         }|j                  dd      }|j                  dd      }|j                  dd	      }|j                  d
      D 	cg c]  }	d|	vr|	
 }
}	d
j	                  |
      }|dk(  rd}d}|r|j                  |      }n|j                  |      }|d| }d}|r||z   }g }|
D ]p  }	|	j                  |      rU|	j                  |      dkD  rA|	j                  |      }|D cg c]  }||z   	 }}|D cg c]  }|j                          }}n|	g}||z   }r |}
d}|
D ]  }	|	j                  |      s|dz  } |dk(  }|dkD  xr t        |
      dkD  }|r}|s{t        |
      D ]  \  }}	|	j                         dk(  s n dk(  r|
d   }d}n/d
j	                  |
d|       }d
j	                  |
|d       }|d
k(  rd}|r| j                  |||      }n|r|j                  d|z         }|dd }|j                  d
d      }|j                  dd      }|j                  dd      }|j                  dd
      }|j                  d
      }|D cg c]  }|s|	 }}| j                  |||      }d}nd}|}||fS c c}	w c c}w c c}w c c}w )z
        LSP hints might provide docstrings instead of signatures.

        This method will check for multiple signatures (dict, type etc...) and
        format the text accordingly.
        rs   Fr   \*r   r   z&#123;r   z&#125;r   ufuncr$   r   NTr:   r   )r   r   r   r{      ry   z\\*)r   r   rn   r   r   
startswithfindcountr   r   	enumerater   )r.   signature_or_textr   r   r   r   open_func_charhas_signaturehas_multisignaturerV   r   idxname_plus_char	all_linessublinesr   r   ir   
extra_textnew_signaturer   sigs                          r/   _check_signature_and_formatz)BaseEditMixin._check_signature_and_format  sP    "4X6<<>-55eSA .55c8D-55c8D #4"9"9$"? )$4'  ) ) IIe,x N!& 1 < <\ J',,^<0#6 $!-!>	! 	5D7 $

> :Q >#'::n#=@H#I1NQ$6#I#I7?#@!AGGI#@#@$(6 )H 4I	5 "! #D~6
#
 !&
%*QY%A3u:>"!3$U+ 4::<2% Av!!H	!
 IIeBQi0	!YYuQRy1
%!%J $ 6 6('' !7 !
  )11.28>2IKI!!"I!))$4I!))&#6I!))%5I!))&$7I".J)3;#s#;J; 22%## 3 M
 J M*Jj,66a). $J#@Z <s   +J J%J*2J/:J/Tc           	         | j                         }|j                         }d}	t        | d|      j                         }|dk(  rq|ro|j	                  d      d   }	d}
|r/|
j                  |j	                               j                  dd       dj                  |j	                               }|
|k(  r|}d	}|r7|j                  dd      }|j                         r|j                  |d
z   d	      }| j                  |||	||      }|\  }}}	| j                  ||	d||||      }| j                  | j                         | j                  j                  ||g        | j                  j                          y)z
        Show calltip.

        Calltips look like tooltips but will not disappear if mouse hovers
        them. They are useful for displaying signature information on methods
        and functions.
        Nr   r$   r   r   ry   r   r   rs   r   )r   r   r   F)r   r   r   r   r   r   r   )rX   r   r   r   r   r   rn   r   r   rh   calltip_widgetshow_tipshow)r.   r   r   documentationr   r   r   r   r6   r   	check_doc	check_sigresr   r   s                  r/   show_calltipzBaseEditMixin.show_calltip*  s    ((*OO%	4X6<<>xI$??3/2L I}2245==eSI!23II%)	 " )11%=M  - 5 5i$6F K ..y)<H8@9B / D -0)t\  #%' ! 
 	 3 34 	$$UD"5  "r1   c                     | j                  ||      }| j                  |||||||	|
||
      }| j                  | j                         | j                  j	                  ||||       y)zShow tooltip.)rQ   rR   )
r   r   r   r   r   r   r   r   r   r   )r<   completion_docN)rX   r   rh   tooltip_widgetr   )r.   r   r   r   r   r   rQ   rR   r   r   r   r<   r   r   r   r6   tiptexts                    r/   show_tooltipzBaseEditMixin.show_tooltipa  s     (( ) 

 ###%%-' $ 
 	 3 34 	$$UGF4B 	% 	Dr1   c                 "   | j                  |||      }|\  }	}
}| j                  |      }|
b| j                  |      }|j                  t        j
                  t        j                         || _        | j                  |	|
||d|||||
       yy)z'Show code hint and crop text as needed.)r   r   NT)
r   r   rR   r   r   r   r   r<   r   r   )	r   get_word_start_poscursorForPositionmovePositionr
   StartOfWord
MoveAnchor_last_hover_cursorr   )r.   r   r   rR   r   r   r   r   r   html_signaturer   _r6   r<   s                 r/   	show_hintzBaseEditMixin.show_hint  s    
 ..ty<H / J(+%
A''1 !++H5F 7 7 + 6 68&,D#Z',<+/9(1&,9-;  = "r1   c                 b    d| _         d| _        d| _        | j                  j	                          y)a&  
        Hide the tooltip widget.

        The tooltip widget is a special QLabel that looks like a tooltip,
        this method is here so it can be hidden as necessary. For example,
        when the user leaves the Linenumber area when hovering over lint
        warnings and errors.
        N)r   _last_hover_word_last_pointr   hider-   s    r/   hide_tooltipzBaseEditMixin.hide_tooltip  s.     #' $  "r1   c                      y Nr3   r.   r   s     r/   document_did_changez!BaseEditMixin.document_did_change  s    r1   c                 .   |1t        j                  |      }|duxr | j                  du}|| _        n||| j                  k7  }|| _        rH| j                         j	                  d       | j
                  | j
                  j                  |       yyy)a7  
        Set widget end-of-line (EOL) characters.

        Parameters
        ----------
        text: str
            Text to detect EOL characters from.
        eol_chars: str
            EOL characters to set.

        Notes
        -----
        If `text` is passed, then `eol_chars` has no effect.
        NT)r   get_eol_charsr+   rA   setModifiedsig_eol_chars_changedemit)r.   r   r+   detected_eol_charsis_document_modifieds        r/   set_eol_charszBaseEditMixin.set_eol_chars  s     !+!9!9$!?"$.M4>>3M ! 0DN"#,#> &DNMMO''-))5**//	: 6  r1   c                 R    | j                   | j                   S t        j                  S )z/Return line separator based on current EOL mode)r+   rM   linesepr-   s    r/   get_line_separatorz BaseEditMixin.get_line_separator  s     >>%>>!::r1   c                     | j                         }| j                         }t        D ]  }|j                  ||      } |S )za
        Same as 'toPlainText', replacing '
' by correct end-of-line
        characters.
        )toPlainTextr  EOL_SYMBOLSrn   )r.   r   r  symbols       r/   get_text_with_eolzBaseEditMixin.get_text_with_eol  sD    
 !))+! 	1F<<0D	1r1   c                    | j                         }|dk(  r	 |j                         S |dk(  r/|j                  t        j                         |j                         S |dk(  r/|j                  t        j                         |j                         S |dk(  r/|j                  t        j
                         |j                         S |dk(  r/|j                  t        j                         |j                         S |S )zYGet offset in character for the given subject from the start of
           text edit arear<   soleoleofsof)
textCursorr   r
   StartOfBlock
EndOfBlockEndStartposition)r.   subjectr<   s      r/   get_positionzBaseEditMixin.get_position  s     "h     8 89     6 67    0     1 12    Nr1   c                     | j                  |      }| j                         }|j                  |       | j                  |      j	                         }|j                         |j                         fS r  )r&  r  setPositionrG   centerrD   rE   )r.   r$  r<   r6   s       r/   rI   zBaseEditMixin.get_coordinates  sZ    $$X."8$'..0wwy%'')##r1   c                 d   | j                  |      }|j                  t        j                  t        j                         | j                  |      }|j                  t        j                  t        j                         | j                  |      }|j                  |      }|j                  |      S )zS
        Check if the mouse is within the rect of the cursor current word.
        )	r   r   r
   r   r   rG   	EndOfWordunitedcontains)r.   r6   r<   
start_rectend_rectbounding_rects         r/   _is_point_inside_word_rectz(BaseEditMixin._is_point_inside_word_rect  s     ''.K33[5K5KL__V,
K11;3I3IJ??6*"))(3%%e,,r1   c                     | j                  |      }|j                  t        j                  t        j                         | j                  |      }t        |j                         dz   |j                               }|S )zV
        Find start position (lower bottom) of a word being hovered by mouse.
        r   )	r   r   r
   r   r   rG   r   leftrH   )r.   r$  r<   rectposs        r/   r   z BaseEditMixin.get_word_start_pos  s_     ''1K33[5K5KLv&TYY[1_dhhj1
r1   c                     | j                   S )z'Return the last (or active) hover word.r  r-   s    r/   get_last_hover_wordz!BaseEditMixin.get_last_hover_word      $$$r1   c                     | j                   S )z)Return the last (or active) hover cursor.)r   r-   s    r/   get_last_hover_cursorz#BaseEditMixin.get_last_hover_cursor  s    &&&r1   c                 f    || j                         }|j                         |j                         fS )z{
        Return `cursor` (line, column) numbers.

        If no `cursor` is provided, use the current text cursor.
        )r  blockNumbercolumnNumberr.   r<   s     r/   get_cursor_line_columnz$BaseEditMixin.get_cursor_line_column  s2     >__&F!!#V%8%8%:::r1   c                 D    | j                         j                         dz   S )zReturn cursor line numberr:   )r  r=  r-   s    r/   get_cursor_line_numberz$BaseEditMixin.get_cursor_line_number$  s     ,,.q00r1   c                    | j                         j                  |      }t        |      }|j                  t        j                         |j                  t        j
                  t        j                  |dz          |j                         S )z1Get position offset from (line, col) coordinates.r:   )n)rA   rF   r
   r   r   Right
KeepAnchorr$  )r.   rV   colblockr<   s        r/   get_position_line_numberz&BaseEditMixin.get_position_line_number(  sm    11$7U#K445K--{/E/E!Ag 	 	'  r1   c                     | j                  |      }| j                         }|j                  |       | j                  |       | j	                          y)zSet cursor positionN)r&  r  r(  setTextCursorensureCursorVisible)r.   r$  r<   s      r/   set_cursor_positionz!BaseEditMixin.set_cursor_position1  sF    $$X."8$6"  "r1   c                     |dkD  rt         j                  nt         j                  }t        t	        |            D ]"  }| j                  |t         j                         $ y)z/Move cursor to left or right (unit: characters)r   N)r
   rE  Leftrangeabs
moveCursorr   )r.   chars	direction_is       r/   move_cursorzBaseEditMixin.move_cursor9  sG    ).K%%8H8H	E
# 	?BOOI{'='=>	?r1   c                     | j                         }|j                  t        j                         |j	                         S )z*Return True if cursor is on the first line)r  r   r
   r   atStartr?  s     r/   is_cursor_on_first_linez%BaseEditMixin.is_cursor_on_first_line?  s/    "K445~~r1   c                     | j                         }|j                  t        j                         |j	                         S )z)Return True if cursor is on the last line)r  r   r
   r!  atEndr?  s     r/   is_cursor_on_last_linez$BaseEditMixin.is_cursor_on_last_lineE  s.    "K223||~r1   c                 >    | j                         j                         S )z/Return True if cursor is at the end of the text)r  r[  r-   s    r/   is_cursor_at_endzBaseEditMixin.is_cursor_at_endK  s     &&((r1   c                     | j                  |      |z   }| j                         }|j                  t        j                         ||j                         k  r$|j                  |       | j                         |k  S y)z*Return True if cursor is before *position*N)r&  r  r   r
   r"  r$  r(  )r.   r$  char_offsetr<   s       r/   is_cursor_beforezBaseEditMixin.is_cursor_beforeO  si    $$X.<"KOO,foo''x(??$v-- (r1   c                    |dv sJ |dk(  rM|dk(  r!| j                  t        j                  |       y |dk(  r!| j                  t        j                  |       y y |dk(  rM|dk(  r!| j                  t        j                  |       y |dk(  r!| j                  t        j
                  |       y y |dk(  rM|dk(  r!| j                  t        j                  |       y |dk(  r!| j                  t        j                  |       y y y )	N)	characterwordrV   rc  r3  rightrd  rV   downup)rR  r
   PreviousCharacterNextCharacterPreviousWordNextWord	NextBlockPreviousBlock)r.   whatrT  	move_modes       r/   __move_cursor_anchorz"BaseEditMixin.__move_cursor_anchorX  s    4444;F" = =yIg% 9 99E &V^F" 8 8)Dg% 4 4i@ &V^F" 5 5yAd" 9 99E # r1   c                 F    | j                  ||t        j                         y)zs
        Move cursor to next *what* ('word' or 'character')
        toward *direction* ('left' or 'right')
        N)"_BaseEditMixin__move_cursor_anchorr
   r   r.   rn  rT  s      r/   move_cursor_to_nextz!BaseEditMixin.move_cursor_to_nextj      
 	!!$	;3I3IJr1   c                 F    | j                  ||t        j                         y)zx
        Extend selection to next *what* ('word' or 'character')
        toward *direction* ('left' or 'right')
        N)rr  r
   rF  rs  s      r/   extend_selection_to_nextz&BaseEditMixin.extend_selection_to_nextr  ru  r1   c                     | j                  |      }| j                  |      }| j                         }|j                  |       |j                  |t        j                         |S )zSelect text and return cursor.)r&  r  r(  r
   rF  )r.   position_fromposition_tor<   s       r/   _select_textzBaseEditMixin._select_text{  sW    ))-8''4"=);(>(>?r1   c                 $   | j                         j                  |      }t        |      }|j                  t        j                         |j                  t        j
                  t        j                         t        |j                               S )z)Return text line at line number *line_nb*mode)	rA   rF   r
   r   r   r!  rF  r   selectedText)r.   line_nbrH  r<   s       r/   get_text_linezBaseEditMixin.get_text_line  si    11':U#K445K229O9OPf11344r1   c                    | j                         j                  |      }| j                         j                  |      }t        |      }|j                  t        j                         t        |      }|j                  t        j
                         |j                         }|j                  |t        j                         | j                  |      S )z:Return text lines spanned from *start_line* to *end_line*.r}  )
rA   rF   r
   r   r   r!  r$  r(  rF  get_selected_text)r.   
start_lineend_linestart_block	end_blockstart_cursor
end_cursorend_positions           r/   get_text_regionzBaseEditMixin.get_text_region  s    mmo77
CMMO55h?	";/!!+":":; +
 6 67!**,  K4J4J K%%l33r1   c                     | j                  ||      }t        |j                               }|r|dk7  xs |dk7  }|r"|r |r|d   t        v r|dd }|r|d   t        v r|S )ac  Returns text between *position_from* and *position_to*.

        Positions may be integers or 'sol', 'eol', 'sof', 'eof' or 'cursor'.

        Unless position_from='sof' and position_to='eof' any trailing newlines
        in the string are removed. This was added as a workaround for
        spyder-ide/spyder#1546 and later caused spyder-ide/spyder#14374.
        The behaviour can be overridden by setting the optional parameter
        *remove_newlines* to False.

        TODO: Evaluate if this is still a problem and if the workaround can
              be moved closer to where the problem occurs.
        r  r  N)r{  r   r  r  )r.   ry  rz  remove_newlinesr<   r   s         r/   get_textzBaseEditMixin.get_text  ss     ""=+>f1134+u4Lu8LOO48{2CRy 48{2r1   c                 `   | j                  |      |z   }| j                         }|j                  t        j                         ||j                         k  rX|j                  |       |j                  t        j                  t        j                         t        |j                               S y)z5Return character at *position* with the given offset.rs   )r&  r  r   r
   r"  r$  r(  rE  rF  r   r  )r.   r$  offsetr<   s       r/   get_characterzBaseEditMixin.get_character  s    $$X.7"KOO,foo''x( 1 1 + 6 68!&"5"5"788r1   c                    | j                         sp|r'| j                  | j                  j                  |       | j                         j	                  |       | j
                  | j
                  j                          yyy)zInsert text at cursor positionN)
isReadOnlysig_will_insert_textr  r  
insertTextsig_text_was_inserted)r.   r   will_insert_texts      r/   insert_textzBaseEditMixin.insert_text  sk     D$=$=$I))..t4OO((.))5**//1 6	 !r1   c                 ~   | j                  ||      }| j                  0| j                  |      \  }}| j                  j                  ||       |j	                          | j
                  | j
                  j                  |       |j                  |       | j                  | j                  j                          y y r  )r{  sig_will_remove_selectionget_selection_start_endr  removeSelectedTextr  r  r  )r.   ry  rz  r   r<   startends          r/   replace_textzBaseEditMixin.replace_text  s    ""=+>))555f=JE3**//s;!!#$$0%%**40$%%1&&++- 2r1   c                     | j                  ||      }| j                  0| j                  |      \  }}| j                  j                  ||       |j	                          y r  )r{  r  r  r  r  )r.   ry  rz  r<   r  r  s         r/   remove_textzBaseEditMixin.remove_text  sV    ""=+>))555f=JE3**//s;!!#r1   c                    | j                         }|j                         }| j                  d      }|j                  t        j
                         | j                  |j                               j                         r^|j                  t        j
                         |j                         rn.| j                  |j                               j                         r^|j                         }|j                  |       | j                  |j                               j                         r^|j                  t        j                         |j                         rn.| j                  |j                               j                         r^|j                         }| j                  ||      j                         }|}|r"| ||k7  r||v r|j                  |      d   |z   }|S )a  
        Return current object under cursor.

        Get the text of the current word plus all the characters
        to the left until a space is found. Used to get text to inspect
        for Help of elements following dot notation for example
        np.linalg.norm
        T)help_reqr   )r  r$  get_current_wordr   r
   rh  r  r   atBlockStartr(  ri  
atBlockEndr  r   )r.   r<   
cursor_poscurrent_wordcursor_pos_leftcursor_pos_rightcurrent_textcurrent_objects           r/   get_current_objectz BaseEditMixin.get_current_object  s    "__&
,,d,; 	K99:  !2399; = =>""$   !2399; !//+ 	:&  !2399; 9 9:  "   !2399; "??, }}-//4uw 	%L4|+0L &&|4Q7,F  r1   c                      j                         }|j                         }|j                         r:|j                  t	        |j                         |j                         g             n fd} fd}|rl |t        j                        r |j                  t        j                         n |t        j                        r|j                  t        j                         n|sM |t        j                        r |t        j                        ry|j                  t        j                         nL |t        j                        ry |t        j                        r|j                  t        j                         |j                  t        j                         t        |j                               }|j                         }	|r-t!        j"                  d|t         j$                        }
|
sy|
d   }|r|d||	z
   }||	fS )zd
        Return current word, i.e. word at cursor position, and the start
        position.
        c                     j                         }|j                  | t        j                         t	        |j                               j                          S r  )r  r   r
   rF  r   r  r   )movecursr.   s     r/   is_spacez=BaseEditMixin.get_current_word_and_position.<locals>.is_space  sE    (!!$(>(>?)$*;*;*=>DDFFFr1   c                    j                         }|j                  | t        j                         t	        |j                               j                         }t        t        j                  d|t        j                              dk(  S )z7Check if a character is a non-letter including numbers.([^\d\W]\w*)r   )r  r   r
   rF  r   r  r   r   r   findallUNICODE)r  r  text_cursorr.   s      r/   is_special_characterzIBaseEditMixin.get_current_word_and_position.<locals>.is_special_character   sm    (!!$(>(>?,T->->-@AGGIJJRZZHJMNO Or1   Nr  r   )r  r$  hasSelectionr(  minselectionStartselectionEndr
   rh  r   ri  WordLeftselectWordUnderCursorr   r  r   r  r  )r.   
completionr  valid_python_variabler<   r  r  r  r   startposr   s   `          r/   get_current_word_and_positionz+BaseEditMixin.get_current_word_and_position  s    "__&
 
 sF$9$9$;$*$7$7$9$;  < =G
O '(E(EF''(A(AB)+*C*CD''(E(EFK556 = =>''(<(<=K99:()B)BC''(<(<=k112f1134((* !JJbjjAE Qx.h./DX~r1   c                 :    | j                  |||      }||d   S y)z2Return current word, i.e. word at cursor position.)r  r  r  Nr   )r  )r.   r  r  r  rets        r/   r  zBaseEditMixin.get_current_wordK  s7     00!"7 1 
 ?q6M r1   c                     | j                   S )z7Return the last hover word that requested a hover hint.r7  r-   s    r/   get_hover_wordzBaseEditMixin.get_hover_wordW  r9  r1   c                     | j                         }|j                  t        j                         t	        |j                               S )zReturn current line's text.)r  r  r
   BlockUnderCursorr   r  r?  s     r/   get_current_linezBaseEditMixin.get_current_line[  s4    "k223f11344r1   c                 :    | j                  | j                  d      S )z"Return text from prompt to cursor.r<   )r  current_prompt_posr-   s    r/   get_current_line_to_cursorz(BaseEditMixin.get_current_line_to_cursora  s    }}T44h??r1   c                 J    | j                  |      }|j                         dz   S )z-Return line number at *coordinates* (QPoint).r:   )r   r=  r.   coordinatesr<   s      r/   get_line_number_atz BaseEditMixin.get_line_number_ate  s&    ''4!!#a''r1   c                     | j                  |      }|j                  t        j                         t	        |j                               j                  dd      S )z&Return line at *coordinates* (QPoint).r!   rs   )r   r  r
   r  r   r  rn   r  s      r/   get_line_atzBaseEditMixin.get_line_atj  sE    ''4k223f1134<<YKKr1   c                     | j                  |      }|j                  t        j                         | j	                  |      rt        |j                               }|S d}|S )z&Return word at *coordinates* (QPoint).rs   )r   r  r
   r  r1  r   r  )r.   r  r<   rd  s       r/   get_word_atzBaseEditMixin.get_word_atp  sX    ''4k112**;7!&"5"5"78D  Dr1   c                     |j                  dd| j                  z        }t        |      t        |j                               z
  S )zGet indentation for given line.	ry   )rn   tab_stop_width_spacesr   lstripr  s     r/   get_line_indentationz"BaseEditMixin.get_line_indentation{  s7    ||D#d&@&@"@A4yT[[]+++r1   c                     t        | j                         j                  |      j                               }| j	                  |      S )z+Return line indentation (character number).)r   rA   rF   r   r  )r.   block_nbr   s      r/   get_block_indentationz#BaseEditMixin.get_block_indentation  s7    dmmo??INNPQ((..r1   c                 4   || j                         }|j                         |j                         }}| j                         j	                  |      }| j                         j	                  |      }t        |j                         |j                         g      S )z(Return selection bounds (block numbers).)r  r  r  rA   	findBlocksortedr=  )r.   r<   r  r  block_start	block_ends         r/   get_selection_boundsz"BaseEditMixin.get_selection_bounds  s|    >__&F**,f.A.A.Csmmo//6MMO--c2	{..0)2G2G2IJKKr1   c                 "   || j                         }|j                         |j                         }}t        |      }|j	                  |       | j                  |      }t        |      }|j	                  |       | j                  |      }||fS )z8Return selection start and end (line, column) positions.)r  r  r  r
   r(  r@  )r.   r<   r  r  r  start_positionr  r  s           r/   r  z%BaseEditMixin.get_selection_start_end  s    >__&F**,f.A.A.Cs"6*  '44\B (
s#22:>|++r1   c                 b    t        t        | j                         j                                     S )z&Returns True if some text is selected.)boolr   r  r  r-   s    r/   has_selected_textzBaseEditMixin.has_selected_text  s"    N4??#4#A#A#CDEEr1   c                     || j                         }t        |j                               j                  d| j	                               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
        r!   )r  r   r  rn   r  r?  s     r/   r  zBaseEditMixin.get_selected_text  sF     >__&Ff1134<<Y595L5L5NP 	Pr1   c                 D   | j                         j                          t        t              t        d      k  s&t        j
                  dk(  st        j                  dk(  rA| j                         }|j                  |j                                | j                  |       yy)zDelete selected text.z5.15r>   r=   N)r  r  r   r   rM   rN   rK   rL   r(  r$  rK  r?  s     r/   remove_selected_textz"BaseEditMixin.remove_selected_text  sr    ,,. *f-ww$#,,(":__&Fv01v&	 #;r1   c                 V   | j                         }|j                          |t        |j                               }| j                  0| j                  |      \  }}| j                  j                  ||       |j                          |2t        j                  t        |      t        |      t                    }| j                  | j                  j                  |       |j                  |       | j                  | j                  j                          |j                          y)zReplace selected text by *text*.

        If *pattern* is not None, replacing selected text using regular
        expression text substitution.N)r  beginEditBlockr   r  r  r  r  r  r   r   r  r  r  endEditBlock)r.   r   r   r<   seltxtr  r  s          r/   rn   zBaseEditMixin.replace  s    
 "#F$7$7$9:F))555f=JE3**//s;!!#66.1(.v0FHD$$0%%**40$%%1&&++-r1   c                    t        |j                               }t        | j                               }	 t        j                  |      }|t        j                  z  rWt        |j                         |j                         g      }|d| }|j                  |d|      D cg c]  }| }	}|	r|	d   }
n<yt        |j                         |j                         g      }|j                  ||      }
|
r[t        j                   |
      \  }}| j#                         }|j%                  |       |j%                  |t&        j(                         |S y# t
        j                  $ r Y yw xY wc c}w )zbReimplement QTextDocument's find method.

        Add support for *multiline* regular expressions.Nr   r  )r   r   r  r   compilesre_constantserrorr   FindBackwardr  r  r  finditermaxsearchshget_spanr  r(  r
   rF  )r.   regexpr<   findflagr   r   regobjr  _mmatchesr   pos1pos2fcursors                 r/   find_multiline_patternz$BaseEditMixin.find_multiline_pattern  sG    !!12d..01	ZZ(F m000&--/1F1F1HIJF=D$*OOD!V$DEbrEGE &--/1F1F1HIJFMM$/EU+JD$oo'G%k&<&<=N  "" 		 Fs   E 	E%E"!E"c                 z   | j                         }t        j                         }t        | dd      r| j	                         }	nd}	|s|t        j
                  z  }|r|t        j                  z  }t        j                  g}
|r|
t        j                  t        j                  gz  }
|rt        |j                               r;t        |j                         |j                         g      }|j!                  |       n4|j#                  t        j$                         n|
t        j&                  gz  }
|rt        |      }nt)        j*                  t        |            }t-        |rdj/                  |      n|      }|r|j1                  t,        j2                         |
D ]  }|j#                  |       |rd|v r| j5                  |||      }n!| j7                         j9                  |||      }|R|j;                         rc| j=                  |       |	'| j	                         }|	|k7  r|}	| j?                           y y)z
Find text.get_visible_block_numbersFNz\b{}\bz\nT) r  r   FindFlagr   r  r  FindCaseSensitivelyr
   NoMoverk  r#  r   r  r  r  r  r(  r   rj  r"  r   escaper   rb   setPatternOptionsCaseInsensitiveOptionr  rA   r   isNullrK  centerCursor)r.   r   changedforwardcaserd  r  r<   r  current_visible_regionmovesnew_positionr   r  found_cursorfound_visible_regions                   r/   	find_textzBaseEditMixin.find_text  s	    " ))+ 44e<%)%C%C%E"%)"-"<"<<H-"C"CCH##$k**K,=,=>>E!&"5"5"78#&(=(=(?(.(;(;(=(? $@L&&|4''(@(@Akoo&&E!$'D99^D12D$[%7%7%=%)+%%&8&N&NO 	D%%4-#::7F;C E
  $}}33GVXN'0C0C0E""<0 *5+/+I+I+K(-1EE1E.))+)	, r1   c                      y)z>Needs to be overloaded in the codeeditor where it will be TrueFr3   r-   s    r/   	is_editorzBaseEditMixin.is_editor3  s    r1   c                    t        |      }|sy|st        j                  |      }|st        | j                               }|rdj	                  |      }	 |rt        j
                  n t        j                  t        j
                  z  }t        j                  ||      }d}|j                  |      D ]  }	|dz  }	 |S # t        j                  $ r Y yw xY w)z0Get the number of matches for the searched text.r   z\b{pattern}\b)r   )flagsNr:   )r   r   r	  r  rb   	MULTILINE
IGNORECASEr  r  r  r  )
r.   r   source_textr  r  rd  re_flagsr  number_matchesr   s
             r/   get_number_matchesz BaseEditMixin.get_number_matches7  s     !)ii(G()9)9);<K&--g->G	'+r||1MHZZx8F __[1 	 EaN	   "" 		s   A
B? ?CCc                     | j                         j                         }| j                  d|      }| j                  |||||      }|S )z.Get number of the match for the searched text.r  )ry  rz  )r  r  r  rd  )r  r$  r  r   )r.   r   r  r  rd  r$  r  match_numbers           r/   get_match_numberzBaseEditMixin.get_match_numberR  sS    ??$--/mm%XmN..w;F4848 / : r1   c                 &    | j                  d       y)z Enter array builder inline mode.TN_enter_arrayr-   s    r/   enter_array_inlinez BaseEditMixin.enter_array_inline]  s    $r1   c                 &    | j                  d       y)zEnter array builder table mode.FNr%  r-   s    r/   enter_array_tablezBaseEditMixin.enter_array_tablea  s    % r1   c                    | j                  d      | j                  d      z
  }| j                         }t        | ||      }|j                         }t	        |dz
        }|j                         |j                         |j                         z
  dz  z   }t	        ||j                         dz  z
  dz
        }t        ||      }| j                  |      }|j                  | j                  |             | j                         r| j                         }d}	nd}d}	|r|j                         r|j                         |	z   }
|
dk7  r| j!                         }|j#                          | j$                  | j$                  j'                  |
       |j)                  |
       | j*                  | j*                  j'                          |j-                          y	y	y	y	)
zEnter array builder mode.r<   r     r9      r   Trs   N)r&  rG   r   r3  rC   rH   bottomheightr   r7   r  rO   r  is_python_likeexec_r   r  r  r  r  r  r  r  )r.   inliner  r4  dlgrD   rE   r5  python_like_checksuffixr   r<   s               r/   r&  zBaseEditMixin._enter_arraye  s   ""8,t/@/@/GG  vv6 IIKBKHHJ$++-$((*4a77CJJLN"Q&'Ql**3/!!#&' >> $ 3 3 5F !%F88:&Drz*%%',,8--2248!!$'--9..335##%  "-r1   )NNr  )r   )rd  r3  )T)FFT)TTFFF)rs   FFF)FFF)Yr`   
__module____qualname__r   r   _PARAMETER_HIGHLIGHT_COLOR_DEFAULT_TITLE_COLORr   COLOR_TEXT_2r~   _DEFAULT_LANGUAGE_DEFAULT_MAX_LINES_DEFAULT_MAX_WIDTH"_DEFAULT_COMPLETION_HINT_MAX_WIDTH_DEFAULT_MAX_HINT_LINES_DEFAULT_MAX_HINT_WIDTHr  r  r  setr[   r0   r4   r7   rX   rh   rp   r   r   r   r   r   r   r  r	  r  r  r  r&  rI   r1  r   r8  r;  r@  rB  rI  rM  rV  rY  r\  r^  ra  rr  rt  rw  r{  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rn   r  r  r  r   r#  r'  r)  r&  r3   r1   r/   r#   r#   <   s   !.!=!=(77)88'44 )+&     $ eO 

'R"$ "&D"&DD1#(EkZ 7;$6*D%:#4	k+Z HL15.@->e7N 15D/;M15#n "&D"&4H!Du11 &+#'$(!DH 43 $T=2#;<	!&$
-%'	;1!#? ).F$KK54.2
.$)V HM<@EN ;@/3
%5@(
L	,
/
L,F
P'2< @E%*?B @E.36 !#&r1   r#   c                   0    e Zd ZdZdZdZd Zd Zd Zd Z	y)TracebackLinksMixinz=Mixin to make file names in tracebacks and anchors clickable.Nc                 B    d| _         d | _        | j                  d       y )NFT)$_TracebackLinksMixin__cursor_changedanchorsetMouseTrackingr-   s    r/   r0   zTracebackLinksMixin.__init__  s     %d#r1   c                    | j                   j                  | |       | j                  |j                               }t	        |      r9| j                         s)| j                  | j                  j                  |       yy| j                  rDt        j                  t        | j                               t        j                          d| _        yy)zGo to error or link in anchor.N)QT_CLASSmouseReleaseEventr  r5  r   r  sig_go_to_error_requestedr  rE  r	   openUrlr   r   restoreOverrideCursorr.   eventr   s      r/   rI  z%TracebackLinksMixin.mouseReleaseEvent  s    ''e4		,4 )?)?)A--9..33D9 :[[$$T$++%67..0DK r1   c                    | j                  |j                               }| j                  |j                               | _        t	        |      s| j                  rG| j
                  s*t        j                  t        j                         d| _        |j                          y| j
                  rt        j                          d| _        | j                  j                  | |       y)z8Show pointing hand cursor on error messages and anchors.TNF)r  r5  anchorAtrE  r   rD  r   setOverrideCursorr   PointingHandCursoracceptrL  rH  mouseMoveEventrM  s      r/   rT  z"TracebackLinksMixin.mouseMoveEvent  s    		,mmEIIK04 DKK((..r/D/DE(,%LLN  ..0$)D!$$T51r1   c                     | j                   rt        j                          d| _         | j                  j	                  | |       y)z.If cursor has not been restored yet, do it nowFN)rD  r   rL  rH  
leaveEvent)r.   rN  s     r/   rV  zTracebackLinksMixin.leaveEvent  s3      ..0$)D!  u-r1   )
r`   r5  r6  __doc__rH  rJ  r0   rI  rT  rV  r3   r1   r/   rB  rB    s&    GH !%$2$.r1   rB  c                   .    e Zd Zd Zd Zd ZddZddZy)	GetHelpMixinc                     d| _         y NFhelp_enabledr-   s    r/   r0   zGetHelpMixin.__init__  
    !r1   c                     || _         y r  r\  )r.   states     r/   set_help_enabledzGetHelpMixin.set_help_enabled  r^  r1   c                 P    | j                         }|| j                  |d       y y )NT)force)r  show_object_info)r.   r  s     r/   inspect_current_objectz#GetHelpMixin.inspect_current_object  s.    002%!!.!= &r1   c                    t        |      }| j                  xs |}|r |dd}| j                  j                  |       |rt	        | dd      r| j                  |      }||r| j                  |      }|j                  d      d   }dx}	}
t        |t              rg }|rddj                  |      z   d	z   }	n,| j                  |      }|t        |      }	|	st        ||      }
|	s|
r|	r||	z   }n|
}| j                  |       yyyyyy)
z:Show signature calltip and/or docstring in the Help pluginF)rN   ignore_unknowncalltipsNr   r  rs   r   r   )r   r]  sig_help_requestedr  r   
iscallableget_arglistr   r   r  r   
get__doc__r   r   r   )r.   r   callrc  r]  docrj  arglistrN   argspecr   r   s               r/   rd  zGetHelpMixin.show_object_info  s)   d# ((1E"'C ##((- GD*d3.J%"..t4G JJsOB/D*,,Gi!'40"$"%(8"83">"ood3? '9&=G#*,@d,K	)"&*WnG&/G))'2 #,#  & 44r1   c                 8    t        | j                         |      S )zB
        Return the last valid object on the current line
        )last)r   r  )r.   rr  s     r/   get_last_objzGetHelpMixin.get_last_obj  s     d557dCCr1   N)FF)F)r`   r5  r6  r0   ra  re  rd  rs  r3   r1   r/   rY  rY    s    "">
)3VDr1   rY  c                   0    e Zd ZdZdZg ZdZddZd Zd Z	y)SaveHistoryMixinNc                 2    || _         | j                          y r  )history_filenamecreate_history_filename)r.   rw  s     r/   r0   zSaveHistoryMixin.__init__  s     0$$&r1   c                     | j                   rLt        j                  | j                         s,	 t        j                  | j
                  | j                          yyy# t        $ r Y yw xY w)z=Create history_filename with INITHISTORY if it doesn't exist.N)rw  ospisfiler   
writelinesINITHISTORYEnvironmentErrorr-   s    r/   rx  z(SaveHistoryMixin.create_history_filename  sZ      D4I4I)J##D$4$4d6K6KL *K  $ s   *A 	A&%A&c                    t        |      }|dv s|j                  d      ry|j                  d      r|dd }d| _        t	        | j
                        dkD  r| j
                  d   |k(  ry| j
                  j                  |       t        j                  |z   }| j                  | j                  vr4| j                  j                  | j                         | j                  |z   }	 t        j                  || j                  d       | j                  '| j                  j!                  | j                  |       yy# t        $ r Y ?w xY w)	zAdd command to history)rs   r   	TracebackNr   r  r   abr}  )r   r   endswithhistidxr   historyr   rM   r  rw  HISTORY_FILENAMES	SEPARATORr   writer~  sig_append_to_history_requestedr  )r.   commandr   s      r/   add_to_historyzSaveHistoryMixin.add_to_history  s'    )j G$6$6{$CD!crlGt||q T\\"%5%@G$zzG#   (>(>>""))$*?*?@>>D(D	NN4!6!6TB //;0055%%t- <   		s   %"D; ;	EE)rs   )
r`   r5  r6  r}  r  r  r  r0   rx  r  r3   r1   r/   ru  ru     s'    KI&*#'-r1   ru  c                   $    e Zd Zd Zd Zd Zd Zy)BrowseHistoryc                 .    g | _         d | _        d| _        y r[  )r  r  hist_wholeliner-   s    r/   r0   zBrowseHistory.__init__3  s    #r1   c                     |t        |      k  r| j                  rd| _        |d| }| j                  || j                  |      \  }| _        |'|j	                         }| j                  r|dfS ||z   dfS y)zc
        Browse history.

        Return the new text and wherever the cursor should move.
        FNTr[  )r   r  find_in_historyr  r   )r.   rV   r  backwardtocursorr   s         r/   browse_historyzBrowseHistory.browse_history8  s     D	!d&9&9"'D$!11(DLL2:<dl::<D""Tz!$--r1   c                 >   |t        | j                        }|rdnd}|}t        |      dk(  s| j                  rk||z  }|t        | j                        k\  st        | j                        dk(  rdt        | j                        fS |dk  rd}d| _        | j                  |   |fS t        t        | j                              D ]U  }|||dz   z  z   t        | j                        z  }| j                  |   }|j	                  |      sE|t        |      d |fc S  d|fS )z7Find text 'tocursor' in history, from index 'start_idx'Nr  r:   r   rs   T)r   r  r  rP  r   )r.   r  	start_idxr  stepr   indexentrys           r/   r  zBrowseHistory.find_in_historyK  s   DLL)Ir1x=A!4!44KCc$,,''3t||+<+A3t||,,,q"&D<<$c))s4<<01 ' uQw/3t||3DDS)##H- X0#55	' Y&r1   c                     d| _         y)z3Reset the position from which to search the historyN)r  r-   s    r/   reset_search_poszBrowseHistory.reset_search_posc  s	    r1   N)r`   r5  r6  r0   r  r  r  r3   r1   r/   r  r  1  s    $
&'0r1   r  c                   $     e Zd Zd Z fdZ xZS )BrowseHistoryMixinc                 <    | j                  | j                  d       y)z4Clear current line (without clearing console prompt)r  N)r  r  r-   s    r/   
clear_linezBrowseHistoryMixin.clear_linej  s    00%8r1   c                    | j                  | j                  d      }| j                  d      }| j                  d      | j                  z
  }|dk  rd}| j                  | j                         t        t
        |   |||      \  }}|6| j                          | j                  |       |s| j                  |       yyy)zBrowse historyr  r<   r   N)	r  r  r&  rM  superr  r  r  r  )r.   r  rV   old_posr  r   rV  r_   s          r/   r  z!BrowseHistoryMixin.browse_historyn  s    }}T44e<##H-&&x043J3JJ
>J$$T%<%<=!"4dJ*h(kOOT"((1  r1   )r`   r5  r6  r  r  __classcell__)r_   s   @r/   r  r  h  s    92 2r1   r  )3rW  rM   os.pathpathrz  r   r  rK   r   packaging.versionr   qtpyr   qtpy.QtCorer   r   r   r   
qtpy.QtGuir	   r
   r   qtpy.QtWidgetsr   spyder_kernels.utils.dochelpersr   r   r   spyder.config.managerr   spyder.py3compatr   spyder.utilsr   r   r   r  spyder.utils.miscr   spyder.utils.paletter   spyder.widgets.arraybuilderr   r  objectr#   rB  rY  ru  r  r  r3   r1   r/   <module>r     s    
  	  
  $  < < C C 'C C ' + - 1 - . :$L&F L&^*3.& 3.l<D6 <D~.-v .-b4F 4n2 2r1   