| 1 | ### -*-python -*- |
| 2 | |
| 3 | def __mdw_hack_bindings(): |
| 4 | |
| 5 | import IPython as IPY |
| 6 | import prompt_toolkit as PTK |
| 7 | |
| 8 | def ding(): |
| 9 | with open('/dev/tty', 'w') as f: f.write('\a') |
| 10 | |
| 11 | ## Key bindings. Alas, IPython's attempt at Emacs keybindings is abysmal. |
| 12 | K = PTK.keys.Keys |
| 13 | F = PTK.filters |
| 14 | BUF = PTK.enums.DEFAULT_BUFFER |
| 15 | ipy = IPY.get_ipython() |
| 16 | try: pt = ipy.pt_cli |
| 17 | except AttributeError: return |
| 18 | |
| 19 | reg = pt.application.key_bindings_registry |
| 20 | try: bind = reg.add_binding |
| 21 | except AttributeError: |
| 22 | bind = PTK.key_binding.bindings.utils.create_handle_decorator(reg) |
| 23 | |
| 24 | def inhibit_history_search(buf, fn): |
| 25 | searchp, searchtext = \ |
| 26 | buf.enable_history_search, buf.history_search_text |
| 27 | buf.enable_history_search = F.Never() |
| 28 | try: |
| 29 | fn() |
| 30 | finally: |
| 31 | buf.enable_history_search, buf.history_search_text = \ |
| 32 | searchp, searchtext |
| 33 | @bind(K.ControlP) |
| 34 | def prev_line(ev): |
| 35 | buf = ev.current_buffer |
| 36 | if buf.document.cursor_position_row > 0: |
| 37 | buf.cursor_up() |
| 38 | elif not buf.selection_state: |
| 39 | inhibit_history_search(buf, lambda: buf.history_backward()) |
| 40 | @bind(K.ControlN) |
| 41 | def next_line(ev): |
| 42 | buf = ev.current_buffer |
| 43 | if buf.document.cursor_position_row < buf.document.line_count - 1: |
| 44 | buf.cursor_down() |
| 45 | elif not buf.selection_state: |
| 46 | inhibit_history_search(buf, lambda: buf.history_forward()) |
| 47 | |
| 48 | bind(K.Escape, u'p')(lambda ev: ev.current_buffer.history_backward()) |
| 49 | bind(K.Escape, u'n')(lambda ev: ev.current_buffer.history_forward()) |
| 50 | |
| 51 | __mdw_hack_bindings() |
| 52 | del __mdw_hack_bindings |