import re import buffer, default, dirutil, regex, util, window from point import Point from method import Method, Argument num_re = re.compile(r'(?:-?[1-9][0-9]*|0[xX][0-9A-Fa-f]+|0[0-7]+|0)') def find_next_number(w, offset=0): b = w.buffer x, y = w.logical_cursor().xy() x += offset while y < len(b.lines): m = num_re.search(b.lines[y], x) if m: if m.group(0).lower().startswith('0x'): base = 16 elif m.group(0).startswith('0'): base = 8 else: base = 10 return (Point(m.start(), y), Point(m.end(), y), base) x = 0 y += 1 return (None, None, None) def find_prev_number(w, offset=0): b = w.buffer x, y = w.logical_cursor().xy() x += offset while y >= 0: m = m2 = num_re.search(b.lines[y], 0, x) while m2: m = m2 m2 = num_re.search(b.lines[y], m2.end(), x) if m: return (Point(m.start(), y), Point(m.end(), y)) y -= 1 x = len(b.lines[y]) return (None, None) def get_converter(s): if s.startswith('0x') or s.startswith('0X'): return lambda x: '0x%02x' % x elif s.startswith('0') and len(s) > 1: return oct else: return str class GotoPrevNumber(Method): def _execute(self, w, **vargs): (p1, p2) = find_prev_number(w, -1) if p1 is not None: w.goto(p1) class GotoNextNumber(Method): def _execute(self, w, **vargs): (p1, p2, base) = find_next_number(w, 1) if p1 is not None: w.goto(p2.add(-1, 0)) class Increment(Method): '''Increment the next number''' def _execute(self, w, **vargs): (p1, p2, base) = find_next_number(w) if p1 is None: return s = w.buffer.lines[p1.y][p1.x:p2.x] num = int(s, base) conv = get_converter(s) w.set_error('found %r' % num) w.delete(p1, p2) s2 = conv(num + 1) w.insert_string(p1, s2) w.goto(p1) class Decrement(Method): '''Decrement the next number''' def _execute(self, w, **vargs): (p1, p2, base) = find_next_number(w) if p1 is None: return s = w.buffer.lines[p1.y][p1.x:p2.x] num = int(s, base) conv = get_converter(s) w.set_error('found %r' % num) w.delete(p1, p2) s2 = conv(num - 1) w.insert_string(p1, s2) w.goto(p1)