https://github.com/akkartik/mu/blob/main/516read-line.mu
 1 # read line from keyboard into stream while also echoing to screen
 2 # abort on stream overflow
 3 fn read-line-from-keyboard keyboard: (addr keyboard), out: (addr stream byte), screen: (addr screen), fg: int, bg: int {
 4   clear-stream out
 5   $read-line-from-keyboard:loop: {
 6     draw-cursor screen, 0x20/space
 7     var key/eax: byte <- read-key keyboard
 8     compare key, 0xa/newline
 9     break-if-=
10     compare key, 0
11     loop-if-=
12     compare key, 8/backspace
13     {
14       break-if-!=
15       undo-append-byte out
16       draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg 0/bg  # clear cursor
17       move-cursor-left screen
18       move-cursor-left screen
19       draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg 0/bg  # clear old cursor
20       move-cursor-left screen
21       loop $read-line-from-keyboard:loop
22     }
23     var key2/eax: int <- copy key
24     append-byte out, key2
25     var c/eax: code-point <- copy key2
26     draw-code-point-at-cursor-over-full-screen screen, c, fg bg
27     loop
28   }
29   # clear cursor
30   draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg bg
31 }