diff --git a/IPython/terminal/interactiveshell.py b/IPython/terminal/interactiveshell.py index d14d5ea..22dc8c2 100644 --- a/IPython/terminal/interactiveshell.py +++ b/IPython/terminal/interactiveshell.py @@ -482,7 +482,10 @@ class TerminalInteractiveShell(InteractiveShell): @observe("shortcuts") def _shortcuts_changed(self, change): - user_shortcuts = change.new + if self.pt_app: + self.pt_app.key_bindings = self._merge_shortcuts(user_shortcuts=change.new) + + def _merge_shortcuts(self, user_shortcuts): # rebuild the bindings list from scratch key_bindings = create_ipython_shortcuts(self) @@ -568,7 +571,8 @@ class TerminalInteractiveShell(InteractiveShell): key_bindings = create_ipython_shortcuts(self, skip=shortcuts_to_skip) for binding in shortcuts_to_add: add_binding(key_bindings, binding) - self.pt_app.key_bindings = key_bindings + + return key_bindings prompt_includes_vi_mode = Bool(True, help="Display the current vi mode (when using vi editing mode)." @@ -607,8 +611,7 @@ class TerminalInteractiveShell(InteractiveShell): return # Set up keyboard shortcuts - key_bindings = create_ipython_shortcuts(self) - + key_bindings = self._merge_shortcuts(user_shortcuts=self.shortcuts) # Pre-populate history from IPython's history database history = PtkHistoryAdapter(self) diff --git a/IPython/terminal/tests/test_shortcuts.py b/IPython/terminal/tests/test_shortcuts.py index a754ecf..ceab176 100644 --- a/IPython/terminal/tests/test_shortcuts.py +++ b/IPython/terminal/tests/test_shortcuts.py @@ -388,17 +388,19 @@ def test_modify_shortcut_with_filters(ipython_with_prompt): assert matched_keys == {")", "]", "}", "x", '"'} -def test_command(): +def example_command(): pass def test_add_shortcut_for_new_command(ipython_with_prompt): - matched = find_bindings_by_command(test_command) + matched = find_bindings_by_command(example_command) assert len(matched) == 0 - with pytest.raises(ValueError, match="test_command is not a known"): - ipython_with_prompt.shortcuts = [{"command": "test_command", "new_keys": ["x"]}] - matched = find_bindings_by_command(test_command) + with pytest.raises(ValueError, match="example_command is not a known"): + ipython_with_prompt.shortcuts = [ + {"command": "example_command", "new_keys": ["x"]} + ] + matched = find_bindings_by_command(example_command) assert len(matched) == 0 @@ -420,3 +422,13 @@ def test_add_shortcut_for_existing_command(ipython_with_prompt): ipython_with_prompt.shortcuts = [] matched = find_bindings_by_command(skip_over) assert len(matched) == 5 + + +def test_setting_shortcuts_before_pt_app_init(): + ipython = get_ipython() + assert ipython.pt_app is None + shortcuts = [ + {"command": "IPython:auto_match.skip_over", "new_keys": ["x"], "create": True} + ] + ipython.shortcuts = shortcuts + assert ipython.shortcuts == shortcuts