about summary refs log tree commit diff stats
path: root/archive/2.vm/sandbox/001-editor.mu
diff options
context:
space:
mode:
Diffstat (limited to 'archive/2.vm/sandbox/001-editor.mu')
-rw-r--r--archive/2.vm/sandbox/001-editor.mu464
1 files changed, 0 insertions, 464 deletions
diff --git a/archive/2.vm/sandbox/001-editor.mu b/archive/2.vm/sandbox/001-editor.mu
deleted file mode 100644
index b3399dbb..00000000
--- a/archive/2.vm/sandbox/001-editor.mu
+++ /dev/null
@@ -1,464 +0,0 @@
-## the basic editor data structure, and how it displays text to the screen
-
-# temporary main for this layer: just render the given text at the given
-# screen dimensions, then stop
-def main text:text [
-  local-scope
-  load-inputs
-  open-console
-  clear-screen null/screen  # non-scrolling app
-  e:&:editor <- new-editor text, 0/left, 5/right
-  render null/screen, e
-  wait-for-event null/console
-  close-console
-]
-
-scenario editor-renders-text-to-screen [
-  local-scope
-  assume-screen 10/width, 5/height
-  e:&:editor <- new-editor [abc], 0/left, 10/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    # top line of screen reserved for menu
-    .          .
-    .abc       .
-    .          .
-  ]
-]
-
-container editor [
-  # editable text: doubly linked list of characters (head contains a special sentinel)
-  data:&:duplex-list:char
-  top-of-screen:&:duplex-list:char
-  bottom-of-screen:&:duplex-list:char
-  # location before cursor inside data
-  before-cursor:&:duplex-list:char
-
-  # raw bounds of display area on screen
-  # always displays from row 1 (leaving row 0 for a menu) and at most until bottom of screen
-  left:num
-  right:num
-  bottom:num
-  # raw screen coordinates of cursor
-  cursor-row:num
-  cursor-column:num
-]
-
-# creates a new editor widget
-#   right is exclusive
-def new-editor s:text, left:num, right:num -> result:&:editor [
-  local-scope
-  load-inputs
-  # no clipping of bounds
-  right <- subtract right, 1
-  result <- new editor:type
-  # initialize screen-related fields
-  *result <- put *result, left:offset, left
-  *result <- put *result, right:offset, right
-  # initialize cursor coordinates
-  *result <- put *result, cursor-row:offset, 1/top
-  *result <- put *result, cursor-column:offset, left
-  # initialize empty contents
-  init:&:duplex-list:char <- push 167/§, null
-  *result <- put *result, data:offset, init
-  *result <- put *result, top-of-screen:offset, init
-  *result <- put *result, before-cursor:offset, init
-  result <- insert-text result, s
-  <editor-initialization>
-]
-
-def insert-text editor:&:editor, text:text -> editor:&:editor [
-  local-scope
-  load-inputs
-  curr:&:duplex-list:char <- get *editor, data:offset
-  insert curr, text
-]
-
-scenario editor-initializes-without-data [
-  local-scope
-  assume-screen 5/width, 3/height
-  run [
-    e:&:editor <- new-editor null/data, 2/left, 5/right
-    1:editor/raw <- copy *e
-  ]
-  memory-should-contain [
-    # 1,2 (data) <- just the § sentinel
-    # 3,4 (top of screen) <- the § sentinel
-    # 5 (bottom of screen) <- null since text fits on screen
-    5 <- 0
-    6 <- 0
-    # 7,8 (before cursor) <- the § sentinel
-    9 <- 2  # left
-    10 <- 4  # right  (inclusive)
-    11 <- 0  # bottom (not set until render)
-    12 <- 1  # cursor row
-    13 <- 2  # cursor column
-  ]
-  screen-should-contain [
-    .     .
-    .     .
-    .     .
-  ]
-]
-
-# Assumes cursor should be at coordinates (cursor-row, cursor-column) and
-# updates before-cursor to match. Might also move coordinates if they're
-# outside text.
-def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, screen:&:screen, editor:&:editor [
-  local-scope
-  load-inputs
-  return-unless editor, 1/top, 0/left
-  left:num <- get *editor, left:offset
-  screen-height:num <- screen-height screen
-  right:num <- get *editor, right:offset
-  # traversing editor
-  curr:&:duplex-list:char <- get *editor, top-of-screen:offset
-  prev:&:duplex-list:char <- copy curr  # just in case curr becomes null and we can't compute prev
-  curr <- next curr
-  # traversing screen
-  color:num <- copy 7/white
-  row:num <- copy 1/top
-  column:num <- copy left
-  cursor-row:num <- get *editor, cursor-row:offset
-  cursor-column:num <- get *editor, cursor-column:offset
-  before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
-  screen <- move-cursor screen, row, column
-  {
-    +next-character
-    break-unless curr
-    off-screen?:bool <- greater-or-equal row, screen-height
-    break-if off-screen?
-    # update editor.before-cursor
-    # Doing so at the start of each iteration ensures it stays one step behind
-    # the current character.
-    {
-      at-cursor-row?:bool <- equal row, cursor-row
-      break-unless at-cursor-row?
-      at-cursor?:bool <- equal column, cursor-column
-      break-unless at-cursor?
-      before-cursor <- copy prev
-    }
-    c:char <- get *curr, value:offset
-    <character-c-received>
-    {
-      # newline? move to left rather than 0
-      newline?:bool <- equal c, 10/newline
-      break-unless newline?
-      # adjust cursor if necessary
-      {
-        at-cursor-row?:bool <- equal row, cursor-row
-        break-unless at-cursor-row?
-        left-of-cursor?:bool <- lesser-than column, cursor-column
-        break-unless left-of-cursor?
-        cursor-column <- copy column
-        before-cursor <- prev curr
-      }
-      # clear rest of line in this window
-      clear-line-until screen, right
-      # skip to next line
-      row <- add row, 1
-      column <- copy left
-      screen <- move-cursor screen, row, column
-      curr <- next curr
-      prev <- next prev
-      loop +next-character
-    }
-    {
-      # at right? wrap. even if there's only one more letter left; we need
-      # room for clicking on the cursor after it.
-      at-right?:bool <- equal column, right
-      break-unless at-right?
-      # print wrap icon
-      wrap-icon:char <- copy 8617/loop-back-to-left
-      print screen, wrap-icon, 245/grey
-      column <- copy left
-      row <- add row, 1
-      screen <- move-cursor screen, row, column
-      # don't increment curr
-      loop +next-character
-    }
-    print screen, c, color
-    curr <- next curr
-    prev <- next prev
-    column <- add column, 1
-    loop
-  }
-  # save first character off-screen
-  *editor <- put *editor, bottom-of-screen:offset, curr
-  # is cursor to the right of the last line? move to end
-  {
-    at-cursor-row?:bool <- equal row, cursor-row
-    cursor-outside-line?:bool <- lesser-or-equal column, cursor-column
-    before-cursor-on-same-line?:bool <- and at-cursor-row?, cursor-outside-line?
-    above-cursor-row?:bool <- lesser-than row, cursor-row
-    before-cursor?:bool <- or before-cursor-on-same-line?, above-cursor-row?
-    break-unless before-cursor?
-    cursor-row <- copy row
-    cursor-column <- copy column
-    before-cursor <- copy prev
-  }
-  *editor <- put *editor, bottom:offset, row
-  *editor <- put *editor, cursor-row:offset, cursor-row
-  *editor <- put *editor, cursor-column:offset, cursor-column
-  *editor <- put *editor, before-cursor:offset, before-cursor
-  clear-line-until screen, right
-  row <- add row, 1
-  return row, left/column
-]
-
-def clear-screen-from screen:&:screen, row:num, column:num, left:num, right:num -> screen:&:screen [
-  local-scope
-  load-inputs
-  # if it's the real screen, use the optimized primitive
-  {
-    break-if screen
-    clear-display-from row, column, left, right
-    return
-  }
-  # if not, go the slower route
-  screen <- move-cursor screen, row, column
-  clear-line-until screen, right
-  clear-rest-of-screen screen, row, left, right
-]
-
-def clear-rest-of-screen screen:&:screen, row:num, left:num, right:num -> screen:&:screen [
-  local-scope
-  load-inputs
-  row <- add row, 1
-  # if it's the real screen, use the optimized primitive
-  {
-    break-if screen
-    clear-display-from row, left, left, right
-    return
-  }
-  screen <- move-cursor screen, row, left
-  screen-height:num <- screen-height screen
-  {
-    at-bottom-of-screen?:bool <- greater-or-equal row, screen-height
-    break-if at-bottom-of-screen?
-    screen <- move-cursor screen, row, left
-    clear-line-until screen, right
-    row <- add row, 1
-    loop
-  }
-]
-
-scenario editor-prints-multiple-lines [
-  local-scope
-  assume-screen 5/width, 5/height
-  s:text <- new [abc
-def]
-  e:&:editor <- new-editor s, 0/left, 5/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    .     .
-    .abc  .
-    .def  .
-    .     .
-  ]
-]
-
-scenario editor-handles-offsets [
-  local-scope
-  assume-screen 5/width, 5/height
-  e:&:editor <- new-editor [abc], 1/left, 5/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    .     .
-    . abc .
-    .     .
-  ]
-]
-
-scenario editor-prints-multiple-lines-at-offset [
-  local-scope
-  assume-screen 5/width, 5/height
-  s:text <- new [abc
-def]
-  e:&:editor <- new-editor s, 1/left, 5/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    .     .
-    . abc .
-    . def .
-    .     .
-  ]
-]
-
-scenario editor-wraps-long-lines [
-  local-scope
-  assume-screen 5/width, 5/height
-  e:&:editor <- new-editor [abc def], 0/left, 5/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    .     .
-    .abc ↩.
-    .def  .
-    .     .
-  ]
-  screen-should-contain-in-color 245/grey [
-    .     .
-    .    ↩.
-    .     .
-    .     .
-  ]
-]
-
-scenario editor-wraps-barely-long-lines [
-  local-scope
-  assume-screen 5/width, 5/height
-  e:&:editor <- new-editor [abcde], 0/left, 5/right
-  run [
-    render screen, e
-  ]
-  # still wrap, even though the line would fit. We need room to click on the
-  # end of the line
-  screen-should-contain [
-    .     .
-    .abcd↩.
-    .e    .
-    .     .
-  ]
-  screen-should-contain-in-color 245/grey [
-    .     .
-    .    ↩.
-    .     .
-    .     .
-  ]
-]
-
-scenario editor-with-empty-text [
-  local-scope
-  assume-screen 5/width, 5/height
-  e:&:editor <- new-editor [], 0/left, 5/right
-  run [
-    render screen, e
-    3:num/raw <- get *e, cursor-row:offset
-    4:num/raw <- get *e, cursor-column:offset
-  ]
-  screen-should-contain [
-    .     .
-    .     .
-    .     .
-  ]
-  memory-should-contain [
-    3 <- 1  # cursor row
-    4 <- 0  # cursor column
-  ]
-]
-
-# just a little color for Mu code
-
-scenario render-colors-comments [
-  local-scope
-  assume-screen 5/width, 5/height
-  s:text <- new [abc
-# de
-f]
-  e:&:editor <- new-editor s, 0/left, 5/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    .     .
-    .abc  .
-    .# de .
-    .f    .
-    .     .
-  ]
-  screen-should-contain-in-color 12/lightblue, [
-    .     .
-    .     .
-    .# de .
-    .     .
-    .     .
-  ]
-  screen-should-contain-in-color 7/white, [
-    .     .
-    .abc  .
-    .     .
-    .f    .
-    .     .
-  ]
-]
-
-after <character-c-received> [
-  color <- get-color color, c
-]
-
-# so far the previous color is all the information we need; that may change
-def get-color color:num, c:char -> color:num [
-  local-scope
-  load-inputs
-  color-is-white?:bool <- equal color, 7/white
-  # if color is white and next character is '#', switch color to blue
-  {
-    break-unless color-is-white?
-    starting-comment?:bool <- equal c, 35/#
-    break-unless starting-comment?
-    trace 90, [app], [switch color back to blue]
-    return 12/lightblue
-  }
-  # if color is blue and next character is newline, switch color to white
-  {
-    color-is-blue?:bool <- equal color, 12/lightblue
-    break-unless color-is-blue?
-    ending-comment?:bool <- equal c, 10/newline
-    break-unless ending-comment?
-    trace 90, [app], [switch color back to white]
-    return 7/white
-  }
-  # if color is white (no comments) and next character is '<', switch color to red
-  {
-    break-unless color-is-white?
-    starting-assignment?:bool <- equal c, 60/<
-    break-unless starting-assignment?
-    return 1/red
-  }
-  # if color is red and next character is space, switch color to white
-  {
-    color-is-red?:bool <- equal color, 1/red
-    break-unless color-is-red?
-    ending-assignment?:bool <- equal c, 32/space
-    break-unless ending-assignment?
-    return 7/white
-  }
-  # otherwise no change
-  return color
-]
-
-scenario render-colors-assignment [
-  local-scope
-  assume-screen 8/width, 5/height
-  s:text <- new [abc
-d <- e
-f]
-  e:&:editor <- new-editor s, 0/left, 8/right
-  run [
-    render screen, e
-  ]
-  screen-should-contain [
-    .        .
-    .abc     .
-    .d <- e  .
-    .f       .
-    .        .
-  ]
-  screen-should-contain-in-color 1/red, [
-    .        .
-    .        .
-    .  <-    .
-    .        .
-    .        .
-  ]
-]