Skip to content

fix(prompt): Keep original key_bindings in prompt-toolkit shell to easy add new key bindings during session#6093

Merged
anki-code merged 2 commits into
mainfrom
ptk_key_bindings
Mar 5, 2026
Merged

fix(prompt): Keep original key_bindings in prompt-toolkit shell to easy add new key bindings during session#6093
anki-code merged 2 commits into
mainfrom
ptk_key_bindings

Conversation

@anki-code

@anki-code anki-code commented Feb 5, 2026

Copy link
Copy Markdown
Member

Motivation

Reduce complexity on managing key bindins during session.

Before

We want to add Ctrl+F hotkey during session and our first thought is about doing same as binding approach in on_ptk_create event.

__xonsh__.shell.shell
# <xonsh.shells.ptk_shell.PromptToolkitShell>
__xonsh__.shell.shell.key_bindings
# <prompt_toolkit.key_binding.key_bindings._MergedKeyBindings>

@__xonsh__.shell.shell.key_bindings.add("c-f")
def _my_ctrl_f(event):
    pass
# AttributeError: '_MergedKeyBindings' object has no attribute 'add'
# Yes, because key_bindings are inside MergedKeyBindings

So we need to patch deeper and it's working:

current_bindings = __xonsh__.shell.shell.key_bindings.registries[0]
@current_bindings.add("c-f")
def _my_ctrl_f(event):
    if not str(event.current_buffer.text):
        (buf := event.current_buffer).insert_text('echo F')
        buf.validate_and_handle()

# Ctrl+F
# echo F
# F

After

Very close approach to using on_ptk_create event:

__xonsh__.shell.shell.key_bindings
# <prompt_toolkit.key_binding.key_bindings.KeyBindings>


@__xonsh__.shell.shell.key_bindings.add("c-f")
def _my_ctrl_f(event):
    if not str(event.current_buffer.text):
        (buf := event.current_buffer).insert_text('echo F')
        buf.validate_and_handle()

# Ctrl+F
# echo F
# F

Implementation

I have feeling that we need here more eyes and mamanging merged key bindings more carefully and may be provide more clean API to add incude-exclude things like load_emacs_shift_selection_bindings. But we have no user issues around this and current PR looks the shortest way to rid of deep patching on user side.

For community

⬇️ Please click the 👍 reaction instead of leaving a +1 or 👍 comment

@anki-code

Copy link
Copy Markdown
Member Author

I'm going to self-merge this to have it in fix release. In case of issues we can revert because it's a few lines change.

@anki-code anki-code merged commit e9b0aea into main Mar 5, 2026
15 checks passed
anki-code pushed a commit that referenced this pull request Mar 5, 2026
🤖 I have created a release *beep* *boop*
---


## [0.22.5](0.22.4...0.22.5)
(2026-03-05)


### Features

* Added useful command decorators: `[@lines](https://github.com/lines)`,
`[@JSON](https://github.com/json)`,
`[@jsonl](https://github.com/jsonl)`, `[@yaml](https://github.com/yaml)`
([#6114](#6114))
([0f7124e](0f7124e))


### Bug Fixes

* **completion:** Fix os.path.commonprefix deprecation warning in
python3.15 ([#6102](#6102))
([2b5b2bb](2b5b2bb))
* Increase `@$()` stability and now it is also working in case of
`$THREAD_SUBPROCS=False`
([#6112](#6112))
([a3ac036](a3ac036))
* **predictor:** Fix predict_threadable to properly handle symlinks,
especially on NixOS
([#6115](#6115))
([bc01b04](bc01b04))
* **prompt:** Keep original key_bindings in prompt-toolkit shell to easy
add new key bindings during session
([#6093](#6093))
([e9b0aea](e9b0aea))
* replace 12 bare except clauses with except Exception
([#6110](#6110))
([54b311c](54b311c))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: xonsh-credentials-bot[bot] <97968350+xonsh-credentials-bot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant