A read coroutine reads terminal input one character at a time, echoes accepted characters, handles deletion, and returns the completed line when the user presses Enter. section 8.4.1
Its input loop coordinates four operations:
- Awaits one byte from a stream reader. section 8.4.1
- Appends ordinary characters to an internal buffer and echoes them to standard output. section 8.4.1
- Removes the last buffered character and erases its displayed form when Delete is pressed. section 8.4.1
- Clears the input line and returns the buffer after Enter terminates input. section 8.4.1
Listing 8.8 Reading input one character at a time
import sys
from asyncio import StreamReader
from collections import deque
from chapter_08.listing_8_7 import move_back_one_char, clear_line
async def read_line(stdin_reader: StreamReader) -> str:
def erase_last_char(): #1
move_back_one_char()
sys.stdout.write(' ')
move_back_one_char()
delete_char = b'\x7f'
input_buffer = deque()
while (input_char := await stdin_reader.read(1)) != b'\n':
if input_char == delete_char: #2
if len(input_buffer) > 0:
input_buffer.pop()
erase_last_char()
sys.stdout.flush()
else:
input_buffer.append(input_char) #3
sys.stdout.write(input_char.decode())
sys.stdout.flush()
clear_line()
return b''.join(input_buffer).decode()
Inspect the implementation of character reads, deletion handling, output erasure, and input buffering. section 8.4.1
