petereon / beaupy

A Python library of interactive CLI elements you have been looking for
https://petereon.github.io/beaupy/
MIT License
181 stars 13 forks source link

Use "ESC" key as abort #50

Closed juxeii closed 1 year ago

juxeii commented 1 year ago

In my use case it would be great if I could detect that the user has pressed ESCin select_multiple. Is this somehow possible?

petereon commented 1 year ago

I have just checked and ESC is accepted as an abort functionality in select_multiple on my Mac.

For keypress handling beaupy uses python_yakh under the hood which tries to abstract the platform layer as much as possible but I am sure there are some hiccups still.

Could you please elaborate in terms of your platform and terminal emulator?

Further, if you wouldn't mind testing this for me, you could run this script and press ESC while it's running and post the resulting prints here.

from yakh import get_key

key = get_key()
print(key.key_codes)
print(bytes(key.key, 'utf-8'))
print(key.is_printable)

yakh is a dependency of beaupy so as long as you run this in the same virtual env you run beaupy in, it should work.

juxeii commented 1 year ago

I am on 08:20 $ cat /etc/os-release

NAME="Red Hat Enterprise Linux Server"
VERSION="7.9 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="7.9"
PRETTY_NAME="Red Hat Enterprise Linux Server 7.9 (Maipo)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.9:GA:server"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.9
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.9"

Running your snippets yields

(snaputils-i_jQa2nS-py3.9) ✔ .../coredev [main ↑·1|✚ 7⚑ 22] 
08:22 $ /home/user/.cache/pypoetry/virtualenvs/snaputils-i_jQa2nS-py3.9/bin/python /test/playground.py
(27,)
b'\x1b'
False

I need do distinguish between ENTERand ESC, which both yield no selection on my side. But "Enter" should mean no selection and ESCshould mean abort all together.

petereon commented 1 year ago

I see, would raising a KeyboardInterrupt on escape and handling it yourself be a good alternative?

If so, you could edit the global Config object, setting .raise_on_interrupt to True and additonally DefaultKeys object setting .escape to [] and appending Keys.ESC into .interrupt attribute.

Just for my reference, what exact behavior would you envision for ESC key? Should it raise some class of Exception?

juxeii commented 1 year ago

I am not a big fan of exceptions. Returning the last key pressed(as tuple element to the already existing return values) would be the most flexible I guess.

So I did

elif keypress in DefaultKeys.escape:
            if Config.raise_on_interrupt:
                raise KeyboardInterrupt()

which is OK for me. Is it also OK for you? Possible to release a patch version? I really think that ENTERand ESCshould have different semantics when the user selects nothing.

petereon commented 1 year ago

So I agree that ENTER and ESC might benefit from different semantics, but I don't want to be releasing breaking changes, so having the functions return tuples is not viable for me.

I would say my best option is actually going for a second config option which controls whether to raise an Exception on ESC key, defaulting to current behavior of not raising on ESC.

Coming from languages that have proper way to deal with nothingness I appreciate that exceptions are suboptiomal, but they are canonical in Python.

juxeii commented 1 year ago

Good point on breaking changes. You proposal sounds reasonable and it would be great if you could release this patch soon. Hope you have simple deploy scripts ;)

petereon commented 1 year ago

I should be able to get it out today, just much later, I am at work atm :sweat_smile:

juxeii commented 1 year ago

Me2 :) Thx for you prompt effort. I will close this issue.

petereon commented 1 year ago

Published: https://github.com/petereon/beaupy/releases/tag/v3.4.0

Should be on PyPI in few minutes.

juxeii commented 1 year ago

Works like a charm! Many thanks and keep up the good work :blush: