From 47a69ab1f8e8b7c9cb99946544176852802d90d0 2006-06-22 17:01:39 From: walter.doerwald Date: 2006-06-22 17:01:39 Subject: [PATCH] Replace the plain dictionaries used for keymaps with a custom class that simplifies handling. --- diff --git a/IPython/Extensions/ibrowse.py b/IPython/Extensions/ibrowse.py index 5ddfded..6659459 100644 --- a/IPython/Extensions/ibrowse.py +++ b/IPython/Extensions/ibrowse.py @@ -145,6 +145,43 @@ class CommandError(Exception): """ +class Keymap(dict): + """ + Stores mapping of keys to commands. + """ + def __init__(self): + self._keymap = {} + + def __setitem__(self, key, command): + if isinstance(key, str): + for c in key: + dict.__setitem__(self, ord(c), command) + else: + dict.__setitem__(self, key, command) + + def register(self, command, *keys): + for key in keys: + self[key] = command + + def __getitem__(self, key): + if isinstance(key, str): + key = ord(key) + return dict.__getitem__(self, key) + + def get(self, key, default=None): + if isinstance(key, str): + key = ord(key) + return dict.get(self, key, default) + + def findkey(self, command, default=ipipe.noitem): + for (key, commandcandidate) in self.iteritems(): + if commandcandidate == command: + return key + if default is ipipe.noitem: + raise KeyError(command) + return default + + class _BrowserCachedItem(object): # This is used internally by ``ibrowse`` to store a item together with its # marked status. @@ -464,29 +501,21 @@ class _BrowserLevel(object): class _CommandInput(object): - keymap = { - curses.KEY_LEFT: "left", - curses.KEY_RIGHT: "right", - curses.KEY_HOME: "home", - 1: "home", - curses.KEY_END: "end", - 5: "end", - # FIXME: What's happening here? - 8: "backspace", - 127: "backspace", - curses.KEY_BACKSPACE: "backspace", - curses.KEY_DC: "delete", - # CTRL-K - 0x0B: "delend", - ord("\n"): "execute", - ord("\r"): "execute", - curses.KEY_UP: "up", - curses.KEY_DOWN: "down", - curses.KEY_PPAGE: "incsearchup", - curses.KEY_NPAGE: "incsearchdown", - # CTRL-X - 0x18: "exit", - } + keymap = Keymap() + keymap.register("left", curses.KEY_LEFT) + keymap.register("right", curses.KEY_RIGHT) + keymap.register("home", curses.KEY_HOME, "\x01") # Ctrl-A + keymap.register("end", curses.KEY_END, "\x05") # Ctrl-E + # FIXME: What's happening here? + keymap.register("backspace", curses.KEY_BACKSPACE, "x\x08\x7f") + keymap.register("delete", curses.KEY_DC) + keymap.register("delend", 0x0b) # Ctrl-K + keymap.register("execute", "\r\n") + keymap.register("up", curses.KEY_UP) + keymap.register("down", curses.KEY_DOWN) + keymap.register("incsearchup", curses.KEY_PPAGE) + keymap.register("incsearchdown", curses.KEY_NPAGE) + keymap.register("exit", "\x18"), # Ctrl-X def __init__(self, prompt): self.prompt = prompt @@ -775,49 +804,40 @@ class ibrowse(ipipe.Display): } # Maps curses key codes to "function" names - keymap = { - ord("q"): "quit", - curses.KEY_UP: "up", - curses.KEY_DOWN: "down", - curses.KEY_PPAGE: "pageup", - curses.KEY_NPAGE: "pagedown", - curses.KEY_LEFT: "left", - curses.KEY_RIGHT: "right", - curses.KEY_HOME: "home", - 1: "home", - curses.KEY_END: "end", - 5: "end", - ord("<"): "prevattr", - 0x1b: "prevattr", # SHIFT-TAB - ord(">"): "nextattr", - ord("\t"):"nextattr", # TAB - ord("p"): "pick", - ord("P"): "pickattr", - ord("C"): "pickallattrs", - ord("m"): "pickmarked", - ord("M"): "pickmarkedattr", - ord("\n"): "enterdefault", - ord("\r"): "enterdefault", - # FIXME: What's happening here? - 8: "leave", - 127: "leave", - curses.KEY_BACKSPACE: "leave", - ord("x"): "leave", - ord("h"): "hideattr", - ord("H"): "unhideattrs", - ord("?"): "help", - ord("e"): "enter", - ord("E"): "enterattr", - ord("d"): "detail", - ord("D"): "detailattr", - ord(" "): "tooglemark", - ord("r"): "markrange", - ord("v"): "sortattrasc", - ord("V"): "sortattrdesc", - ord("g"): "goto", - ord("f"): "find", - ord("b"): "findbackwards", - } + keymap = Keymap() + keymap.register("quit", "q") + keymap.register("up", curses.KEY_UP) + keymap.register("down", curses.KEY_DOWN) + keymap.register("pageup", curses.KEY_PPAGE) + keymap.register("pagedown", curses.KEY_NPAGE) + keymap.register("left", curses.KEY_LEFT) + keymap.register("right", curses.KEY_RIGHT) + keymap.register("home", curses.KEY_HOME, "\x01") + keymap.register("end", curses.KEY_END, "\x05") + keymap.register("prevattr", "<\x1b") + keymap.register("nextattr", ">\t") + keymap.register("pick", "p") + keymap.register("pickattr", "P") + keymap.register("pickallattrs", "C") + keymap.register("pickmarked", "m") + keymap.register("pickmarkedattr", "M") + keymap.register("enterdefault", "\r\n") + # FIXME: What's happening here? + keymap.register("leave", curses.KEY_BACKSPACE, "x\x08\x7f") + keymap.register("hideattr", "h") + keymap.register("unhideattrs", "H") + keymap.register("help", "?") + keymap.register("enter", "e") + keymap.register("enterattr", "E") + keymap.register("detail", "d") + keymap.register("detailattr", "D") + keymap.register("tooglemark", " ") + keymap.register("markrange", "r") + keymap.register("sortattrasc", "v") + keymap.register("sortattrdesc", "V") + keymap.register("goto", "g") + keymap.register("find", "f") + keymap.register("findbackwards", "b") def __init__(self, *attrs): """ @@ -1331,12 +1351,12 @@ class ibrowse(ipipe.Display): footery = 2 keys = [] - for (key, cmd) in self.keymap.iteritems(): - if cmd == "quit": - keys.append("%s=%s" % (self.keylabel(key), cmd)) - for (key, cmd) in self.keymap.iteritems(): - if cmd == "help": - keys.append("%s=%s" % (self.keylabel(key), cmd)) + quitkey = self.keymap.findkey("quit", None) + if quitkey is not None: + keys.append("%s=quit" % self.keylabel(quitkey)) + helpkey = self.keymap.findkey("help", None) + if helpkey is not None: + keys.append("%s=help" % self.keylabel(helpkey)) helpmsg = " | %s" % " ".join(keys) scr.clear() diff --git a/doc/ChangeLog b/doc/ChangeLog index b75a52a..b9e75cc 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,12 @@ +2006-06-22 Walter Doerwald + + * IPython/Extensions/ibrowse.py: Replace the plain dictionaries used + for keymaps with a custom class that simplifies handling. + 2006-06-19 Walter Doerwald * IPython/Extensions/ibrowse.py: ibrowse now properly handles terminal - resizing. This requires Python 2.5 to word. + resizing. This requires Python 2.5 to work. 2006-06-16 Walter Doerwald