about summary refs log blame commit diff stats
path: root/html/edit/001-editor.mu.html
blob: 01b0bf0aa87dc9ac1602e3942e5eb0f379bf6e0c (plain) (tree)
1
2
3
4
5
6
7
8
9
10




                                                                                          

                                                
                                   

                                                                                         

                       
                                                                                                 
                                                                                            
                                      
                           
                              
                            
                              
                            
                             
                                   

                               

        





                               

       
                         

                                                                                                              
                                                                                                     
                                                           
                                                   
                                           
                                                







                                                                                                                                      
                                                                                 
                                           

                                                                                              
                                                                                                                                                     








                                                                       
                                              
                                                                                                                   


                                         
                                                                   
                                      


                                                                                                                         


            
                                                                 

                   

 


                                                                                                       
                                                                                                                                                                            
                                           
                                                
                                                      

                                                                                          
                                                                 

                                                                                                           
                                                              

                                                                                                                                              
                                                          




                                                                                                                                                
                                                                                  
                                                                               
                                                             

 
                                                                                                                                      
                                           
                                                
                                                            



                                                                                 
                                                                                            
                                                                                                                       
                                  
                                                                           
                                                 
                                                              
                  
                                            

                                                                                   

                                       
                                                                   


                                                                          
                                           

                                                                                             

                                                                                                                                                                                                       



                                                                          
                                                                                                                                                                                       
                                                                          




                                                                                                                                                         







                                         


                                                                                                      
                                                                                                                                                                                               
                                           
                                                



                                                                                                                                                                                          
                                                  


                                                                                                                                                                   

                                                           






                                                                                                                                         


                                                    
                                                                                           
                                                       
                                                              


                                                                                                           
                                                                                  
                                                                
                                                                                    
                                                            
                                                                
                                    
                                                                                                   


                                                                        
                                                                                                        


                                                               
                                                                                    
                                                                  
                                                                                                 
                                                                   

                                                                    

                                                                      
                                    
                                                      




                                                                                     
                                                                                       



                                                                                                       
                                                                           

                                                           
                                                                                                                 
                                                                     


                                                                                     
                                                         
                                                                                       
                                    
                          


                                                                                         


                                                                
                                                                                                                     

                                                                                     




                                                                                                                
                                                              


                                                                
                                  




                                                                                                                           

 
                                                                                                                                                                           
                                           
                                                



                                                                                     
                                                                     

                                                            
                                                                           
                                
                                               
                                                                   

 
                                                                                                                                                                  
                                           
                                                


                                                                                 
                                  
                                                                                                    
                                                                
                                                                           
                                  
                                                                                   




                                                                                 
                                           

                                                                                             
                                                                                    
                                  
                                                                                                                  









                                                                           
                                           

                                                                                             
                                                                                     
                                                                                                                  








                                                                                           
                                           

                                                                                             
                                                                                    
                                  
                                                                                                                  









                                                                            
                                           

                                                                                             
                                                                                         
                                                                                                                  















                                                                                   
                                           

                                                                                             
                                                                                       
                                                                                                                  

















                                                                                                         
                                           

                                                                                             


                                                                                                                                                                                                   






                                         

                                                                                                                                                    


   
                                                              

                                                                 
                                           

                                                                                             
                                                                                    

                                  
                                                                                                                  
























                                                                                                
                                                             

 
                                                                                                        
                                                                                                             
                                           
                                                
                                                                                                            


                                                                                                  
                                                                                                         
                                                                 

                                                                                                                                          
                                                                           


                                                                                                      
                                                                                                                  
                                                              
                                                                                                             
                                                               

                                                                                                                                           
                                                                           



                                                                                                                  
                                                                                                               
                                                                    
                                                                                     
                                                                           


                                                                                                   
                                                                                                          
                                                             
                                                                                                              
                                                                  
                                                                                       
                                                                           


                                                    
                                             


                                                                   
                                           

                                                                                             
                                                                                    

                                       
                                                                                                                  


















                                                                       
                                     
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - edit/001-editor.mu</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="none">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.muData { color: #ffff00; }
.muControl { color: #c0a020; }
.Special { color: #c00000; }
.Delimiter { color: #800080; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="SalientComment">## the basic editor data structure, and how it displays text to the screen</span>

<span class="Comment"># temporary main for this layer: just render the given text at the given</span>
<span class="Comment"># screen dimensions, then stop</span>
<span class="muRecipe">def!</span> main text:text [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  open-console
  hide-screen <span class="Constant">0/screen</span>
  new-editor text, <span class="Constant">0/screen</span>, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
  show-screen <span class="Constant">0/screen</span>
  wait-for-event <span class="Constant">0/console</span>
  close-console
]

<span class="muScenario">scenario</span> editor-initially-prints-text-to-screen [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
  run [
    new-editor <span class="Constant">[abc]</span>, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
  ]
  screen-should-contain [
    <span class="Comment"># top line of screen reserved for menu</span>
   <span class="Constant"> .          .</span>
   <span class="Constant"> .abc       .</span>
   <span class="Constant"> .          .</span>
  ]
]

<span class="muData">container</span> editor [
  <span class="Comment"># editable text: doubly linked list of characters (head contains a special sentinel)</span>
  data:&amp;:duplex-list:char
  top-of-screen:&amp;:duplex-list:char
  bottom-of-screen:&amp;:duplex-list:char
  <span class="Comment"># location before cursor inside data</span>
  before-cursor:&amp;:duplex-list:char

  <span class="Comment"># raw bounds of display area on screen</span>
  <span class="Comment"># always displays from row 1 (leaving row 0 for a menu) and at most until bottom of screen</span>
  left:num
  right:num
  bottom:num
  <span class="Comment"># raw screen coordinates of cursor</span>
  cursor-row:num
  cursor-column:num
]

<span class="Comment"># creates a new editor widget and renders its initial appearance to screen</span>
<span class="Comment">#   top/left/right constrain the screen area available to the new editor</span>
<span class="Comment">#   right is exclusive</span>
<span class="muRecipe">def</span> new-editor s:text, screen:&amp;:screen, left:num, right:num<span class="muRecipe"> -&gt; </span>result:&amp;:editor, screen:&amp;:screen [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  <span class="Comment"># no clipping of bounds</span>
  right <span class="Special">&lt;-</span> subtract right,<span class="Constant"> 1</span>
  result <span class="Special">&lt;-</span> new <span class="Constant">editor:type</span>
  <span class="Comment"># initialize screen-related fields</span>
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">left:offset</span>, left
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">right:offset</span>, right
  <span class="Comment"># initialize cursor coordinates</span>
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">cursor-row:offset</span>, <span class="Constant">1/top</span>
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">cursor-column:offset</span>, left
  <span class="Comment"># initialize empty contents</span>
  init:&amp;:duplex-list:char <span class="Special">&lt;-</span> push <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">data:offset</span>, init
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">top-of-screen:offset</span>, init
  *result <span class="Special">&lt;-</span> put *result, <span class="Constant">before-cursor:offset</span>, init
  result <span class="Special">&lt;-</span> insert-text result, s
  <span class="Comment"># initial render to screen, just for some old tests</span>
  _, _, screen, result <span class="Special">&lt;-</span> render screen, result
<span class="Constant">  &lt;editor-initialization&gt;</span>
]

<span class="muRecipe">def</span> insert-text editor:&amp;:editor, text:text<span class="muRecipe"> -&gt; </span>editor:&amp;:editor [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  <span class="Comment"># early exit if text is empty</span>
  <span class="muControl">return-unless</span> text, editor/same-as-ingredient:0
  len:num <span class="Special">&lt;-</span> length *text
  <span class="muControl">return-unless</span> len, editor/same-as-ingredient:0
  idx:num <span class="Special">&lt;-</span> copy<span class="Constant"> 0</span>
  <span class="Comment"># now we can start appending the rest, character by character</span>
  curr:&amp;:duplex-list:char <span class="Special">&lt;-</span> get *editor, <span class="Constant">data:offset</span>
  <span class="Delimiter">{</span>
    done?:bool <span class="Special">&lt;-</span> greater-or-equal idx, len
    <span class="muControl">break-if</span> done?
    c:char <span class="Special">&lt;-</span> index *text, idx
    insert c, curr
    <span class="Comment"># next iter</span>
    curr <span class="Special">&lt;-</span> next curr
    idx <span class="Special">&lt;-</span> add idx,<span class="Constant"> 1</span>
    <span class="muControl">loop</span>
  <span class="Delimiter">}</span>
  <span class="muControl">return</span> editor/same-as-ingredient:0
]

<span class="muScenario">scenario</span> editor-initializes-without-data [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">3/height</span>
  run [
    e:&amp;:editor <span class="Special">&lt;-</span> new-editor <span class="Constant">0/data</span>, screen:&amp;:screen, <span class="Constant">2/left</span>, <span class="Constant">5/right</span>
    2:editor/<span class="Special">raw</span> <span class="Special">&lt;-</span> copy *e
  ]
  memory-should-contain [
    <span class="Comment"># 2 (data) &lt;- just the § sentinel</span>
    <span class="Comment"># 3 (top of screen) &lt;- the § sentinel</span>
   <span class="Constant"> 4</span> <span class="Special">&lt;-</span><span class="Constant"> 0</span>  <span class="Comment"># bottom-of-screen; null since text fits on screen</span>
    <span class="Comment"># 5 (before cursor) &lt;- the § sentinel</span>
   <span class="Constant"> 6</span> <span class="Special">&lt;-</span><span class="Constant"> 2</span>  <span class="Comment"># left</span>
   <span class="Constant"> 7</span> <span class="Special">&lt;-</span><span class="Constant"> 4</span>  <span class="Comment"># right  (inclusive)</span>
   <span class="Constant"> 8</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># bottom</span>
   <span class="Constant"> 9</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># cursor row</span>
   <span class="Constant"> 10</span> <span class="Special">&lt;-</span><span class="Constant"> 2</span>  <span class="Comment"># cursor column</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="Comment"># Assumes cursor should be at coordinates (cursor-row, cursor-column) and</span>
<span class="Comment"># updates before-cursor to match. Might also move coordinates if they're</span>
<span class="Comment"># outside text.</span>
<span class="muRecipe">def</span> render screen:&amp;:screen, editor:&amp;:editor<span class="muRecipe"> -&gt; </span>last-row:num, last-column:num, screen:&amp;:screen, editor:&amp;:editor [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  <span class="muControl">return-unless</span> editor, <span class="Constant">1/top</span>, <span class="Constant">0/left</span>, screen/same-as-ingredient:0, editor/same-as-ingredient:1
  left:num <span class="Special">&lt;-</span> get *editor, <span class="Constant">left:offset</span>
  screen-height:num <span class="Special">&lt;-</span> screen-height screen
  right:num <span class="Special">&lt;-</span> get *editor, <span class="Constant">right:offset</span>
  <span class="Comment"># traversing editor</span>
  curr:&amp;:duplex-list:char <span class="Special">&lt;-</span> get *editor, <span class="Constant">top-of-screen:offset</span>
  prev:&amp;:duplex-list:char <span class="Special">&lt;-</span> copy curr  <span class="Comment"># just in case curr becomes null and we can't compute prev</span>
  curr <span class="Special">&lt;-</span> next curr
  <span class="Comment"># traversing screen</span>
<span class="Constant">  +render-loop-initialization</span>
  color:num <span class="Special">&lt;-</span> copy <span class="Constant">7/white</span>
  row:num <span class="Special">&lt;-</span> copy <span class="Constant">1/top</span>
  column:num <span class="Special">&lt;-</span> copy left
  cursor-row:num <span class="Special">&lt;-</span> get *editor, <span class="Constant">cursor-row:offset</span>
  cursor-column:num <span class="Special">&lt;-</span> get *editor, <span class="Constant">cursor-column:offset</span>
  before-cursor:&amp;:duplex-list:char <span class="Special">&lt;-</span> get *editor, <span class="Constant">before-cursor:offset</span>
  screen <span class="Special">&lt;-</span> move-cursor screen, row, column
  <span class="Delimiter">{</span>
<span class="Constant">    +next-character</span>
    <span class="muControl">break-unless</span> curr
    off-screen?:bool <span class="Special">&lt;-</span> greater-or-equal row, screen-height
    <span class="muControl">break-if</span> off-screen?
    <span class="Comment"># update editor.before-cursor</span>
    <span class="Comment"># Doing so at the start of each iteration ensures it stays one step behind</span>
    <span class="Comment"># the current character.</span>
    <span class="Delimiter">{</span>
      at-cursor-row?:bool <span class="Special">&lt;-</span> equal row, cursor-row
      <span class="muControl">break-unless</span> at-cursor-row?
      at-cursor?:bool <span class="Special">&lt;-</span> equal column, cursor-column
      <span class="muControl">break-unless</span> at-cursor?
      before-cursor <span class="Special">&lt;-</span> copy prev
    <span class="Delimiter">}</span>
    c:char <span class="Special">&lt;-</span> get *curr, <span class="Constant">value:offset</span>
<span class="Constant">    &lt;character-c-received&gt;</span>
    <span class="Delimiter">{</span>
      <span class="Comment"># newline? move to left rather than 0</span>
      newline?:bool <span class="Special">&lt;-</span> equal c, <span class="Constant">10/newline</span>
      <span class="muControl">break-unless</span> newline?
      <span class="Comment"># adjust cursor if necessary</span>
      <span class="Delimiter">{</span>
        at-cursor-row?:bool <span class="Special">&lt;-</span> equal row, cursor-row
        <span class="muControl">break-unless</span> at-cursor-row?
        left-of-cursor?:bool <span class="Special">&lt;-</span> lesser-than column, cursor-column
        <span class="muControl">break-unless</span> left-of-cursor?
        cursor-column <span class="Special">&lt;-</span> copy column
        before-cursor <span class="Special">&lt;-</span> prev curr
      <span class="Delimiter">}</span>
      <span class="Comment"># clear rest of line in this window</span>
      clear-line-until screen, right
      <span class="Comment"># skip to next line</span>
      row <span class="Special">&lt;-</span> add row,<span class="Constant"> 1</span>
      column <span class="Special">&lt;-</span> copy left
      screen <span class="Special">&lt;-</span> move-cursor screen, row, column
      curr <span class="Special">&lt;-</span> next curr
      prev <span class="Special">&lt;-</span> next prev
      <span class="muControl">loop</span> <span class="Constant">+next-character</span>
    <span class="Delimiter">}</span>
    <span class="Delimiter">{</span>
      <span class="Comment"># at right? wrap. even if there's only one more letter left; we need</span>
      <span class="Comment"># room for clicking on the cursor after it.</span>
      at-right?:bool <span class="Special">&lt;-</span> equal column, right
      <span class="muControl">break-unless</span> at-right?
      <span class="Comment"># print wrap icon</span>
      wrap-icon:char <span class="Special">&lt;-</span> copy <span class="Constant">8617/loop-back-to-left</span>
      print screen, wrap-icon, <span class="Constant">245/grey</span>
      column <span class="Special">&lt;-</span> copy left
      row <span class="Special">&lt;-</span> add row,<span class="Constant"> 1</span>
      screen <span class="Special">&lt;-</span> move-cursor screen, row, column
      <span class="Comment"># don't increment curr</span>
      <span class="muControl">loop</span> <span class="Constant">+next-character</span>
    <span class="Delimiter">}</span>
    print screen, c, color
    curr <span class="Special">&lt;-</span> next curr
    prev <span class="Special">&lt;-</span> next prev
    column <span class="Special">&lt;-</span> add column,<span class="Constant"> 1</span>
    <span class="muControl">loop</span>
  <span class="Delimiter">}</span>
  <span class="Comment"># save first character off-screen</span>
  *editor <span class="Special">&lt;-</span> put *editor, <span class="Constant">bottom-of-screen:offset</span>, curr
  <span class="Comment"># is cursor to the right of the last line? move to end</span>
  <span class="Delimiter">{</span>
    at-cursor-row?:bool <span class="Special">&lt;-</span> equal row, cursor-row
    cursor-outside-line?:bool <span class="Special">&lt;-</span> lesser-or-equal column, cursor-column
    before-cursor-on-same-line?:bool <span class="Special">&lt;-</span> and at-cursor-row?, cursor-outside-line?
    above-cursor-row?:bool <span class="Special">&lt;-</span> lesser-than row, cursor-row
    before-cursor?:bool <span class="Special">&lt;-</span> or before-cursor-on-same-line?, above-cursor-row?
    <span class="muControl">break-unless</span> before-cursor?
    cursor-row <span class="Special">&lt;-</span> copy row
    cursor-column <span class="Special">&lt;-</span> copy column
    before-cursor <span class="Special">&lt;-</span> copy prev
  <span class="Delimiter">}</span>
  *editor <span class="Special">&lt;-</span> put *editor, <span class="Constant">bottom:offset</span>, row
  *editor <span class="Special">&lt;-</span> put *editor, <span class="Constant">cursor-row:offset</span>, cursor-row
  *editor <span class="Special">&lt;-</span> put *editor, <span class="Constant">cursor-column:offset</span>, cursor-column
  *editor <span class="Special">&lt;-</span> put *editor, <span class="Constant">before-cursor:offset</span>, before-cursor
  <span class="muControl">return</span> row, column, screen/same-as-ingredient:0, editor/same-as-ingredient:1
]

<span class="muRecipe">def</span> clear-screen-from screen:&amp;:screen, row:num, column:num, left:num, right:num<span class="muRecipe"> -&gt; </span>screen:&amp;:screen [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  <span class="Comment"># if it's the real screen, use the optimized primitive</span>
  <span class="Delimiter">{</span>
    <span class="muControl">break-if</span> screen
    clear-display-from row, column, left, right
    <span class="muControl">return</span> screen/same-as-ingredient:0
  <span class="Delimiter">}</span>
  <span class="Comment"># if not, go the slower route</span>
  screen <span class="Special">&lt;-</span> move-cursor screen, row, column
  clear-line-until screen, right
  clear-rest-of-screen screen, row, left, right
  <span class="muControl">return</span> screen/same-as-ingredient:0
]

<span class="muRecipe">def</span> clear-rest-of-screen screen:&amp;:screen, row:num, left:num, right:num<span class="muRecipe"> -&gt; </span>screen:&amp;:screen [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  row <span class="Special">&lt;-</span> add row,<span class="Constant"> 1</span>
  screen <span class="Special">&lt;-</span> move-cursor screen, row, left
  screen-height:num <span class="Special">&lt;-</span> screen-height screen
  <span class="Delimiter">{</span>
    at-bottom-of-screen?:bool <span class="Special">&lt;-</span> greater-or-equal row, screen-height
    <span class="muControl">break-if</span> at-bottom-of-screen?
    screen <span class="Special">&lt;-</span> move-cursor screen, row, left
    clear-line-until screen, right
    row <span class="Special">&lt;-</span> add row,<span class="Constant"> 1</span>
    <span class="muControl">loop</span>
  <span class="Delimiter">}</span>
]

<span class="muScenario">scenario</span> editor-initially-prints-multiple-lines [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .abc  .</span>
   <span class="Constant"> .def  .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="muScenario">scenario</span> editor-initially-handles-offsets [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abc]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">1/left</span>, <span class="Constant">5/right</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> . abc .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="muScenario">scenario</span> editor-initially-prints-multiple-lines-at-offset [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">1/left</span>, <span class="Constant">5/right</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> . abc .</span>
   <span class="Constant"> . def .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="muScenario">scenario</span> editor-initially-wraps-long-lines [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abc def]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .abc ↩.</span>
   <span class="Constant"> .def  .</span>
   <span class="Constant"> .     .</span>
  ]
  screen-should-contain-in-color <span class="Constant">245/grey</span> [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .    ↩.</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="muScenario">scenario</span> editor-initially-wraps-barely-long-lines [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abcde]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
  ]
  <span class="Comment"># still wrap, even though the line would fit. We need room to click on the</span>
  <span class="Comment"># end of the line</span>
  screen-should-contain [
   <span class="Constant"> .     .</span>
<span class="Constant">    .abcd↩.</span>
   <span class="Constant"> .e    .</span>
   <span class="Constant"> .     .</span>
  ]
  screen-should-contain-in-color <span class="Constant">245/grey</span> [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .    ↩.</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="muScenario">scenario</span> editor-initializes-empty-text [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    e:&amp;:editor <span class="Special">&lt;-</span> new-editor <span class="Constant">[]</span>, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
    3:num/<span class="Special">raw</span> <span class="Special">&lt;-</span> get *e, <span class="Constant">cursor-row:offset</span>
    4:num/<span class="Special">raw</span> <span class="Special">&lt;-</span> get *e, <span class="Constant">cursor-column:offset</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
  ]
  memory-should-contain [
   <span class="Constant"> 3</span> <span class="Special">&lt;-</span><span class="Constant"> 1</span>  <span class="Comment"># cursor row</span>
   <span class="Constant"> 4</span> <span class="Special">&lt;-</span><span class="Constant"> 0</span>  <span class="Comment"># cursor column</span>
  ]
]

<span class="Comment"># just a little color for Mu code</span>

<span class="muScenario">scenario</span> render-colors-comments [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abc</span>
<span class="Constant"># de</span>
<span class="Constant">f]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
  ]
  screen-should-contain [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .abc  .</span>
   <span class="Constant"> .# de .</span>
   <span class="Constant"> .f    .</span>
   <span class="Constant"> .     .</span>
  ]
  screen-should-contain-in-color <span class="Constant">12/lightblue</span>, [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .# de .</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .     .</span>
  ]
  screen-should-contain-in-color <span class="Constant">7/white</span>, [
   <span class="Constant"> .     .</span>
   <span class="Constant"> .abc  .</span>
   <span class="Constant"> .     .</span>
   <span class="Constant"> .f    .</span>
   <span class="Constant"> .     .</span>
  ]
]

<span class="muRecipe">after</span> <span class="Constant">&lt;character-c-received&gt;</span> [
  color <span class="Special">&lt;-</span> get-color color, c
]

<span class="Comment"># so far the previous color is all the information we need; that may change</span>
<span class="muRecipe">def</span> get-color color:num, c:char<span class="muRecipe"> -&gt; </span>color:num [
  <span class="Constant">local-scope</span>
  <span class="Constant">load-ingredients</span>
  color-is-white?:bool <span class="Special">&lt;-</span> equal color, <span class="Constant">7/white</span>
  <span class="Comment"># if color is white and next character is '#', switch color to blue</span>
  <span class="Delimiter">{</span>
    <span class="muControl">break-unless</span> color-is-white?
    starting-comment?:bool <span class="Special">&lt;-</span> equal c, <span class="Constant">35/#</span>
    <span class="muControl">break-unless</span> starting-comment?
    trace<span class="Constant"> 90</span>, <span class="Constant">[app]</span>, <span class="Constant">[switch color back to blue]</span>
    color <span class="Special">&lt;-</span> copy <span class="Constant">12/lightblue</span>
    <span class="muControl">jump</span> <span class="Constant">+exit</span>
  <span class="Delimiter">}</span>
  <span class="Comment"># if color is blue and next character is newline, switch color to white</span>
  <span class="Delimiter">{</span>
    color-is-blue?:bool <span class="Special">&lt;-</span> equal color, <span class="Constant">12/lightblue</span>
    <span class="muControl">break-unless</span> color-is-blue?
    ending-comment?:bool <span class="Special">&lt;-</span> equal c, <span class="Constant">10/newline</span>
    <span class="muControl">break-unless</span> ending-comment?
    trace<span class="Constant"> 90</span>, <span class="Constant">[app]</span>, <span class="Constant">[switch color back to white]</span>
    color <span class="Special">&lt;-</span> copy <span class="Constant">7/white</span>
    <span class="muControl">jump</span> <span class="Constant">+exit</span>
  <span class="Delimiter">}</span>
  <span class="Comment"># if color is white (no comments) and next character is '&lt;', switch color to red</span>
  <span class="Delimiter">{</span>
    <span class="muControl">break-unless</span> color-is-white?
    starting-assignment?:bool <span class="Special">&lt;-</span> equal c, <span class="Constant">60/&lt;</span>
    <span class="muControl">break-unless</span> starting-assignment?
    color <span class="Special">&lt;-</span> copy <span class="Constant">1/red</span>
    <span class="muControl">jump</span> <span class="Constant">+exit</span>
  <span class="Delimiter">}</span>
  <span class="Comment"># if color is red and next character is space, switch color to white</span>
  <span class="Delimiter">{</span>
    color-is-red?:bool <span class="Special">&lt;-</span> equal color, <span class="Constant">1/red</span>
    <span class="muControl">break-unless</span> color-is-red?
    ending-assignment?:bool <span class="Special">&lt;-</span> equal c, <span class="Constant">32/space</span>
    <span class="muControl">break-unless</span> ending-assignment?
    color <span class="Special">&lt;-</span> copy <span class="Constant">7/white</span>
    <span class="muControl">jump</span> <span class="Constant">+exit</span>
  <span class="Delimiter">}</span>
  <span class="Comment"># otherwise no change</span>
<span class="Constant">  +exit</span>
  <span class="muControl">return</span> color
]

<span class="muScenario">scenario</span> render-colors-assignment [
  <span class="Constant">local-scope</span>
  assume-screen <span class="Constant">8/width</span>, <span class="Constant">5/height</span>
  run [
    s:text <span class="Special">&lt;-</span> new <span class="Constant">[abc</span>
<span class="Constant">d &lt;- e</span>
<span class="Constant">f]</span>
    new-editor s, screen:&amp;:screen, <span class="Constant">0/left</span>, <span class="Constant">8/right</span>
  ]
  screen-should-contain [
   <span class="Constant"> .        .</span>
   <span class="Constant"> .abc     .</span>
   <span class="Constant"> .d &lt;- e  .</span>
   <span class="Constant"> .f       .</span>
   <span class="Constant"> .        .</span>
  ]
  screen-should-contain-in-color <span class="Constant">1/red</span>, [
   <span class="Constant"> .        .</span>
   <span class="Constant"> .        .</span>
   <span class="Constant"> .  &lt;-    .</span>
   <span class="Constant"> .        .</span>
   <span class="Constant"> .        .</span>
  ]
]
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->