about summary refs log tree commit diff stats
path: root/baremetal/shell
diff options
context:
space:
mode:
Diffstat (limited to 'baremetal/shell')
-rw-r--r--baremetal/shell/gap-buffer.mu7
-rw-r--r--baremetal/shell/sandbox.mu115
-rw-r--r--baremetal/shell/trace.mu30
3 files changed, 140 insertions, 12 deletions
diff --git a/baremetal/shell/gap-buffer.mu b/baremetal/shell/gap-buffer.mu
index 6e5d7f6d..5b6591db 100644
--- a/baremetal/shell/gap-buffer.mu
+++ b/baremetal/shell/gap-buffer.mu
@@ -750,3 +750,10 @@ fn skip-whitespace-from-gap-buffer self: (addr gap-buffer) {
   g <- read-from-gap-buffer self
   loop
 }
+
+fn edit-gap-buffer self: (addr gap-buffer), key: grapheme {
+}
+
+fn cursor-on-final-line? self: (addr gap-buffer) -> _/eax: boolean {
+  return 1/true
+}
diff --git a/baremetal/shell/sandbox.mu b/baremetal/shell/sandbox.mu
index 08b76c3a..d7fed376 100644
--- a/baremetal/shell/sandbox.mu
+++ b/baremetal/shell/sandbox.mu
@@ -2,6 +2,7 @@ type sandbox {
   data: (handle gap-buffer)
   value: (handle stream byte)
   trace: (handle trace)
+  cursor-in-trace?: boolean
 }
 
 fn initialize-sandbox _self: (addr sandbox) {
@@ -58,13 +59,21 @@ fn render-sandbox screen: (addr screen), _self: (addr sandbox), _x: int, _y: int
   var data/edx: (addr gap-buffer) <- copy _data
   var x/eax: int <- copy _x
   var y/ecx: int <- copy _y
-  x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, 0x20/xmax, 0x20/ymax, x, y, 1/show-cursor
+  var cursor-in-sandbox?/ebx: boolean <- copy 0/false
+  {
+    var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
+    compare *cursor-in-trace?, 0/false
+    break-if-!=
+    cursor-in-sandbox? <- copy 1/true
+  }
+  x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, 0x20/xmax, 0x20/ymax, x, y, cursor-in-sandbox?
   y <- increment
   # trace
   var trace-ah/eax: (addr handle trace) <- get self, trace
   var _trace/eax: (addr trace) <- lookup *trace-ah
   var trace/edx: (addr trace) <- copy _trace
-  y <- render-trace screen, trace, _x, y, 0x20/xmax, 0x20/ymax
+  var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
+  y <- render-trace screen, trace, _x, y, 0x20/xmax, 0x20/ymax, *cursor-in-trace?
   # value
   var value-ah/eax: (addr handle stream byte) <- get self, value
   var _value/eax: (addr stream byte) <- lookup *value-ah
@@ -90,6 +99,7 @@ fn edit-sandbox _self: (addr sandbox), key: byte {
     delete-grapheme-before-cursor self
     return
   }
+  # running code
   {
     compare g, 0x12/ctrl-r
     break-if-!=
@@ -114,6 +124,41 @@ fn edit-sandbox _self: (addr sandbox), key: byte {
     run data, value, trace
     return
   }
+  # arrow keys
+  {
+    compare g, 0x4/ctrl-d
+    break-if-!=
+    # ctrl-d: cursor down (into trace if it makes sense)
+    var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
+    # if cursor in input, check if we need to switch to trace
+    {
+      compare *cursor-in-trace?, 0/false
+      break-if-!=
+      var data-ah/eax: (addr handle gap-buffer) <- get self, data
+      var data/eax: (addr gap-buffer) <- lookup *data-ah
+      var at-bottom?/eax: boolean <- cursor-on-final-line? data
+      compare at-bottom?, 0/false
+      break-if-=
+      var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
+      copy-to *cursor-in-trace?, 1/true
+      return
+    }
+    # if cursor in trace, send cursor to trace
+    {
+      compare cursor-in-trace?, 0/false
+      break-if-=
+      var trace-ah/eax: (addr handle trace) <- get self, trace
+      var trace/eax: (addr trace) <- lookup *trace-ah
+      edit-trace trace, g
+      return
+    }
+    # otherwise send cursor to input
+    var data-ah/eax: (addr handle gap-buffer) <- get self, data
+    var data/eax: (addr gap-buffer) <- lookup *data-ah
+    edit-gap-buffer data, g
+    return
+  }
+  # default: insert character
   add-grapheme-to-sandbox self, g
 }
 
@@ -130,3 +175,69 @@ fn run in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
   # TODO: eval
   print-cell read-result, out
 }
