def startsHelper(self, s, i, kind, tags, tag=None): ''' return True if s[i:] starts an markdown section. Sets sigStart, sigEnd, sigId and codeEnd ivars. ''' trace = False and not g.unitTesting level, name, i = self.startsSection(s, i) if level == 0: if trace: i2, j2 = g.getLine(s, i-1) g.trace('==== False:', s[i2:j2].rstrip()) return False self.lastSectionLevel = self.sectionLevel self.sectionLevel = level self.sigStart = g.find_line_start(s, i-1) self.sigEnd = i self.sigId = name if trace: i2, j2 = g.getLine(s, i-1) g.trace('==== True:', s[i2:j2].rstrip()) i += 1 while i < len(s): progress = i i2, j2 = g.getLine(s, i) level, name, j = self.startsSection(s, i2) if trace: g.trace('---- body:', level, name, s[i2:j2].rstrip()) if level > 0: break else: i = j assert i > progress self.codeEnd = i if trace: g.trace('found %s...\n%s' % ( self.sigId, s[self.sigStart: self.codeEnd])) return True
def startsSection (self,s,i): ''' Scan one or two lines looking for the start of a section. Sections are an underlined name or a line starting with '#'s. Return (level,name,i): level: 0 for plain lines, n > 0 for section lines. name: the section name or None. i: the new i. ''' i2,j2 = g.getLine(s,i) line = s[i2:j2] if line.startswith('#'): # Found a section line. level = 0 while level < len(line) and line[level] == '#': level += 1 name = line[level:].rstrip() # Retain leading ws. kind = '#' else: # Look ahead if the next line is an underline. i2,j2 = g.getLine(s,j2) line2 = s[i2:j2] level = self.isUnderline(line2) name = line.rstrip() if level > 0 else None kind = {0: '#', 1: '=', 2: '-'}.get(level) # Update the kind dict. if name: d = self.underlineDict d [name] = kind return level,name,j2
def startsSection(self, s, i): ''' Scan one or two lines looking for the start of a section. Sections are an underlined name or a line starting with '#'s. Return (level,name,i): level: 0 for plain lines, n > 0 for section lines. name: the section name or None. i: the new i. ''' i2, j2 = g.getLine(s, i) line = s[i2:j2] if line.startswith('#'): # Found a section line. level = 0 while level < len(line) and line[level] == '#': level += 1 name = line[level:].rstrip() # Retain leading ws. kind = '#' else: # Look ahead if the next line is an underline. i2, j2 = g.getLine(s, j2) line2 = s[i2:j2] level = self.isUnderline(line2) name = line.rstrip() if level > 0 else None kind = {0: '#', 1: '=', 2: '-'}.get(level) # Update the kind dict. if name: d = self.underlineDict d[name] = kind return level, name, j2
def startsSection(self, s, i): '''Scan a line and possible one or two other lines, looking for an underlined or overlined/underlined name. Return (kind,name,i): kind: in ('under','over','plain') name: the name of the underlined or overlined line. i: the following character if kind is not 'plain' ch: the underlining and possibly overlining character. ''' trace = False and not g.unitTesting verbose = False # Under/overlines can not begin with whitespace. i1, j, nows, line = self.getLine(s, i) ch, kind = '', 'plain' # defaults. if nows and self.isUnderLine(line): # an overline. name_i = g.skip_line(s, i1) name_i, name_j = g.getLine(s, name_i) name = s[name_i: name_j].strip() next_i = g.skip_line(s, name_i) i, j, nows, line2 = self.getLine(s, next_i) n1, n2, n3 = len(line), len(name), len(line2) ch1, ch3 = line[0], line2 and line2[0] ok = (nows and self.isUnderLine(line2) and n1 >= n2 and n2 > 0 and n3 >= n2 and ch1 == ch3) if ok: i += n3 ch, kind = ch1, 'over' if ch1 not in self.underlines2: self.underlines2.append(ch1) if trace: g.trace('*** underlines2', self.underlines2, name) if trace and verbose: g.trace('\nline %s\nname %s\nline2 %s' % ( repr(line), repr(name), repr(line2))) #,'\n',g.callers(4)) else: name = line.strip() i = g.skip_line(s, i1) i, j, nows2, line2 = self.getLine(s, i) n1, n2 = len(name), len(line2) # look ahead two lines. i3, j3 = g.getLine(s, j) name2 = s[i3: j3].strip() i4, j4, nows4, line4 = self.getLine(s, j3) n3, n4 = len(name2), len(line4) overline = ( nows2 and self.isUnderLine(line2) and nows4 and self.isUnderLine(line4) and n3 > 0 and n2 >= n3 and n4 >= n3) ok = (not overline and nows2 and self.isUnderLine(line2) and n1 > 0 and n2 >= n1) if ok: i += n2 ch, kind = line2[0], 'under' if ch not in self.underlines1: self.underlines1.append(ch) if trace: g.trace('*** underlines1', self.underlines1, name) if trace and verbose: g.trace('\nname %s\nline2 %s' % ( repr(name), repr(line2))) return kind, name, i, ch
def startsSection(self, s, i): '''Scan a line and possible one or two other lines, looking for an underlined or overlined/underlined name. Return (kind,name,i): kind: in ('under','over','plain') name: the name of the underlined or overlined line. i: the following character if kind is not 'plain' ch: the underlining and possibly overlining character. ''' trace = False and not g.unitTesting verbose = False # Under/overlines can not begin with whitespace. i1, j, nows, line = self.getLine(s, i) ch, kind = '', 'plain' # defaults. if nows and self.isUnderLine(line): # an overline. name_i = g.skip_line(s, i1) name_i, name_j = g.getLine(s, name_i) name = s[name_i: name_j].strip() next_i = g.skip_line(s, name_i) i, j, nows, line2 = self.getLine(s, next_i) n1, n2, n3 = len(line), len(name), len(line2) ch1, ch3 = line[0], line2 and line2[0] ok = (nows and self.isUnderLine(line2) and n1 >= n2 and n2 > 0 and n3 >= n2 and ch1 == ch3) if ok: i += n3 ch, kind = ch1, 'over' if ch1 not in self.underlines2: self.underlines2.append(ch1) if trace: g.trace('*** underlines2', self.underlines2, name) if trace and verbose: g.trace('\nline %s\nname %s\nline2 %s' % ( repr(line), repr(name), repr(line2))) #,'\n',g.callers(4)) else: name = line.strip() i = g.skip_line(s, i1) i, j, nows2, line2 = self.getLine(s, i) n1, n2 = len(name), len(line2) # look ahead two lines. i3, j3 = g.getLine(s, j) name2 = s[i3: j3].strip() i4, j4, nows4, line4 = self.getLine(s, j3) n3, n4 = len(name2), len(line4) overline = ( nows2 and self.isUnderLine(line2) and nows4 and self.isUnderLine(line4) and n3 > 0 and n2 >= n3 and n4 >= n3) ok = (not overline and nows2 and self.isUnderLine(line2) and n1 > 0 and n2 >= n1) if ok: i += n2 ch, kind = line2[0], 'under' if ch not in self.underlines1: self.underlines1.append(ch) if trace: g.trace('*** underlines1', self.underlines1, name) if trace and verbose: g.trace('\nname %s\nline2 %s' % ( repr(name), repr(line2))) return kind, name, i, ch
def startsHelper(self, s, i, kind, tags, tag=None): '''return True if s[i:] starts an rST section. Sets sigStart, sigEnd, sigId and codeEnd ivars.''' trace = False and not g.unitTesting verbose = True kind, name, next, ch = self.startsSection(s, i) if kind == 'plain': return False self.underlineCh = ch self.lastSectionLevel = self.sectionLevel self.sectionLevel = self.computeSectionLevel(ch, kind) self.sigStart = g.find_line_start(s, i) self.sigEnd = next self.sigId = name i = next + 1 if trace: g.trace('sigId', self.sigId, 'next', next) while i < len(s): progress = i i, j = g.getLine(s, i) kind, name, next, ch = self.startsSection(s, i) if trace and verbose: g.trace(kind, repr(s[i:j])) if kind in ('over', 'under'): break else: i = j assert i > progress self.codeEnd = i if trace: if verbose: g.trace('found...\n%s' % s[self.sigStart:self.codeEnd]) else: g.trace('level %s %s' % (self.sectionLevel, self.sigId)) return True
def unreformat(c, head, oldSel, oldYview, original, result, tail, undoType): '''unformat the body and update the selection.''' body = c.frame.body w = body.wrapper # This destroys recoloring. junk, ins = body.setSelectionAreas(head, result, tail) changed = original != head + result + tail if changed: body.onBodyChanged(undoType, oldSel=oldSel, oldYview=oldYview) # Advance to the next paragraph. s = w.getAllText() ins += 1 # Move past the selection. while ins < len(s): i, j = g.getLine(s, ins) line = s[i: j] if line.isspace(): ins = j + 1 else: ins = i break # setSelectionAreas has destroyed the coloring. c.recolor() w.setSelectionRange(ins, ins, insert=ins) # More useful than for reformat-paragraph. w.see(ins) # Make sure we never scroll horizontally. w.setXScrollPosition(0)
def rp_reformat(c, head, oldSel, oldYview, original, result, tail, undoType): '''Reformat the body and update the selection.''' body = c.frame.body w = body.wrapper # This destroys recoloring. junk, ins = body.setSelectionAreas(head, result, tail) changed = original != head + result + tail if changed: s = w.getAllText() # Fix an annoying glitch when there is no # newline following the reformatted paragraph. if not tail and ins < len(s): ins += 1 # 2010/11/16: stay in the paragraph. body.onBodyChanged(undoType, oldSel=oldSel, oldYview=oldYview) else: # Advance to the next paragraph. s = w.getAllText() ins += 1 # Move past the selection. while ins < len(s): i, j = g.getLine(s, ins) line = s[i: j] # 2010/11/16: it's annoying, imo, to treat @ lines differently. if line.isspace(): ins = j + 1 else: ins = i break # setSelectionAreas has destroyed the coloring. c.recolor() w.setSelectionRange(ins, ins, insert=ins) # 2011/10/26: Calling see does more harm than good. # w.see(ins) # Make sure we never scroll horizontally. w.setXScrollPosition(0)
def startsHelper(self, s, i, kind, tags, tag=None): '''return True if s[i:] starts an rST section. Sets sigStart, sigEnd, sigId and codeEnd ivars.''' trace = False and not g.unitTesting verbose = True kind, name, next, ch = self.startsSection(s, i) if kind == 'plain': return False self.underlineCh = ch self.lastSectionLevel = self.sectionLevel self.sectionLevel = self.computeSectionLevel(ch, kind) self.sigStart = g.find_line_start(s, i) self.sigEnd = next self.sigId = name i = next + 1 if trace: g.trace('sigId', self.sigId, 'next', next) while i < len(s): progress = i i, j = g.getLine(s, i) kind, name, next, ch = self.startsSection(s, i) if trace and verbose: g.trace(kind, repr(s[i: j])) if kind in ('over', 'under'): break else: i = j assert i > progress self.codeEnd = i if trace: if verbose: g.trace('found...\n%s' % s[self.sigStart: self.codeEnd]) else: g.trace('level %s %s' % (self.sectionLevel, self.sigId)) return True
def unreformat(c, head, oldSel, oldYview, original, result, tail, undoType): '''unformat the body and update the selection.''' body = c.frame.body w = body.wrapper # This destroys recoloring. junk, ins = body.setSelectionAreas(head, result, tail) changed = original != head + result + tail if changed: body.onBodyChanged(undoType, oldSel=oldSel, oldYview=oldYview) # Advance to the next paragraph. s = w.getAllText() ins += 1 # Move past the selection. while ins < len(s): i, j = g.getLine(s, ins) line = s[i:j] if line.isspace(): ins = j + 1 else: ins = i break # setSelectionAreas has destroyed the coloring. c.recolor() w.setSelectionRange(ins, ins, insert=ins) # More useful than for reformat-paragraph. w.see(ins) # Make sure we never scroll horizontally. w.setXScrollPosition(0)
def rp_reformat(c, head, oldSel, oldYview, original, result, tail, undoType): '''Reformat the body and update the selection.''' body = c.frame.body w = body.wrapper # This destroys recoloring. junk, ins = body.setSelectionAreas(head, result, tail) changed = original != head + result + tail if changed: s = w.getAllText() # Fix an annoying glitch when there is no # newline following the reformatted paragraph. if not tail and ins < len(s): ins += 1 # 2010/11/16: stay in the paragraph. body.onBodyChanged(undoType, oldSel=oldSel, oldYview=oldYview) else: # Advance to the next paragraph. s = w.getAllText() ins += 1 # Move past the selection. while ins < len(s): i, j = g.getLine(s, ins) line = s[i:j] # 2010/11/16: it's annoying, imo, to treat @ lines differently. if line.isspace(): ins = j + 1 else: ins = i break # setSelectionAreas has destroyed the coloring. c.recolor() w.setSelectionRange(ins, ins, insert=ins) # 2011/10/26: Calling see does more harm than good. # w.see(ins) # Make sure we never scroll horizontally. w.setXScrollPosition(0)
def unreformat(c, head, oldSel, oldYview, original, result, tail, undoType): """unformat the body and update the selection.""" p, u, w = c.p, c.undoer, c.frame.body.wrapper s = head + result + tail ins = max(len(head), len(head) + len(result) - 1) bunch = u.beforeChangeBody(p) w.setAllText(s) # Destroys coloring. changed = original != s if changed: p.v.b = w.getAllText() u.afterChangeBody(p, undoType, bunch) # Advance to the next paragraph. ins += 1 # Move past the selection. while ins < len(s): i, j = g.getLine(s, ins) line = s[i:j] if line.isspace(): ins = j + 1 else: ins = i break c.recolor() # Required. w.setSelectionRange(ins, ins, insert=ins) # More useful than for reformat-paragraph. w.see(ins) # Make sure we never scroll horizontally. w.setXScrollPosition(0)
def matchlines(b, miter): res = [] for m in miter: st, en = g.getLine(b, m.start()) li = b[st:en].strip() res.append((li, (m.start(), m.end()))) return res
def matchlines(b, miter): res = [] for m in miter: st, en = g.getLine(b, m.start()) li = b[st:en].strip() res.append((li, (m.start(), m.end() ))) return res
def get_current_line(self,w): s = w.getAllText() ins = w.getInsertPoint() i,j = g.getLine(s,ins) head, tail = s[i:ins], s[ins:j] return head, tail
def getLine (self,s,i): i,j = g.getLine(s,i) line = s[i:j] nows = i == g.skip_ws(s,i) line = line.strip() return i,j,nows,line
def get_current_line(self, w): s = w.getAllText() ins = w.getInsertPoint() i, j = g.getLine(s, ins) head, tail = s[i:ins], s[ins:j] return head, tail
def startsSection(self, s, i): ''' Scan one or two lines looking for the start of a section. Sections are an underlined name or a line starting with '#'s. Return (level,name,i): level: 0 for plain lines, n > 0 for section lines. name: the section name or None. i: the new i. ''' trace = False and not g.unitTesting i2, j2 = g.getLine(s, i) line = s[i2: j2] if trace: g.trace('LINE', repr(line)) level, name = 0, None if line.startswith('#'): # Found a section line. kind = '#' level = 0 while level < len(line) and line[level] == '#': level += 1 name = line[level:].rstrip() # Retain leading ws. if 0: # This is almost impossible for perfect import to handle. # It's certainly not worth the trouble. # If the user want's to get rid of trailing hashes, that's their choice. while name and name.endswith('#'): name = name[:-1] else: # Look ahead if the next line is an underline. # Bug fix: 2016/04/11: don't set j2 here. i3, j3 = g.getLine(s, j2+1) line2 = s[i3: j3] if trace: g.trace('TEST', repr(line2)) level2 = self.isUnderline(line2) name = line.rstrip() if level2 > 0 else None if name: kind = {0: '#', 1: '=', 2: '-'}.get(level2) level = level2 j2 = j3 # Update the kind dict. if name: d = self.underlineDict d[name] = kind if trace: g.trace(level, name, line.rstrip()) return level, name, j2
def skipInterface(self, s, i): '''Skip from the opening delim to *past* the matching closing delim. If no matching is found i is set to len(s)''' trace = False start = i delim2 = 'end.' level = 0 start = i startIndent = self.startSigIndent if trace: g.trace('***', 'startIndent', startIndent, g.callers()) while i < len(s): progress = i if g.is_nl(s, i): backslashNewline = i > 0 and g.match(s, i - 1, '\\\n') i = g.skip_nl(s, i) if not backslashNewline and not g.is_nl(s, i): j, indent = g.skip_leading_ws_with_indent( s, i, self.tab_width) line = g.get_line(s, j) if trace: g.trace('indent', indent, line) if indent < startIndent and line.strip(): # An non-empty underindented line. # Issue an error unless it contains just the closing bracket. if level == 1 and g.match(s, j, delim2): pass else: if j not in self.errorLines: # No error yet given. self.errorLines.append(j) self.underindentedLine(line) elif s[i] in ( ' ', '\t', ): i += 1 # speed up the scan. elif self.startsComment(s, i): i = self.skipComment(s, i) elif self.startsString(s, i): i = self.skipString(s, i) elif g.match(s, i, delim2): i += len(delim2) if trace: g.trace('returns\n', repr(s[start:i])) return i else: i += 1 assert progress < i self.error('no interface') if 1: g.pr('** no interface **') i, j = g.getLine(s, start) g.trace(i, s[i:j]) else: if trace: g.trace('** no interface') return start
def skipInterface(self, s, i): """Skip from the opening delim to *past* the matching closing delim. If no matching is found i is set to len(s)""" trace = False start = i delim2 = "end." level = 0 start = i startIndent = self.startSigIndent if trace: g.trace("***", "startIndent", startIndent, g.callers()) while i < len(s): progress = i if g.is_nl(s, i): backslashNewline = i > 0 and g.match(s, i - 1, "\\\n") i = g.skip_nl(s, i) if not backslashNewline and not g.is_nl(s, i): j, indent = g.skip_leading_ws_with_indent(s, i, self.tab_width) line = g.get_line(s, j) if trace: g.trace("indent", indent, line) if indent < startIndent and line.strip(): # An non-empty underindented line. # Issue an error unless it contains just the closing bracket. if level == 1 and g.match(s, j, delim2): pass else: if j not in self.errorLines: # No error yet given. self.errorLines.append(j) self.underindentedLine(line) elif s[i] in (" ", "\t"): i += 1 # speed up the scan. elif self.startsComment(s, i): i = self.skipComment(s, i) elif self.startsString(s, i): i = self.skipString(s, i) elif g.match(s, i, delim2): i += len(delim2) if trace: g.trace("returns\n", repr(s[start:i])) return i else: i += 1 assert progress < i self.error("no interface") if 1: g.pr("** no interface **") i, j = g.getLine(s, start) g.trace(i, s[i:j]) else: if trace: g.trace("** no interface") return start
def vim_d2(self): vc = self if vc.stroke == 'd': w = vc.event.w s = w.getAllText() for z in range(vc.n): i = w.getInsertPoint() i, j = g.getLine(s, i) w.delete(i, j) return None else: return vc.begin_motion(vc.vim_d3)
def vim_d2(self): vc = self if vc.stroke == 'd': w = vc.event.w s = w.getAllText() for z in range(vc.n): i = w.getInsertPoint() i,j = g.getLine(s,i) w.delete(i,j) return None else: return vc.begin_motion(vc.vim_d3)
def matchlines(self,b, miter): res = [] for m in miter: st, en = g.getLine(b, m.start()) li = b[st:en] ipre = b.rfind("\n", 0, st-2) ipost = b.find("\n", en +1 ) spre = b[ipre +1 : st-1] + "\n" spost = b[en : ipost] res.append((li, (m.start()-st, m.end()-st ), (spre, spost))) return res
def startsSection (self,s,i): ''' Scan one or two lines looking for the start of a section. Sections are an underlined name or a line starting with '#'s. Return (level,name,i): level: 0 for plain lines, n > 0 for section lines. name: the section name or None. i: the new i. ''' i2,j2 = g.getLine(s,i) line = s[i2:j2] if line.startswith('#'): # Found a section line. level = 0 while level < len(line) and line[level] == '#': level += 1 name = line[level:].strip() else: # Look ahead if the next line is an underline. i2,j2 = g.getLine(s,j2) line2 = s[i2:j2] level = self.isUnderline(line2) name = line.strip() if level > 0 else None return level,name,j2
def killLine(self, event): '''Kill the line containing the cursor.''' w = self.editWidget(event) if not w: return s = w.getAllText() ins = w.getInsertPoint() i, j = g.getLine(s, ins) if ins >= len(s) and g.match(s, j - 1, '\n'): # Kill the trailing newline of the body text. i = max(0, len(s) - 1) j = len(s) elif j > i + 1 and g.match(s, j - 1, '\n'): # Kill the line, but not the newline. j -= 1 else: pass # Kill the newline in the present line. self.kill(event, i, j, undoType='kill-line')
def killLine(self, event): '''Kill the line containing the cursor.''' w = self.editWidget(event) if not w: return s = w.getAllText() ins = w.getInsertPoint() i, j = g.getLine(s, ins) if ins >= len(s) and g.match(s, j - 1, '\n'): # Kill the trailing newline of the body text. i = max(0, len(s) - 1) j = len(s) elif j > i + 1 and g.match(s, j - 1, '\n'): # Kill the line, but not the newline. j -= 1 else: pass # Kill the newline in the present line. self.kill(event, i, j, undoType='kill-line')
def success(self, lines, n, n2, p): '''Place the cursor on line n2 of p.b.''' trace = False and not g.unitTesting c = self.c w = c.frame.body.wrapper # Select p and make it visible. if c.p.isOutsideAnyAtFileTree(): p = c.findNodeOutsideAnyAtFileTree(p) c.redraw(p) # Put the cursor on line n2 of the body text. s = w.getAllText() ins = g.convertRowColToPythonIndex(s, n2 - 1, 0) if trace: i, j = g.getLine(s, ins) g.trace('%2s %2s %15s %s' % (n, n2, p.h, repr(s[i: j]))) w.setInsertPoint(ins) c.bodyWantsFocus() w.seeInsertPoint()
def success(self, lines, n, n2, p): '''Place the cursor on line n2 of p.b.''' trace = False and not g.unitTesting c = self.c w = c.frame.body.wrapper # Select p and make it visible. if c.p.isOutsideAnyAtFileTree(): p = c.findNodeOutsideAnyAtFileTree(p) c.redraw(p) # Put the cursor on line n2 of the body text. s = w.getAllText() ins = g.convertRowColToPythonIndex(s, n2 - 1, 0) if trace: i, j = g.getLine(s, ins) g.trace('%2s %2s %15s %s' % (n, n2, p.h, repr(s[i: j]))) w.setInsertPoint(ins) c.bodyWantsFocus() w.seeInsertPoint()
def yankHelper(self, event, pop): """ Helper for yank and yank-pop: pop = False: insert the first entry of the kill ring. pop = True: insert the next entry of the kill ring. """ c = self.c w = self.editWidget(event) if not w: return current = c.p if not current: return text = w.getAllText() i, j = w.getSelectionRange() clip_text = self.getClipboard() if not g.app.globalKillBuffer and not clip_text: return undoType = 'yank-pop' if pop else 'yank' self.beginCommand(w, undoType=undoType) try: if not pop or self.lastYankP and self.lastYankP != current: self.reset = 0 s = self.kbiterator.__next__() if s is None: s = clip_text or '' if i != j: w.deleteTextSelection() if s != s.lstrip(): # s contains leading whitespace. i2, j2 = g.getLine(text, i) k = g.skip_ws(text, i2) if i2 < i <= k: # Replace the line's leading whitespace by s's leading whitespace. w.delete(i2, k) i = i2 w.insert(i, s) # Fix bug 1099035: Leo yank and kill behaviour not quite the same as emacs. # w.setSelectionRange(i,i+len(s),insert=i+len(s)) w.setInsertPoint(i + len(s)) self.lastYankP = current.copy() finally: self.endCommand(changed=True, setLabel=True)
def killToEndOfLine(self, event): '''Kill from the cursor to end of the line.''' w = self.editWidget(event) if not w: return s = w.getAllText() ins = w.getInsertPoint() i, j = g.getLine(s, ins) if ins >= len(s) and g.match(s, j - 1, '\n'): # Kill the trailing newline of the body text. i = max(0, len(s) - 1) j = len(s) elif ins + 1 < j and s[ins:j - 1].strip() and g.match(s, j - 1, '\n'): # Kill the line, but not the newline. i, j = ins, j - 1 elif g.match(s, j - 1, '\n'): i = ins # Kill the newline in the present line. else: i = j if i < j: self.kill(event, i, j, undoType='kill-line')
def killToEndOfLine(self, event): '''Kill from the cursor to end of the line.''' w = self.editWidget(event) if not w: return s = w.getAllText() ins = w.getInsertPoint() i, j = g.getLine(s, ins) if ins >= len(s) and g.match(s, j - 1, '\n'): # Kill the trailing newline of the body text. i = max(0, len(s) - 1) j = len(s) elif ins + 1 < j and s[ins: j - 1].strip() and g.match(s, j - 1, '\n'): # Kill the line, but not the newline. i, j = ins, j - 1 elif g.match(s, j - 1, '\n'): i = ins # Kill the newline in the present line. else: i = j if i < j: self.kill(event, i, j, undoType='kill-line')
def yank(self, event, pop=False): ''' yank: insert the first entry of the kill ring. yank-pop: insert the next entry of the kill ring. ''' c = self.c w = self.editWidget(event) if not w: return current = c.p if not current: return text = w.getAllText() i, j = w.getSelectionRange() clip_text = self.getClipboard() if not g.app.globalKillBuffer and not clip_text: return undoType = 'yank-pop' if pop else 'yank' self.beginCommand(w, undoType=undoType) try: if not pop or self.lastYankP and self.lastYankP != current: self.reset = 0 s = self.kbiterator.next() if s is None: s = clip_text or '' if i != j: w.deleteTextSelection() if s != s.lstrip(): # s contains leading whitespace. i2, j2 = g.getLine(text, i) k = g.skip_ws(text, i2) if i2 < i <= k: # Replace the line's leading whitespace by s's leading whitespace. w.delete(i2, k) i = i2 w.insert(i, s) # Fix bug 1099035: Leo yank and kill behaviour not quite the same as emacs. # w.setSelectionRange(i,i+len(s),insert=i+len(s)) w.setInsertPoint(i + len(s)) self.lastYankP = current.copy() c.frame.body.forceFullRecolor() finally: self.endCommand(changed=True, setLabel=True)
def skipBlock(self, s, i, delim1, delim2): '''Skip from the opening delim to *past* the matching closing delim. If no matching is found i is set to len(s)''' # pylint: disable=signature-differs trace = False and not g.unitTesting # k1, k2 = g.getLine(s,i) # g.trace(s[i:]) i1, level = i, 0 assert s[i] == delim1, (s[i], delim1, g.callers()) while i < len(s): progress = i ch = s[i] if g.is_nl(s, i): i = g.skip_nl(s, i) elif self.startsComment(s, i): i = self.skipComment(s, i) elif ch in '"\'': i = self.skipString(s, i) elif ch == '/': i = self.skipRegex(s, i) elif ch == delim1: level += 1 i += 1 elif ch == delim2: level -= 1 i += 1 if level <= 0: # g.trace('returns:\n\n%s\n\n' % s[i1: i]) return i else: i += 1 assert progress < i self.error('no block: %s' % i) if trace: i2, j2 = g.getLine(s, i1) g.trace(i, level, s[i2:j2 + 1]) return i
def skipBlock(self, s, i, delim1, delim2): '''Skip from the opening delim to *past* the matching closing delim. If no matching is found i is set to len(s)''' # pylint: disable=signature-differs trace = False and not g.unitTesting # k1, k2 = g.getLine(s,i) # g.trace(s[i:]) i1, level = i, 0 assert s[i] == delim1, (s[i], delim1, g.callers()) while i < len(s): progress = i ch = s[i] if g.is_nl(s, i): i = g.skip_nl(s, i) elif self.startsComment(s, i): i = self.skipComment(s, i) elif ch in '"\'': i = self.skipString(s, i) elif ch == '/': i = self.skipRegex(s, i) elif ch == delim1: level += 1 i += 1 elif ch == delim2: level -= 1 i += 1 if level <= 0: # g.trace('returns:\n\n%s\n\n' % s[i1: i]) return i else: i += 1 assert progress < i self.error('no block: %s' % i) if trace: i2, j2 = g.getLine(s, i1) g.trace(i, level, s[i2:j2+1]) return i
def rp_reformat(c, head, oldSel, oldYview, original, result, tail, undoType): """Reformat the body and update the selection.""" p, u, w = c.p, c.undoer, c.frame.body.wrapper s = head + result + tail changed = original != s bunch = u.beforeChangeBody(p) if changed: w.setAllText(s) # Destroys coloring. # # #1748: Always advance to the next paragraph. i = len(head) j = max(i, len(head) + len(result) - 1) ins = j + 1 while ins < len(s): i, j = g.getLine(s, ins) line = s[i:j] # It's annoying, imo, to treat @ lines differently. if line.isspace(): ins = j + 1 else: ins = i break ins = min(ins, len(s)) w.setSelectionRange(ins, ins, insert=ins) # # Show more lines, if they exist. k = g.see_more_lines(s, ins, 4) p.v.insertSpot = ins w.see(k) # New in 6.4. w.see works! if not changed: return # # Finish. p.v.b = s # p.b would cause a redraw. u.afterChangeBody(p, undoType, bunch) w.setXScrollPosition(0) # Never scroll horizontally.
def getLine(self, s, i): i, j = g.getLine(s, i) line = s[i:j] nows = i == g.skip_ws(s, i) line = line.strip() return i, j, nows, line