import re, sets, string, sys import color, commands, default, lex2, method, mode2, regex, tab2 from point2 import Point from lex2 import Grammar, ConstantRule, PatternRule, ContextPatternRule, \ RegionRule, DualRegionRule class Life(mode2.Fundamental): def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_action(LifeShiftLeft()) self.add_action(LifeShiftRight()) self.add_action_and_bindings(LifeDoTurn(), ('M-RETURN',)) for c in string.letters + string.digits + string.punctuation: self.add_action_and_bindings(LifeInsertString(c), c) self.token = 'o' w.buffer.set_lines(self.normalize_board(), force=True) w.goto_beginning() def name(self): return "Life" def normalize_board(self): lines = self.window.buffer.lines s = ' ' * (self.window.width-1) newlines = [s] * (self.window.height-1) for i in range(0, min(len(lines), (self.window.height-1))): chars = [' '] * (self.window.width-1) for j in range(0, min(len(lines[i]), (self.window.height-1))): if lines[i][j] != ' ': chars[j] = self.token newlines[i] = ''.join(chars) return newlines class LifeShiftLeft(method.Method): def _execute(self, w, **vargs): newlines = list(w.buffer.lines) for i in range(0, len(newlines)): newlines[i] = newlines[i][10:] + newlines[i][:10] w.buffer.set_lines(newlines) w.goto_beginning() class LifeShiftRight(method.Method): def _execute(self, w, **vargs): newlines = list(w.buffer.lines) for i in range(0, len(newlines)): newlines[i] = newlines[i][-10:] + newlines[i][:-10] w.buffer.set_lines(newlines) w.goto_beginning() # insert text class LifeInsertString(method.Method): _is_method = False def __init__(self, s): self.name = "life-insert-string-%s" % (s) self.args = [] self.help = "Insert %r into the current buffer." % s self.string = s def _execute(self, w, **vargs): if w.cursor_char() == '\n': return w.right_delete() w.insert_string_at_cursor(w.mode.token) class LifeDoTurn(method.Method): '''Run a turn of life on the current buffer''' def _execute(self, w, **vargs): lines = w.mode.normalize_board() newlines = list(lines) w.buffer.set_lines(lines) w.goto_beginning() for y in range(0, (w.height-1)): line = list(newlines[y]) for x in range(0, (w.width-1)): on = lines[y][x] != ' ' count = 0 for (i,j) in ((-1, -1), (-1, 0), (-1, 1), (0, 1), (0, -1), (1, -1), (1, 0), (1, 1)): y2 = (y + i) % (w.height-2) x2 = (x + j) % (w.width-2) if lines[y2][x2] != ' ': count += 1 if count == 3 or count == 2 and on: line[x] = w.mode.token else: line[x] = ' ' newlines[y] = ''.join(line) w.buffer.set_lines(newlines) w.goto_beginning()