import string import color, mode2 from lex3 import Grammar, PatternRule, RegionRule from method import Method, Argument from point2 import Point class HexGrammar(Grammar): rules = [ PatternRule(r'zero', r"00"), PatternRule(r'byte', r'[0-f][0-f]'), ] class Hex(mode2.Fundamental): grammar = HexGrammar colors = { 'zero': ('magenta', 'default'), 'byte': ('white', 'default'), } def __init__(self, w): mode2.Fundamental.__init__(self, w) self.add_action_and_bindings(GotoWord(), ('M-g',)) self.add_action(FindStrings()) self.add_action(WhichWord()) # create all the insert actions for the basic text input for c in string.letters + string.digits + string.punctuation: if c in string.hexdigits: self.add_binding('overwrite-char-%s' % c.lower(), c) else: self.del_binding(c) def name(self): return "Hex" class GotoWord(Method): '''Jump to the specified line number''' args = [Argument("wordno", type=type(0), prompt="Goto word: ")] def _execute(self, w, **vargs): n = vargs["wordno"] if n < 0: w.set_error("Negative word counts not supported.") try: x = (n % w.buffer.numwords) * (w.buffer.wordsize + 1) y = n / w.buffer.numwords p = Point(x, y) w.goto(p) except: w.goto_end() class WhichWord(Method): '''Show the current word number''' def _execute(self, w, **vargs): cursor = w.logical_cursor() n = cursor.y * w.buffer.numwords n += cursor.x / (w.buffer.wordsize + 1) w.set_error("Currently in word %s (%s)" % (hex(n), n)) class FindStrings(Method): def _execute(self, w, **vargs): newlines = [] lastline = '' i = 0 for line in w.buffer.lines: lastc = None newline = "" for c in line: if c not in '0123456789abcdefABCDEF': lastc = None elif lastc is None: lastc = c else: char = chr(int(lastc + c, 16)) lastc = None if char in string.whitespace: newline += ' ' elif char in string.letters + string.digits + string.punctuation: newline += char else: newline += '.' if lastc is not None: newline += '.' if i == 3: newlines.append(lastline) lastline = '' else: lastline += newline i = (i + 1) % 4 w.application.data_buffer("*Strings*", '\n'.join(newlines), switch_to=True)