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 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 )