def processReturn(self, stc): """Add a newline and indent to the proper tab level. Indent to the level of the line above. This uses the findIndent method to determine the proper indentation of the line about to be added, inserts the appropriate end-of-line characters, and indents the new line to that indentation level. @param stc: stc of interest """ linesep = stc.getLinesep() stc.BeginUndoAction() # reindent current line (if necessary), then process the return #pos = stc.reindentLine() linenum = stc.GetCurrentLine() pos = stc.GetCurrentPos() col = stc.GetColumn(pos) #linestart = stc.PositionFromLine(linenum) #line = stc.GetLine(linenum)[:pos-linestart] #get info about the current line's indentation ind = stc.GetLineIndentation(linenum) self.dprint("format = %s col=%d ind = %d" % (repr(linesep), col, ind)) stc.SetTargetStart(pos) stc.SetTargetEnd(pos) if col <= ind: newline = linesep + self.getNewLineIndentString(stc, col, ind) elif not pos: newline = linesep else: stc.ReplaceTarget(linesep) pos += len(linesep) end = min(pos + 1, stc.GetTextLength()) # Scintilla always returns a fold level of zero on the last line, # so when trying to indent the last line, must add a newline # character. if pos == end and self.folding_last_line_bug: stc.AddText("\n") end = stc.GetTextLength() # When we insert a new line, the colorization isn't always # immediately updated, so we have to force that here before # calling findIndent to guarantee that the new line will have the # correct fold property set. stc.Colourise(stc.PositionFromLine(linenum), end) stc.SetTargetStart(pos) stc.SetTargetEnd(pos) ind = self.findIndent(stc, linenum + 1) self.dprint("pos=%d ind=%d fold=%d" % (pos, ind, (stc.GetFoldLevel(linenum+1)&wx.stc.STC_FOLDLEVELNUMBERMASK) - wx.stc.STC_FOLDLEVELBASE)) newline = stc.GetIndentString(ind) stc.ReplaceTarget(newline) stc.GotoPos(pos + len(newline)) stc.EndUndoAction()
def electricBackspace(self, stc): """Delete all whitespace before the cursor unless in a string or comment """ start, end = stc.GetSelection() if start != end: stc.ReplaceSelection("") return pos = stc.GetCurrentPos() if pos <= 0: return s = stc.GetStyleAt(pos - 1) if stc.isStyleComment(s) or stc.isStyleString(s): stc.CmdKeyExecute(wx.stc.STC_CMD_DELETEBACK) else: self.dprint("backspace from pos %d" % pos) start = pos while start > 0: c = stc.GetCharAt(start - 1) if c == ord(' ') or c == ord('\t') or c == 10 or c == 13: start -= 1 else: break if start < pos: stc.SetTargetStart(start) stc.SetTargetEnd(pos) stc.ReplaceTarget('') else: stc.CmdKeyExecute(wx.stc.STC_CMD_DELETEBACK)
def electricDelete(self, stc): """Delete all whitespace after the cursor unless in a string or comment """ start, end = stc.GetSelection() if start != end: stc.ReplaceSelection("") return pos = stc.GetCurrentPos() s = stc.GetStyleAt(pos) if stc.isStyleComment(s) or stc.isStyleString(s): stc.CmdKeyExecute(wx.stc.STC_CMD_CLEAR) else: self.dprint("deleting from pos %d" % pos) end = pos while end < stc.GetLength(): c = stc.GetCharAt(end) if c == ord(' ') or c == ord('\t') or c == 10 or c == 13: end += 1 else: break if end > pos: stc.SetTargetStart(pos) stc.SetTargetEnd(end) stc.ReplaceTarget('') else: stc.CmdKeyExecute(wx.stc.STC_CMD_CLEAR)
def reindentLine(self, stc, linenum=None, dedent_only=False): """Reindent the specified line to the correct level. Changes the indentation of the given line by inserting or deleting whitespace as required. This operation is typically bound to the tab key, but regardless to the actual keypress to which it is bound is *only* called in response to a user keypress. @param stc: the stc of interest @param linenum: the line number, or None to use the current line @param dedent_only: flag to indicate that indentation should only be removed, not added @return: the new cursor position, in case the cursor has moved as a result of the indention. """ if linenum is None: linenum = stc.GetCurrentLine() if linenum == 0: # first line is always indented correctly return stc.GetCurrentPos() linestart = stc.PositionFromLine(linenum) # actual indention of current line indcol = stc.GetLineIndentation(linenum) # columns pos = stc.GetCurrentPos() indpos = stc.GetLineIndentPosition(linenum) # absolute character position col = stc.GetColumn(pos) self.dprint("linestart=%d indpos=%d pos=%d col=%d indcol=%d" % (linestart, indpos, pos, col, indcol)) newind = self.findIndent(stc, linenum) if newind is None: return pos if dedent_only and newind > indcol: return pos # the target to be replaced is the leading indention of the # current line indstr = stc.GetIndentString(newind) self.dprint("linenum=%d indstr='%s'" % (linenum, indstr)) stc.SetTargetStart(linestart) stc.SetTargetEnd(indpos) stc.ReplaceTarget(indstr) # recalculate cursor position, because it may have moved if it # was within the target after = stc.GetLineIndentPosition(linenum) self.dprint("after: indent=%d cursor=%d" % (after, stc.GetCurrentPos())) if pos < linestart: return pos newpos = pos - indpos + after if newpos < linestart: # we were in the indent region, but the region was made smaller return after elif pos < indpos: # in the indent region return after return newpos
def prepareSTC(stc, before): print "*** before *** repr=%s\n%s" % (repr(before), before) cursor = before.find("|") stc.SetText(before) # change "|" to the cursor stc.SetTargetStart(cursor) stc.SetTargetEnd(cursor + 1) stc.ReplaceTarget("") stc.GotoPos(cursor) stc.Colourise(0, stc.GetTextLength()) stc.showStyle()
def reindentComment(self, stc, ln, dedent_only): cursor = stc.GetCurrentPos() fc = stc.PositionFromLine(ln) lc = stc.GetLineEndPosition(ln) text = stc.GetTextRange(fc, lc) count = len(text) pos = 0 while pos < count and text[pos] == ' ': pos += 1 stc.SetTargetStart(fc) stc.SetTargetEnd(lc) stc.ReplaceTarget(text[pos:count]) cursor -= pos return cursor
def reindentSourceLine(self, stc, ln, dedent_only): cursor = stc.GetCurrentPos() fc = stc.PositionFromLine(ln) lc = stc.GetLineEndPosition(ln) text = stc.GetTextRange(fc, lc) #dprint("1234567") #dprint(text) #col = stc.GetColumn(cursor) #dprint(" "*col + "_") if len(text) > 5: numbers = text[0:5] continuation = text[5] remainder = text[6:] else: numbers = text + " "*(5 - len(text)) continuation = " " remainder = "" newind = self.findIndent(stc, ln) - 6 if newind < 0: newind = 0 #dprint("newind: %d" % newind) col = stc.GetColumn(cursor) if col < 5: cursor = fc + 6 + newind elif col > 5: before = len(remainder) remainder = remainder.lstrip() leading_blanks = before - len(remainder) #dprint("leading blanks: %d" % leading_blanks) if leading_blanks > newind: cursor -= leading_blanks - newind elif col - 6 <= newind: cursor = fc + 6 + newind remainder = remainder.lstrip() remainder = " "*newind + remainder numbers = numbers.strip() line = "%-5s%s%s" % (numbers, continuation, remainder) #dprint("1234567") #dprint(line) #col = stc.GetColumn(cursor) #dprint(" "*col + "_") stc.SetTargetStart(fc) stc.SetTargetEnd(lc) stc.ReplaceTarget(line) return cursor
def electricChar(self, stc, uchar): i = ord(uchar) if i >= ord('0') and i <= ord('9'): pos = stc.GetCurrentPos() s = stc.GetStyleAt(pos) col = stc.GetColumn(pos) if not stc.isStyleComment(s) and col < 5: ln = stc.LineFromPosition(pos) fc = stc.PositionFromLine(ln) lc = stc.GetLineEndPosition(ln) text = stc.GetTextRange(fc, lc) #dprint("pos=%d col=%d ln=%d fc=%d lc=%d len=%d" % (pos, col, ln, fc, lc, len(text))) #dprint("1234567") #dprint(text) if len(text) > 5: numbers = text[0:5] continuation = text[5] remainder = text[6:] else: numbers = text + " "*(5 - len(text)) continuation = " " remainder = "" numbers = numbers[0:col] + uchar + numbers[col:] before = len(numbers) numbers = numbers.lstrip() if before > len(numbers): col -= before - len(numbers) numbers = numbers.strip() #dprint("pos=%d col=%d ln=%d fc=%d lc=%d len=%d" % (pos, col, ln, fc, lc, len(text))) line = "%-5s%s%s" % (numbers, continuation, remainder) #dprint("1234567") #dprint(line) stc.SetTargetStart(fc) stc.SetTargetEnd(lc) stc.ReplaceTarget(line) stc.GotoPos(fc + col + 1) return True return False