2

In my shell (zsh) or in python, I can go backward through command history by pressing PageDown, and I can go forward by pressing PageUp.

But in ipython, these shortcuts are reversed.

Where are these shortcuts defined for ipython, and how can I reverse them back, so that

PageDown goes back in history, and PageUp goes forward in history?

I am using ipython3 version 5.8.0 on Debian 10.

Darkonaut
  • 20,186
  • 7
  • 54
  • 65
400 the Cat
  • 266
  • 3
  • 23

2 Answers2

1

In IPython version 5.x, this is mentioned in the documentation: Specific config details — IPython 5.11.0.dev documentation

To get the function to bind to, see key_binding/bindings/basic.py: The default is

handle("pageup", filter=~has_selection)(get_by_name("previous-history"))
handle("pagedown", filter=~has_selection)(get_by_name("next-history"))

So, put this code in a startup file:

from IPython import get_ipython
from prompt_toolkit.filters import HasSelection
from prompt_toolkit.keys import Keys
from prompt_toolkit.key_binding.bindings.named_commands import get_by_name

registry = get_ipython().pt_cli.application.key_bindings_registry
registry.add_binding(Keys.PageUp, filter=~HasSelection())(get_by_name("next-history"))
registry.add_binding(Keys.PageDown, filter=~HasSelection())(get_by_name("previous-history"))

On newer IPython versions (such as 7.19.0) replace the registry = ... line with

registry = get_ipython().pt_app.key_bindings

Reference: Specific config details — IPython 7.19.0 documentation

user202729
  • 3,358
  • 3
  • 25
  • 36
  • Possibly related: [1](https://stackoverflow.com/questions/38443907/how-does-one-set-specific-vim-bindings-in-ipython-5-0-0) [2](https://stackoverflow.com/questions/30014267/custom-keybindings-for-ipython-terminal) [3](https://stackoverflow.com/questions/42828946/is-there-any-way-to-replace-the-exists-default-key-bindings-in-ipython-vi-mode) [4](https://stackoverflow.com/questions/21793051/ipython-does-not-read-inputrc) [5](https://stackoverflow.com/questions/38659721/ipython-5-0-and-key-bindings-in-console) – user202729 Jan 31 '21 at 17:18
  • I get this error: `AttributeError: 'TerminalInteractiveShell' object has no attribute 'pt_app'` – 400 the Cat Feb 01 '21 at 02:35
1

Create script in ~/.ipython/profile_default/startup directory with any name ending with extension .py or .ipy

For example i created history_keybindings.py and put it inside ~/.ipython/profile_default/startup directory

from IPython import get_ipython
from IPython.terminal.shortcuts import previous_history_or_previous_completion, next_history_or_next_completion
from prompt_toolkit.keys import Keys
from prompt_toolkit.filters import HasSelection

ip = get_ipython()

registry = None

if (getattr(ip, 'pt_app', None)):
   # for IPython versions 7.x
   registry = ip.pt_app.key_bindings
elif (getattr(ip, 'pt_cli', None)):
   # for IPython versions 5.x
   registry = ip.pt_cli.application.key_bindings_registry

if registry:
   registry.add_binding(Keys.PageUp, filter=(~HasSelection()))(previous_history_or_previous_completion)
   registry.add_binding(Keys.PageDown, filter=(~HasSelection()))(next_history_or_next_completion)

Note: For more info check here

Chandan
  • 11,465
  • 1
  • 6
  • 25