chiark / gitweb /
dot/ipython-key-bindings.py: Hack IPython's bogus keybindings.
[profile] / dot / ipython-key-bindings.py
diff --git a/dot/ipython-key-bindings.py b/dot/ipython-key-bindings.py
new file mode 100644 (file)
index 0000000..3f392fe
--- /dev/null
@@ -0,0 +1,43 @@
+### -*-python -*-
+
+import IPython as IPY
+import prompt_toolkit as PTK
+
+def ding():
+  with open('/dev/tty', 'w') as f: f.write('\a')
+
+## Key bindings.  Alas, IPython's attempt at Emacs keybindings is abysmal.
+K = PTK.keys.Keys
+F = PTK.filters
+BUF = PTK.enums.DEFAULT_BUFFER
+ipy = IPY.get_ipython()
+try: pt = ipy.pt_cli
+except AttributeError: pass
+else:
+  reg = pt.application.key_bindings_registry
+  bind = PTK.key_binding.bindings.utils.create_handle_decorator(reg)
+
+  def inhibit_history_search(buf, fn):
+    searchp, searchtext = buf.enable_history_search, buf.history_search_text
+    buf.enable_history_search = F.Never()
+    try:
+      fn()
+    finally:
+      buf.enable_history_search, buf.history_search_text = searchp, searchtext
+  @bind(K.ControlP)
+  def prev_line(ev):
+    buf = ev.current_buffer
+    if buf.document.cursor_position_row > 0:
+      buf.cursor_up()
+    elif not buf.selection_state:
+      inhibit_history_search(buf, lambda: buf.history_backward())
+  @bind(K.ControlN)
+  def next_line(ev):
+    buf = ev.current_buffer
+    if buf.document.cursor_position_row < buf.document.line_count - 1:
+      buf.cursor_down()
+    elif not buf.selection_state:
+      inhibit_history_search(buf, lambda: buf.history_forward())
+
+  bind(K.Escape, u'p')(lambda ev: ev.current_buffer.history_backward())
+  bind(K.Escape, u'n')(lambda ev: ev.current_buffer.history_forward())