def skipSpaceAndWordByRight(lineText,curIndex):
     rightText = lineText[curIndex:]
     for searcher in TextDocument.Searchers:
         matchObj = searcher.match(rightText)
         if matchObj != None:
             return RetuInfo.info( searcher = searcher, offset = matchObj.span()[1] - matchObj.span()[0] )
     return RetuInfo.info( searcher = None,offset = 1)
 def combineRecords(firstRecord,secondRecord):
     if OperateRecord.isRecordCanCombine(firstRecord, secondRecord) == False:
         return RetuInfo.error()
     else:
         if firstRecord.recordType == OperateRecord.OPERATETYPE_INSERTTEXT:
             if firstRecord.indexPos[0] == secondRecord.indexPos[0]:
                 return RetuInfo.success( combinedRecord = OperateRecord.insertText( firstRecord.indexPos,secondRecord.text + firstRecord.text )  )
             else:
                 return RetuInfo.success( combinedRecord = OperateRecord.insertText( firstRecord.indexPos,firstRecord.text + secondRecord.text ) )
         else:
             return RetuInfo.success( combinedRecord = OperateRecord.deleteText( secondRecord.indexPos,firstRecord.length + secondRecord.length ) )
 def sortedIndexPos(indexPos1,indexPos2):
     if FrequentlyUsedFunc.isIndexPosEqual(indexPos1, indexPos2):
         retuObj = RetuInfo.info( first=indexPos1,second=indexPos2,changed=False )
     elif indexPos1[1] == indexPos2[1]:
         if indexPos1[0] >= indexPos2[0]:
             retuObj = RetuInfo.info( first=indexPos2,second=indexPos1,changed=True )
         else:
             retuObj = RetuInfo.info( first=indexPos1,second=indexPos2,changed=False )
     else:
         if indexPos1[1] > indexPos2[1]:
             retuObj = RetuInfo.info( first=indexPos2,second=indexPos1,changed=True )
         else:
             retuObj = RetuInfo.info( first=indexPos1,second=indexPos2,changed=False )
     return retuObj
    def __insertTextWithoutLineBreak(self,xyIndexPosTuple,text):        
        xPos,yPos = xyIndexPosTuple
        curLineText = self.getLineText(yPos)
        self.setLineText(yPos, curLineText[0:xPos] + text + curLineText[xPos:len(curLineText)])

        newXYIndexPos = ( len(curLineText[0:xPos] + text) ,yPos)
        operateRecord = OperateRecord.deleteText( (xPos,yPos),len(text) )
        return RetuInfo.info( newXYIndexPos=newXYIndexPos,operateRecord=operateRecord )
 def __insertLineBreak(self,xyIndexPosTuple):
     xPos,yPos = xyIndexPosTuple
     curLineText = self.getLineText(yPos)
     self.setLineText(yPos,curLineText[0:xPos] )
     self.addLine( yPos + 1,curLineText[xPos:len(curLineText)] )
     
     newXYIndexPos = (0,yPos+1)
     operateRecord = OperateRecord.deleteText( (len(curLineText),yPos),1 )
     return RetuInfo.info( newXYIndexPos=newXYIndexPos,operateRecord=operateRecord )
 def splitTextToLines(text):
     splitN = text.split('\n')
     splitRN = text.split('\r\n')
     if len(splitN) == len(splitRN):
         splitedTexts = splitRN
         splitedChar = '\r\n'
     else:
         splitedTexts = splitN
         splitedChar = '\n'
     return RetuInfo.info( splitedTexts=splitedTexts,splitedChar=splitedChar )
    def __deleteText(self,xyIndexPosTuple,length):
        xPos,yPos = xyIndexPosTuple
        operateRecords = []
        
        while len(self.getLineText(yPos))-xPos < length:
            retuRecord = self.__deleteLineBreak(yPos)
            operateRecords.append( retuRecord )
            length -= 1            
        
        curLineText = self.getLineText(yPos)
        self.setLineText( yPos,curLineText[0:xPos]+curLineText[xPos+length:len(curLineText)] )
        operateRecords.append( OperateRecord.insertText( (xPos,yPos),curLineText[xPos:xPos+length] ) )

        return RetuInfo.info( indexPos = xyIndexPosTuple,operateRecords = operateRecords )
 def __insertText(self,xyIndexPosTuple,text):
     splitedTexts = FUF.splitTextToLines(text)['splitedTexts']
     indexPos = xyIndexPosTuple
     operateRecords = []
     
     for index in range(len( splitedTexts )-1):
         retuDict = self.__insertTextWithoutLineBreak( indexPos , splitedTexts[index])
         indexPos = retuDict['newXYIndexPos']
         operateRecords.append( retuDict['operateRecord'] )
         
         retuDict = self.__insertLineBreak( indexPos)
         indexPos = retuDict['newXYIndexPos']
         operateRecords.append( retuDict['operateRecord'] )
     
     retuDict = self.__insertTextWithoutLineBreak( indexPos , splitedTexts[-1])
     indexPos = retuDict['newXYIndexPos']
     operateRecords.append( retuDict['operateRecord'] )
     
     return RetuInfo.info( indexPos = indexPos,operateRecords = operateRecords )
 def transUserClickedPixelPosToIndexPos(self,xyClickedPixelPosTuple):
     x,y = xyClickedPixelPosTuple
     x = max([x,0])
     lineIndex = self.settings().getStartDisLineNumber() + int((y-CEGD.TextYOff)/self.settings().getFontMetrics().lineSpacing())
     lineIndex = FUF.calcMidNumberByRange(0, lineIndex, self.__textDocument.getLineCount()-1)
     
     charWidthArray = self.__textDocument.getLineCharWidthArrayByIndex(lineIndex)
             
     startX = 0 - self.settings().getStartDisLetterXOff()
     xIndex = 0
     while xIndex < len(charWidthArray):
         charWidth = charWidthArray[xIndex]
         startX += charWidth + CEGD.CharDistancePixel
         xIndex += 1
         if startX >= x:
             break
     if startX > x:
         if ( startX - (charWidth + CEGD.CharDistancePixel)/2 > x ):
             startX -= (charWidth + CEGD.CharDistancePixel)
             xIndex -= 1
     return RetuInfo.info( indexPos = ( xIndex,lineIndex ) , offset = x-startX )
    def __calcDescAndStrIndexPosRanges(self,lastKey,lineIndex,sharpAndQuotePoss):
        lineText = self.getLineText(lineIndex)
        descIndexPosArr = []
        strIndexPosArr = []
        
        lastPos = None 
        index = 0
        while index < len(sharpAndQuotePoss):
            pos,token = sharpAndQuotePoss[index]
            index += 1
            
            if lastKey == None:
                if token == '#':
                    descIndexPosArr.append( pos )       # 如果一个 # 不在字符串内,则它右边的字符串将会全部视为注释
                    break
                else:
                    if len(token) == 1 or len(token) == 3:
                        lastPos = pos
                        lastKey = token
                    elif len(token) == 2:
                        strIndexPosArr.append( pos )
                        strIndexPosArr.append( pos+2 )
                        # strIndexPosArr.append( {'start':,'end':,'key':token[0]} )
                    elif len(token) > 3:
                        lastKey = token[0:3]
                        lastPos = pos
                        sharpAndQuotePoss.insert( index, (pos+3,token[3:]) )
            
            elif lastKey == "'''" or lastKey == '"""' or lastKey == "'" or lastKey == '"':
                if lastKey[0] != token[0]:
                    continue
            
                # 如果当前遇到的token的左侧存在转义符的个数为奇数个,则token中的第一个字符将会被转义
                # realEscapeNumber表示作为转义符而存在的转义符(如 '\\'中的第二个 \ ,实际上是作为被转义符而不是转义符存在的)
                realEscapeNumber = PythonTextDocument.__findEscapeCharNumberFromRightToLeft(lineText,pos) % 2
                pos += realEscapeNumber
                token = token[realEscapeNumber:]
                
                # 如果剩下来的边界字符个数小与lastKey的字符个数,则表明本次匹配失败
                lastKeyLength = len(lastKey)
                if len(token) < lastKeyLength:
                    continue
                else:
                    if lastPos != None:
                        strIndexPosArr.append( lastPos )
                    strIndexPosArr.append( pos+lastKeyLength )

                    lastKey = None
                    lastPos = None
                    
                    # 如果剩下来的边界字符个数大与lastKey的字符个数,则需要将剩下来的字符再放回去
                    if len(token) >  lastKeyLength:
                        sharpAndQuotePoss.insert( index, (pos+lastKeyLength,token[lastKeyLength:]) )                    
        
        # 如果该行剩余 ' 或 " 没有匹配,则默认匹配到该行尾(不跨行)
        if lastKey == '"' or lastKey == "'":
            if PythonTextDocument.__findEscapeCharNumberFromRightToLeft( lineText,len(lineText) ) % 2 == 0:
                if lastPos != None:
                    strIndexPosArr.append( lastPos )
                strIndexPosArr.append( len(lineText) )
                lastKey = None
                lastPos = None
        
        return RetuInfo.info( descIndexPosArr=descIndexPosArr,strIndexPosArr=strIndexPosArr,lastKey=lastKey,lastPos=lastPos )