about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-10-13 23:15:59 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-10-13 23:15:59 -0700
commit9a183b817903c39fc33d38d73bf506ced3e5553e (patch)
treebfa090e6815c1963dc1583397ee68349fa6b571c
parentdb0363462f42b05561853bd295fb4d39909a9f6c (diff)
downloadmu-9a183b817903c39fc33d38d73bf506ced3e5553e.tar.gz
support backspace when reading line from keyboard
-rw-r--r--115write-byte.subx25
-rw-r--r--400.mu1
-rw-r--r--516read-line.mu13
3 files changed, 38 insertions, 1 deletions
diff --git a/115write-byte.subx b/115write-byte.subx
index 67516731..0df1b85e 100644
--- a/115write-byte.subx
+++ b/115write-byte.subx
@@ -76,4 +76,29 @@ test-append-byte-single:
     # . end
     c3/return
 
+undo-append-byte:  # f: (addr stream byte)
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # . save registers
+    50/push-eax
+    # eax = f
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 # copy *(ebp+8) to eax
+    # if (f->write <= 0) abort
+    81          7/subop/compare     0/mod/indirect  0/rm32/eax    .           .             .           .           .               0/imm32           # compare *eax
+    7e/jump-if-<=  $undo-append-byte:abort/disp8
+    # --f->write
+    ff          1/subop/decrement   0/mod/indirect  0/rm32/eax    .           .             .           .           .               .                 # decrement *eax
+$undo-append-byte:end:
+    # . restore registers
+    58/pop-to-eax
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
+$undo-append-byte:abort:
+    (abort "undo-append-byte: empty stream")
+    # never gets here
+
 # . . vim:nowrap:textwidth=0
diff --git a/400.mu b/400.mu
index 539093b8..9baad977 100644
--- a/400.mu
+++ b/400.mu
@@ -65,6 +65,7 @@ sig write-stream-immutable f: (addr stream byte), s: (addr stream byte)
 sig read-byte s: (addr stream byte) -> _/eax: byte
 sig peek-byte s: (addr stream byte) -> _/eax: byte
 sig append-byte f: (addr stream byte), n: int  # really just a byte, but I want to pass in literal numbers
+sig undo-append-byte f: (addr stream byte)  # take most recent append back out
 #sig to-hex-char in/eax: int -> out/eax: int
 sig append-byte-hex f: (addr stream byte), n: int  # really just a byte, but I want to pass in literal numbers
 sig write-int32-hex f: (addr stream byte), n: int
diff --git a/516read-line.mu b/516read-line.mu
index 1bb79c5a..5c96a832 100644
--- a/516read-line.mu
+++ b/516read-line.mu
@@ -2,13 +2,24 @@
 # abort on stream overflow
 fn read-line-from-keyboard keyboard: (addr keyboard), out: (addr stream byte), screen: (addr screen), fg: int, bg: int {
   clear-stream out
-  {
+  $read-line-from-keyboard:loop: {
     draw-cursor screen, 0x20/space
     var key/eax: byte <- read-key keyboard
     compare key, 0xa/newline
     break-if-=
     compare key, 0
     loop-if-=
+    compare key, 8/backspace
+    {
+      break-if-!=
+      undo-append-byte out
+      draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg 0/bg  # clear cursor
+      move-cursor-left screen
+      move-cursor-left screen
+      draw-code-point-at-cursor-over-full-screen screen, 0x20/space, fg 0/bg  # clear old cursor
+      move-cursor-left screen
+      loop $read-line-from-keyboard:loop
+    }
     var key2/eax: int <- copy key
     append-byte out, key2
     var c/eax: code-point <- copy key2