import string import color, mode from lex import Grammar, PatternRule, RegionRule from method import Method, Argument from point import Point class Hex(mode.Fundamental): modename = 'Hex' lmargin = 12 rmargin = 18 _ctrans = ['.'] * 256 for c in string.letters + string.digits + string.punctuation + ' ': _ctrans[ord(c)] = c ctrans = ''.join(_ctrans) def __init__(self, w): mode.Fundamental.__init__(self, w) self.bindings = {} self.add_bindings('start-of-line', ('C-a', 'HOME',)) self.add_bindings('end-of-line', ('C-e', 'END',)) #self.add_bindings('backward', ('C-b', 'L_ARROW',)) #self.add_bindings('forward', ('C-f', 'R_ARROW',)) self.add_bindings('center-view', ('C-l',)) self.add_bindings('next-line', ('C-n', 'D_ARROW',)) self.add_bindings('previous-line', ('C-p', 'U_ARROW',)) self.add_bindings('next-section', ('M-n', 'M-D_ARROW',)) self.add_bindings('previous-section', ('M-p', 'M-U_ARROW',)) self.add_bindings('page-down', ('C-v', 'PG_DN',)) self.add_bindings('page-up', ('M-v', 'PG_UP',)) self.add_bindings('goto-beginning', ('M-<',)) self.add_bindings('goto-end', ('M->',)) #self.add_bindings('delete-left', ('DELETE', 'BACKSPACE',)) #self.add_bindings('delete-left-word', ('M-DELETE', 'M-BACKSPACE',)) #self.add_bindings('delete-right', ('C-d',)) #self.add_bindings('delete-right-word', ('M-d',)) #self.add_bindings('kill-region', ('C-w',)) #self.add_bindings('copy-region', ('M-w',)) #self.add_bindings('kill', ('C-k',)) #self.add_bindings('copy', ('M-k',)) #self.add_bindings('yank', ('C-y',)) #self.add_bindings('pop-kill', ('M-y',)) self.add_bindings('right-word', ('M-f',)) self.add_bindings('left-word', ('M-b',)) self.add_bindings('set-mark', ('C-@',)) self.add_bindings('switch-buffer', ('C-x b',)) self.add_bindings('switch-mark', ('C-x C-x',)) self.add_bindings('undo', ('C-/', 'C-x u',)) self.add_bindings('redo', ('M-/', 'M-_', 'C-x r',)) self.add_bindings('goto-line', ('M-g',)) self.add_bindings('forward-chars', ('C-x M-c',)) self.add_bindings('forward-lines', ('C-x M-n',)) self.add_bindings('search', ('C-s',)) self.add_bindings('reverse-search', ('C-r',)) self.add_bindings('regex-search', ('M-C-s',)) self.add_bindings('regex-reverse-search', ('M-C-r',)) self.add_bindings('toggle-margins', ('M-m',)) #self.add_bindings('replace', ('M-%',)) #self.add_bindings('regex-replace', ('M-$',)) self.add_bindings('open-file', ('C-x C-f',)) self.add_bindings('kill-buffer', ('C-x k',)) self.add_bindings('list-buffers', ('C-x C-b',)) self.add_bindings('meta-x', ('M-x',)) #self.add_bindings('wrap-line', ('M-q',)) #self.add_bindings('transpose-words', ('M-t',)) self.add_bindings('save-buffer', ('C-x C-s',)) self.add_bindings('save-buffer-as', ('C-x C-w',)) #self.add_bindings('relex-buffer', ('M-r',)) self.add_bindings('exit', ('C-x C-c',)) self.add_bindings('split-window', ('C-x s', 'C-x 2',)) self.add_bindings('unsplit-window', ('C-u s', 'C-x 1',)) self.add_bindings('toggle-window', ('C-x o',)) #self.add_bindings('delete-left-whitespace', ('C-c DELETE', 'C-c BACKSPACE',)) #self.add_bindings('delete-right-whitespace', ('C-c d',)) #self.add_bindings('insert-space', ('SPACE',)) #self.add_bindings('insert-tab', ('TAB',)) #self.add_bindings('insert-newline', ('RETURN',)) #self.add_bindings('comment-region', ('C-c #',)) #self.add_bindings('uncomment-region', ('C-u C-c #',)) #self.add_bindings('justify-right', ('C-c f',)) #self.add_bindings('justify-left', ('C-c b',)) #self.add_bindings('indent-block', ('C-c >',)) #self.add_bindings('unindent-block', ('C-c <',)) #self.add_bindings('token-complete', ('M-c', 'C-c c', 'C-c TAB',)) #self.add_bindings('open-aes-file', ('C-c a',)) self.add_bindings('open-console', ('M-e',)) self.add_bindings('show-bindings-buffer', ('C-c M-h',)) self.add_bindings('show-functions-buffer', ('C-c M-?',)) self.add_bindings('which-command', ('M-h',)) self.add_bindings('cmd-help-buffer', ('M-?',)) self.add_bindings('set-mode', ('C-x m',)) self.add_bindings('cancel', ('C-]',)) self.add_bindings('exec', ('C-c e', 'C-c !')) self.add_bindings('grep', ('C-c g',)) self.add_bindings('pipe', ('C-c p', 'C-c |')) self.add_bindings('view-buffer-parent', ('C-c .',)) #self.add_bindings('insert-squotes', ('M-\'',)) #self.add_bindings('insert-dquotes', ('M-"',)) self.add_bindings('get-token', ('C-c t',)) #self.add_bindings('insert-text', ('C-c i',)) #self.add_bindings('insert-text2', ('C-c M-i',)) #self.add_bindings('insert-multiline-text', ('C-c m',)) self.add_action_and_bindings(HexForward(), ('C-f', 'R_ARROW',)) self.add_action_and_bindings(HexBackward(), ('C-b', 'L_ARROW',)) 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_action_and_bindings(HexOverwriteChar(c), (c,)) def get_lmargin(self, y, x=0, ended=False, cont=False): lm = self.lmargin if ended: s = ' -------- ' elif x == 0: s = '0x%08x ' % (y * 16) return ((0, s, color.build('cyan', 'default', 'bold')),) def get_rmargin(self, y, x=0, ended=False, cont=False): if ended: return ((0, '', 0),) else: (cx, cy) = self.window.cursor.xy() s = string.translate(self.window.buffer.rawdata[y], self.ctrans) if cy == y: i = self.window.buffer.cursorx_to_datax(cy, cx) if i is None: return ((0, s, color.build('green', 'default', 'bold')),) elif i < len(s) - 1: return ((0, s[0:i], color.build('green', 'default', 'bold')), (i, s[i], color.build('default', 'default', 'bold', 'reverse')), (i + 1, s[i+1:], color.build('green', 'default', 'bold'))) else: return ((0, s[0:i], color.build('green', 'default', 'bold')), (i, s[i], color.build('default', 'default', 'bold', 'reverse'))) else: return ((0, s, color.build('green', 'default', 'bold')),) class HexForward(Method): def _execute(self, w, **vargs): w.forward() end = w.buffer.get_buffer_end() while w.cursor_char().isspace() and w.cursor < end: w.forward() class HexBackward(Method): def _execute(self, w, **vargs): w.backward() start = w.buffer.get_buffer_start() while w.cursor_char().isspace() and w.cursor > start: w.backward() class HexOverwriteChar(Method): _is_method = False def __init__(self, c): self.name = 'hex-overwrite-char-%s' % c self.args = [] self.help = "Overwrite %r into the current hex buffer." % c self.char = c def _execute(self, w, **vargs): w.overwrite_char_at_cursor(self.char) end = w.buffer.get_buffer_end() while w.cursor_char().isspace() and w.cursor < end: w.forward() 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) install = Hex.install