+
+fn test-run-integer {
+  var sandbox-storage: sandbox
+  var sandbox/esi: (addr sandbox) <- address sandbox-storage
+  initialize-sandbox sandbox
+  # type "1"
+  edit-sandbox sandbox, 0x31/1
+  # eval
+  edit-sandbox sandbox, 0x13/ctrl-s
+  # setup: screen
+  var screen-on-stack: screen
+  var screen/edi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 0xa, 4
+  #
+  render-sandbox screen, sandbox, 0/x, 0/y
+  check-screen-row screen, 0/y, "1    ", "F - test-run-integer/0"
+  check-screen-row screen, 1/y, "=> 1 ", "F - test-run-integer/1"
+}
+
+fn test-run-error-invalid-integer {
+  var sandbox-storage: sandbox
+  var sandbox/esi: (addr sandbox) <- address sandbox-storage
+  initialize-sandbox sandbox
+  # type "1a"
+  edit-sandbox sandbox, 0x31/1
+  edit-sandbox sandbox, 0x61/a
+  # eval
+  edit-sandbox sandbox, 0x13/ctrl-s
+  # setup: screen
+  var screen-on-stack: screen
+  var screen/edi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 0x10, 4
+  #
+  render-sandbox screen, sandbox, 0/x, 0/y
+  check-screen-row screen, 0/y, "1a             ", "F - test-run-error-invalid-integer/0"
+  check-screen-row screen, 1/y, "invalid number ", "F - test-run-error-invalid-integer/1"
+}
+
+fn test-run-move-cursor-into-trace {
+  var sandbox-storage: sandbox
+  var sandbox/esi: (addr sandbox) <- address sandbox-storage
+  initialize-sandbox sandbox
+  # type "1a"
+  edit-sandbox sandbox, 0x31/1
+  edit-sandbox sandbox, 0x61/a
+  # eval
+  edit-sandbox sandbox, 0x13/ctrl-s
+  # setup: screen
+  var screen-on-stack: screen
+  var screen/edi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 0x10, 4
+  #
+  render-sandbox screen, sandbox, 0/x, 0/y
+  check-screen-row screen,                                  0/y, "1a             ", "F - test-run-move-cursor-into-trace/pre-0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "  |            ", "F - test-run-move-cursor-into-trace/pre-0/cursor"
+  check-screen-row screen,                                  1/y, "invalid number ", "F - test-run-move-cursor-into-trace/pre-1"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "               ", "F - test-run-move-cursor-into-trace/pre-1/cursor"
+  # move cursor down
+  edit-sandbox sandbox, 4/ctrl-d
+  #
+  render-sandbox screen, sandbox, 0/x, 0/y
+  check-screen-row screen,                                  0/y, "1a             ", "F - test-run-move-cursor-into-trace/0"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "               ", "F - test-run-move-cursor-into-trace/0/cursor"
+  check-screen-row screen,                                  1/y, "invalid number ", "F - test-run-move-cursor-into-trace/1"
+  check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "|||||||||||||| ", "F - test-run-move-cursor-into-trace/1/cursor"
+}
diff --git a/baremetal/shell/trace.mu b/baremetal/shell/trace.mu
index 4c699a08..d3549f2a 100644
--- a/baremetal/shell/trace.mu
+++ b/baremetal/shell/trace.mu
@@ -2,8 +2,9 @@
 # An integral part of the Mu Shell is facilities for browsing traces.
 
 type trace {
-  curr-depth: int
+  curr-depth: int  # depth that will be assigned to next line appended
   data: (handle stream trace-line)
+  cursor-y: int  # row index on screen
 }
 
 type trace-line {
@@ -92,8 +93,14 @@ fn trace-higher _self: (addr trace) {
   decrement *depth
 }
 
-fn render-trace screen: (addr screen), _self: (addr trace), xmin: int, ymin: int, xmax: int, ymax: int -> _/ecx: int {
+fn render-trace screen: (addr screen), _self: (addr trace), xmin: int, ymin: int, xmax: int, ymax: int, show-cursor?: boolean -> _/ecx: int {
   var already-hiding-lines?/ebx: boolean <- copy 0/false
+  var bg/edi: int <- copy 0/black
+  compare show-cursor?, 0/false
+  {
+    break-if-=
+    bg <- copy 7/grey
+  }
   var y/ecx: int <- copy ymin
   var self/eax: (addr trace) <- copy _self
   var trace-ah/eax: (addr handle stream trace-line) <- get self, data
@@ -118,7 +125,7 @@ fn render-trace screen: (addr screen), _self: (addr trace), xmin: int, ymin: int
       var _curr-data/eax: (addr array byte) <- lookup *curr-data-ah
       var curr-data/edx: (addr array byte) <- copy _curr-data
       var x/eax: int <- copy xmin
-      x, y <- draw-text-wrapping-right-then-down screen, curr-data, xmin, ymin, xmax, ymax, x, y, 0xc/fg=trace-error, 0/bg
+      x, y <- draw-text-wrapping-right-then-down screen, curr-data, xmin, ymin, xmax, ymax, x, y, 0xc/fg=trace-error, bg
       y <- increment
       already-hiding-lines? <- copy 0/false
       loop $render-trace:loop
@@ -128,7 +135,7 @@ fn render-trace screen: (addr screen), _self: (addr trace), xmin: int, ymin: int
     {
       break-if-!=
       var x/eax: int <- copy xmin
-      x, y <- draw-text-wrapping-right-then-down screen, "...", xmin, ymin, xmax, ymax, x, y, 9/fg=trace, 0/bg
+      x, y <- draw-text-wrapping-right-then-down screen, "...", xmin, ymin, xmax, ymax, x, y, 9/fg=trace, bg
       y <- increment
     }
     loop
@@ -145,7 +152,7 @@ fn test-render-trace-empty {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 5, 4
   #
-  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax
+  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax, 0/no-cursor
   #
   check-ints-equal y, 0, "F - test-render-trace-empty/cursor"
   check-screen-row screen, 0/y, "    ", "F - test-render-trace-empty"
@@ -164,7 +171,7 @@ fn test-render-trace-collapsed-by-default {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 5, 4
   #
-  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax
+  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax, 0/no-cursor
   #
   check-ints-equal y, 1, "F - test-render-trace-collapsed-by-default/cursor"
   check-screen-row screen, 0/y, "... ", "F - test-render-trace-collapsed-by-default"
@@ -180,7 +187,7 @@ fn test-render-trace-error {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 0xa, 4
   #
-  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax
+  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor
   #
   check-ints-equal y, 1, "F - test-render-trace-error/cursor"
   check-screen-row screen, 0/y, "error", "F - test-render-trace-error"
@@ -202,7 +209,7 @@ fn test-render-trace-error-at-start {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 0xa, 4
   #
-  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax
+  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor
   #
   check-ints-equal y, 2, "F - test-render-trace-error-at-start/cursor"
   check-screen-row screen, 0/y, "error", "F - test-render-trace-error-at-start/0"
@@ -225,7 +232,7 @@ fn test-render-trace-error-at-end {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 0xa, 4
   #
-  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax
+  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor
   #
   check-ints-equal y, 2, "F - test-render-trace-error-at-end/cursor"
   check-screen-row screen, 0/y, "...  ", "F - test-render-trace-error-at-end/0"
@@ -250,10 +257,13 @@ fn test-render-trace-error-in-the-middle {
   var screen/edi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 0xa, 4
   #
-  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax
+  var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor
   #
   check-ints-equal y, 3, "F - test-render-trace-error-in-the-middle/cursor"
   check-screen-row screen, 0/y, "...  ", "F - test-render-trace-error-in-the-middle/0"
   check-screen-row screen, 1/y, "error", "F - test-render-trace-error-in-the-middle/1"
   check-screen-row screen, 2/y, "...  ", "F - test-render-trace-error-in-the-middle/2"
 }
+
+fn edit-trace self: (addr trace), key: grapheme {
+}