Input¶
Input
objects provide user keypress events
and other control events.
Input - Example¶
>>> from curtsies import Input
>>> with Input(keynames='curtsies') as input_generator:
... for e in Input():
... if e in (u'<ESC>', u'<Ctrl-d>'):
... break
... else:
... print(e)
Input - Getting Keyboard Events¶
The simplest way to use an Input
object is to
iterate over it in a for loop:
each time a keypress is detected or other event occurs, an event is produced
and can be acted upon.
Since it’s iterable, next()
can be used to wait for a single event.
send()
works like next()
but takes a timeout
in seconds, which if reached will cause None to be returned signalling
that no keypress or other event occured within the timeout.
Key events are unicode strings, but sometimes event objects
(see Event
) are returned instead.
Built-in events signal SigIntEvent
events from the OS and PasteEvent
consisting
of multiple keypress events if reporting of these types of events was enabled
in instantiation of the Input
object.
Input - Using as a Reactor¶
Custom events can also be scheduled to be returned from
Input
with callback functions
created by the event trigger methods.
Each of these methods returns a callback that will schedule an instance of the desired event type:
- Using a callback created by
event_trigger()
schedules an event to be returned the next time an event is requested, but not if an event has already been requested (if called from another thread). threadsafe_event_trigger()
does the same, but may notify a concurrent request for an event so that the custom event is immediately returned.scheduled_event_trigger()
schedules an event to be returned at some point in the future.
Input - Context¶
next()
and send()
must be used within the context of that Input
object.
Within the (context-manager) context of an Input generator, an in-stream
is put in raw mode or cbreak mode, and keypresses are stored to be reported
later. Original tty attributes are recorded to be restored on exiting
the context. The SigInt signal handler may be replaced if this behavior was
specified on creation of the Input
object.
Input - Notes¶
Input
takes an optional argument keynames
for how to name
keypress events, which is 'curtsies'
by default.
For compatibility with curses code, you can use 'curses'
names,
but note that curses doesn’t have nice key names for many key combinations
so you’ll be putting up with names like u'\xe1'
for
option-j
and '\x86'
for ctrl-option-f
.
Pass 'plain'
for this parameter to return a simple unicode representation.
PasteEvent
objects representing multiple
keystrokes in very rapid succession
(typically because the user pasted in text, but possibly because they typed
two keys simultaneously). How many bytes must occur together to trigger such
an event is customizable via the paste_threshold
argument to the Input
object - by default it’s one greater than the maximum possible keypress
length in bytes.
If sigint_event=True
is passed to Input
, SIGINT
signals from the
operating system (which usually raise a KeyboardInterrupt
exception)
will be returned as SigIntEvent
instances.
To set a timeout on the blocking get, treat it like a generator and call
.send(timeout)
. The call will return None
if no event is available.
Input - Events¶
To see what a given keypress is called (what unicode string is returned
by Terminal.next()
), try
python -m curtsies.events
and play around.
Events returned by Input
fall into two categories:
instances of subclasses of Event
and
Keypress strings.
Input - Event Objects¶
-
class
curtsies.events.
Event
¶
-
class
curtsies.events.
SigIntEvent
¶ Event signifying a SIGINT
-
class
curtsies.events.
PasteEvent
¶ Multiple keypress events combined, likely from copy/paste.
The events attribute contains a list of keypress event strings.
-
class
curtsies.events.
ScheduledEvent
(when)¶ Event scheduled for a future time.
Parameters: when (float) – unix time in seconds for which this event is scheduled Custom events that occur at a specific time in the future should be subclassed from ScheduledEvent.
Input - Keypress Strings¶
Keypress events are Unicode strings in both Python 2 and 3 like:
a, 4, *, ?
<UP>, <DOWN>, <RIGHT>, <LEFT>
<SPACE>, <TAB>, <F1>, <F12>
<BACKSPACE>, <HOME>, <PADENTER>, <PADDELETE>
<Ctrl+a>, <Ctrl+SPACE>
A, <Shift-TAB>, ?
<Esc+a>, <Esc+A>, <Esc+Ctrl-A>
<Esc+Ctrl+A>
<Meta-J>, <Meta-Ctrl-J>
(this is old-style meta)
Likely points of confusion for keypress strings:
- Enter is
<Ctrl-j>
- Modern meta (the escape-prepending version) key is
<Esc+a>
while control and shift keys are<Ctrl-a>
(note the + vs -) - Letter keys are capitalized in
<Esc+Ctrl-A>
while they are lowercase in<Ctrl-a>
(this should be fixed in the next api-breaking release) - Some special characters lose their special names when used with modifier keys, for example:
<TAB>, <Shift-TAB>, <Esc+Ctrl-Y>, <Esc+Ctrl-I>
are all produced by the tab key, whiley, Y, <Shift-TAB>, <Esc+y>, <Esc+Y>, <Esc+Ctrl-y>, <Esc+Ctrl-Y>, <Ctrl-Y>
are all produced by the y key. (This should really be figured out)
Input - API docs¶
-
class
curtsies.
Input
(in_stream=None, keynames='curtsies', paste_threshold=8, sigint_event=False, signint_callback_provider=None)¶ Keypress and control event generator
Returns an Input instance.
Parameters: - in_stream (file) – Defaults to sys.__stdin__
- keynames (string) – How keypresses should be named - one of ‘curtsies’, ‘curses’, or ‘plain’.
- paste_threshold (int) – How many bytes must be read in one os.read on the in_stream to trigger the keypresses they represent to be combined into a single paste event
- sigint_event (bool) – Whether SIGINT signals from the OS should be intercepted and returned as SigIntEvent objects
-
unget_bytes
(string)¶ Adds bytes to be internal buffer to be read
This method is for reporting bytes from an in_stream read not initiated by this Input object
-
send
(timeout=None)¶ Returns an event or None if no events occur before timeout.
-
event_trigger
(event_type)¶ Returns a callback that creates events.
Returned callback function will add an event of type event_type to a queue which will be checked the next time an event is requested.
-
scheduled_event_trigger
(event_type)¶ Returns a callback that schedules events for the future.
Returned callback function will add an event of type event_type to a queue which will be checked the next time an event is requested.
-
threadsafe_event_trigger
(event_type)¶ Returns a callback to creates events, interrupting current event requests.
Returned callback function will create an event of type event_type which will interrupt an event request if one is concurrently occuring, otherwise adding the event to a queue that will be checked on the next event request.