Skip to content

aiorepl: Fix Enter key handling in raw terminal mode #1016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions micropython/aiorepl/aiorepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,26 @@ async def task(g=None, prompt="--> "):
pt = t # save previous time
t = time.ticks_ms()
if c < 0x20 or c > 0x7E:
if c == 0x0A:
# LF
if c == 0x0A or c == 0x0D:
# LF or CR (handle both for raw terminal mode compatibility)
if paste:
# In paste mode, preserve the actual character
sys.stdout.write(b)
cmd += b
continue
# If the previous character was also LF, and was less
# than 20 ms ago, this was likely due to CRLF->LFLF
# conversion, so ignore this linefeed.
if pc == 0x0A and time.ticks_diff(t, pt) < 20:
# Handle various newline sequences to avoid double-execution:
# - CR+LF (Windows style): ignore LF if it follows CR quickly
# - LF+LF (PTY double-newline): ignore second LF if it follows quickly
# - CR+CR (potential double-CR): ignore second CR if it follows quickly
if (
(c == 0x0A and pc == 0x0D) # LF after CR (CRLF)
or (c == 0x0A and pc == 0x0A) # LF after LF (double LF)
or (c == 0x0D and pc == 0x0D)
) and time.ticks_diff(t, pt) < 20: # CR after CR
continue
if curs:
# move cursor to end of the line
sys.stdout.write("\x1B[{}C".format(curs))
sys.stdout.write("\x1b[{}C".format(curs))
curs = 0
sys.stdout.write("\n")
if cmd:
Expand All @@ -153,10 +159,10 @@ async def task(g=None, prompt="--> "):
if curs:
cmd = "".join((cmd[: -curs - 1], cmd[-curs:]))
sys.stdout.write(
"\x08\x1B[K"
"\x08\x1b[K"
) # move cursor back, erase to end of line
sys.stdout.write(cmd[-curs:]) # redraw line
sys.stdout.write("\x1B[{}D".format(curs)) # reset cursor location
sys.stdout.write("\x1b[{}D".format(curs)) # reset cursor location
else:
cmd = cmd[:-1]
sys.stdout.write("\x08 \x08")
Expand Down Expand Up @@ -207,21 +213,21 @@ async def task(g=None, prompt="--> "):
elif key == "[D": # left
if curs < len(cmd) - 1:
curs += 1
sys.stdout.write("\x1B")
sys.stdout.write("\x1b")
sys.stdout.write(key)
elif key == "[C": # right
if curs:
curs -= 1
sys.stdout.write("\x1B")
sys.stdout.write("\x1b")
sys.stdout.write(key)
elif key == "[H": # home
pcurs = curs
curs = len(cmd)
sys.stdout.write("\x1B[{}D".format(curs - pcurs)) # move cursor left
sys.stdout.write("\x1b[{}D".format(curs - pcurs)) # move cursor left
elif key == "[F": # end
pcurs = curs
curs = 0
sys.stdout.write("\x1B[{}C".format(pcurs)) # move cursor right
sys.stdout.write("\x1b[{}C".format(pcurs)) # move cursor right
else:
# sys.stdout.write("\\x")
# sys.stdout.write(hex(c))
Expand All @@ -231,7 +237,7 @@ async def task(g=None, prompt="--> "):
# inserting into middle of line
cmd = "".join((cmd[:-curs], b, cmd[-curs:]))
sys.stdout.write(cmd[-curs - 1 :]) # redraw line to end
sys.stdout.write("\x1B[{}D".format(curs)) # reset cursor location
sys.stdout.write("\x1b[{}D".format(curs)) # reset cursor location
else:
sys.stdout.write(b)
cmd += b
Expand Down
Loading