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]*|0x[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: return (Point(m.start(), y), Point(m.end(), y)) x = 0 y += 1 return (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'): return hex elif s.startswith('0') and len(s) > 1: return oct else: return str class GotoPrevNumber(Method): '''Move the cursor to the start of the word to the right''' 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) = 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) = find_next_number(w) if p1 is None: return s = w.buffer.lines[p1.y][p1.x:p2.x] num = int(s) 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) = find_next_number(w) if p1 is None: return s = w.buffer.lines[p1.y][p1.x:p2.x] num = int(s) 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)