Skip to content

Commit 10c9281

Browse files
pi-anldpgeorge
authored andcommitted
aiorepl: Add cursor left/right support.
Allows modifying current line, adding/deleting characters in the middle etc. Includes home/end keys to move to start/end of current line. Signed-off-by: Andrew Leech <[email protected]>
1 parent d41851c commit 10c9281

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

micropython/aiorepl/aiorepl.py

+42-5
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ async def task(g=None, prompt="--> "):
111111
sys.stdout.write(prompt)
112112
cmd: str = ""
113113
paste = False
114+
curs = 0 # cursor offset from end of cmd buffer
114115
while True:
115116
b = await s.read(1)
116117
pc = c # save previous character
@@ -129,6 +130,10 @@ async def task(g=None, prompt="--> "):
129130
# conversion, so ignore this linefeed.
130131
if pc == 0x0A and time.ticks_diff(t, pt) < 20:
131132
continue
133+
if curs:
134+
# move cursor to end of the line
135+
sys.stdout.write("\x1B[{}C".format(curs))
136+
curs = 0
132137
sys.stdout.write("\n")
133138
if cmd:
134139
# Push current command.
@@ -145,8 +150,16 @@ async def task(g=None, prompt="--> "):
145150
elif c == 0x08 or c == 0x7F:
146151
# Backspace.
147152
if cmd:
148-
cmd = cmd[:-1]
149-
sys.stdout.write("\x08 \x08")
153+
if curs:
154+
cmd = "".join((cmd[: -curs - 1], cmd[-curs:]))
155+
sys.stdout.write(
156+
"\x08\x1B[K"
157+
) # move cursor back, erase to end of line
158+
sys.stdout.write(cmd[-curs:]) # redraw line
159+
sys.stdout.write("\x1B[{}D".format(curs)) # reset cursor location
160+
else:
161+
cmd = cmd[:-1]
162+
sys.stdout.write("\x08 \x08")
150163
elif c == CHAR_CTRL_B:
151164
continue
152165
elif c == CHAR_CTRL_C:
@@ -178,7 +191,7 @@ async def task(g=None, prompt="--> "):
178191
elif c == 0x1B:
179192
# Start of escape sequence.
180193
key = await s.read(2)
181-
if key in ("[A", "[B"):
194+
if key in ("[A", "[B"): # up, down
182195
# Stash the current command.
183196
hist[(hist_i - hist_b) % _HISTORY_LIMIT] = cmd
184197
# Clear current command.
@@ -194,12 +207,36 @@ async def task(g=None, prompt="--> "):
194207
# Update current command.
195208
cmd = hist[(hist_i - hist_b) % _HISTORY_LIMIT]
196209
sys.stdout.write(cmd)
210+
elif key == "[D": # left
211+
if curs < len(cmd) - 1:
212+
curs += 1
213+
sys.stdout.write("\x1B")
214+
sys.stdout.write(key)
215+
elif key == "[C": # right
216+
if curs:
217+
curs -= 1
218+
sys.stdout.write("\x1B")
219+
sys.stdout.write(key)
220+
elif key == "[H": # home
221+
pcurs = curs
222+
curs = len(cmd)
223+
sys.stdout.write("\x1B[{}D".format(curs - pcurs)) # move cursor left
224+
elif key == "[F": # end
225+
pcurs = curs
226+
curs = 0
227+
sys.stdout.write("\x1B[{}C".format(pcurs)) # move cursor right
197228
else:
198229
# sys.stdout.write("\\x")
199230
# sys.stdout.write(hex(c))
200231
pass
201232
else:
202-
sys.stdout.write(b)
203-
cmd += b
233+
if curs:
234+
# inserting into middle of line
235+
cmd = "".join((cmd[:-curs], b, cmd[-curs:]))
236+
sys.stdout.write(cmd[-curs - 1 :]) # redraw line to end
237+
sys.stdout.write("\x1B[{}D".format(curs)) # reset cursor location
238+
else:
239+
sys.stdout.write(b)
240+
cmd += b
204241
finally:
205242
micropython.kbd_intr(3)

0 commit comments

Comments
 (0)