about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-07-12 18:29:00 -0700
committerKartik K. Agaram <vc@akkartik.com>2022-07-12 20:54:50 -0700
commit3b36093553920fb2548332e983a32aa6fe218fd2 (patch)
tree72466962f6c71af141790f9b5cb1eb0abc8c322c
parent1ede1c3c6d3fc2ec8070da4c726b3fbe1bf9d374 (diff)
downloadview.love-3b36093553920fb2548332e983a32aa6fe218fd2.tar.gz
left/right margin -> left/right coordinates
Editor state initialization now depends on window dimensions, so we have
to more carefully orchestrate startup.
-rw-r--r--drawing.lua68
-rw-r--r--drawing_tests.lua224
-rw-r--r--edit.lua35
-rw-r--r--help.lua78
-rw-r--r--main.lua41
-rw-r--r--main_tests.lua8
-rw-r--r--search.lua4
-rw-r--r--text.lua62
-rw-r--r--text_tests.lua335
9 files changed, 486 insertions, 369 deletions
diff --git a/drawing.lua b/drawing.lua
index d0e0123..8206bd5 100644
--- a/drawing.lua
+++ b/drawing.lua
@@ -6,13 +6,13 @@ require 'drawing_tests'
 -- into 256 parts.
 function Drawing.draw(State, line)
   local pmx,pmy = App.mouse_x(), App.mouse_y()
-  if pmx < App.screen.width-State.margin_right and pmy > line.y and pmy < line.y+Drawing.pixels(line.h) then
+  if pmx < State.right and pmy > line.y and pmy < line.y+Drawing.pixels(line.h) then
     App.color(Icon_color)
-    love.graphics.rectangle('line', State.margin_left,line.y, App.screen.width-State.margin_width,Drawing.pixels(line.h))
+    love.graphics.rectangle('line', State.left,line.y, State.width,Drawing.pixels(line.h))
     if icon[State.current_drawing_mode] then
-      icon[State.current_drawing_mode](App.screen.width-State.margin_right-22, line.y+4)
+      icon[State.current_drawing_mode](State.right-22, line.y+4)
     else
-      icon[State.previous_drawing_mode](App.screen.width-State.margin_right-22, line.y+4)
+      icon[State.previous_drawing_mode](State.right-22, line.y+4)
     end
 
     if App.mouse_down(1) and love.keyboard.isDown('h') then
@@ -26,7 +26,7 @@ function Drawing.draw(State, line)
     return
   end
 
-  local mx,my = Drawing.coord(pmx-State.margin_left), Drawing.coord(pmy-line.y)
+  local mx,my = Drawing.coord(pmx-State.left), Drawing.coord(pmy-line.y)
 
   for _,shape in ipairs(line.shapes) do
     assert(shape)
@@ -35,20 +35,20 @@ function Drawing.draw(State, line)
     else
       App.color(Stroke_color)
     end
-    Drawing.draw_shape(State.margin_left,line.y, line, shape)
+    Drawing.draw_shape(State.left,line.y, line, shape)
   end
   for i,p in ipairs(line.points) do
     if p.deleted == nil then
       if Drawing.near(p, mx,my) then
         App.color(Focus_stroke_color)
-        love.graphics.circle('line', Drawing.pixels(p.x)+State.margin_left,Drawing.pixels(p.y)+line.y, 4)
+        love.graphics.circle('line', Drawing.pixels(p.x)+State.left,Drawing.pixels(p.y)+line.y, 4)
       else
         App.color(Stroke_color)
-        love.graphics.circle('fill', Drawing.pixels(p.x)+State.margin_left,Drawing.pixels(p.y)+line.y, 2)
+        love.graphics.circle('fill', Drawing.pixels(p.x)+State.left,Drawing.pixels(p.y)+line.y, 2)
       end
       if p.name then
         -- TODO: clip
-        local x,y = Drawing.pixels(p.x)+State.margin_left+5, Drawing.pixels(p.y)+line.y+5
+        local x,y = Drawing.pixels(p.x)+State.left+5, Drawing.pixels(p.y)+line.y+5
         love.graphics.print(p.name, x,y)
         if State.current_drawing_mode == 'name' and i == line.pending.target_point then
           -- create a faint red box for the name
@@ -66,7 +66,7 @@ function Drawing.draw(State, line)
     end
   end
   App.color(Current_stroke_color)
-  Drawing.draw_pending_shape(State.margin_left,line.y, line)
+  Drawing.draw_pending_shape(State.left,line.y, line)
 end
 
 function Drawing.draw_shape(left,top, drawing, shape)
@@ -204,20 +204,20 @@ end
 
 function Drawing.in_drawing(drawing, x,y)
   if drawing.y == nil then return false end  -- outside current page
-  return y >= drawing.y and y < drawing.y + Drawing.pixels(drawing.h) and x >= Editor_state.margin_left and x < App.screen.width-Editor_state.margin_right
+  return y >= drawing.y and y < drawing.y + Drawing.pixels(drawing.h) and x >= Editor_state.left and x < Editor_state.right
 end
 
 function Drawing.mouse_pressed(State, drawing, x,y, button)
   if State.current_drawing_mode == 'freehand' then
-    drawing.pending = {mode=State.current_drawing_mode, points={{x=Drawing.coord(x-State.margin_left), y=Drawing.coord(y-drawing.y)}}}
+    drawing.pending = {mode=State.current_drawing_mode, points={{x=Drawing.coord(x-State.left), y=Drawing.coord(y-drawing.y)}}}
   elseif State.current_drawing_mode == 'line' or State.current_drawing_mode == 'manhattan' then
-    local j = Drawing.insert_point(drawing.points, Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y))
+    local j = Drawing.insert_point(drawing.points, Drawing.coord(x-State.left), Drawing.coord(y-drawing.y))
     drawing.pending = {mode=State.current_drawing_mode, p1=j}
   elseif State.current_drawing_mode == 'polygon' or State.current_drawing_mode == 'rectangle' or State.current_drawing_mode == 'square' then
-    local j = Drawing.insert_point(drawing.points, Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y))
+    local j = Drawing.insert_point(drawing.points, Drawing.coord(x-State.left), Drawing.coord(y-drawing.y))
     drawing.pending = {mode=State.current_drawing_mode, vertices={j}}
   elseif State.current_drawing_mode == 'circle' then
-    local j = Drawing.insert_point(drawing.points, Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y))
+    local j = Drawing.insert_point(drawing.points, Drawing.coord(x-State.left), Drawing.coord(y-drawing.y))
     drawing.pending = {mode=State.current_drawing_mode, center=j}
   elseif State.current_drawing_mode == 'move' then
     -- all the action is in mouse_released
@@ -238,9 +238,9 @@ function Drawing.update(State)
   if App.mouse_down(1) then
     if Drawing.in_drawing(drawing, x,y) then
       if drawing.pending.mode == 'freehand' then
-        table.insert(drawing.pending.points, {x=Drawing.coord(App.mouse_x()-State.margin_left), y=Drawing.coord(App.mouse_y()-drawing.y)})
+        table.insert(drawing.pending.points, {x=Drawing.coord(App.mouse_x()-State.left), y=Drawing.coord(App.mouse_y()-drawing.y)})
       elseif drawing.pending.mode == 'move' then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         drawing.pending.target_point.x = mx
         drawing.pending.target_point.y = my
         Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
@@ -248,7 +248,7 @@ function Drawing.update(State)
     end
   elseif State.current_drawing_mode == 'move' then
     if Drawing.in_drawing(drawing, x, y) then
-      local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+      local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
       drawing.pending.target_point.x = mx
       drawing.pending.target_point.y = my
       Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
@@ -294,14 +294,14 @@ function Drawing.mouse_released(State, x,y, button)
         Drawing.smoothen(drawing.pending)
         table.insert(drawing.shapes, drawing.pending)
       elseif drawing.pending.mode == 'line' then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           drawing.pending.p2 = Drawing.insert_point(drawing.points, mx,my)
           table.insert(drawing.shapes, drawing.pending)
         end
       elseif drawing.pending.mode == 'manhattan' then
         local p1 = drawing.points[drawing.pending.p1]
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           if math.abs(mx-p1.x) > math.abs(my-p1.y) then
             drawing.pending.p2 = Drawing.insert_point(drawing.points, mx, p1.y)
@@ -309,11 +309,11 @@ function Drawing.mouse_released(State, x,y, button)
             drawing.pending.p2 = Drawing.insert_point(drawing.points, p1.x, my)
           end
           local p2 = drawing.points[drawing.pending.p2]
-          App.mouse_move(State.margin_left+Drawing.pixels(p2.x), drawing.y+Drawing.pixels(p2.y))
+          App.mouse_move(State.left+Drawing.pixels(p2.x), drawing.y+Drawing.pixels(p2.y))
           table.insert(drawing.shapes, drawing.pending)
         end
       elseif drawing.pending.mode == 'polygon' then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           table.insert(drawing.pending.vertices, Drawing.insert_point(drawing.points, mx,my))
           table.insert(drawing.shapes, drawing.pending)
@@ -321,7 +321,7 @@ function Drawing.mouse_released(State, x,y, button)
       elseif drawing.pending.mode == 'rectangle' then
         assert(#drawing.pending.vertices <= 2)
         if #drawing.pending.vertices == 2 then
-          local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+          local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
           if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
             local first = drawing.points[drawing.pending.vertices[1]]
             local second = drawing.points[drawing.pending.vertices[2]]
@@ -336,7 +336,7 @@ function Drawing.mouse_released(State, x,y, button)
       elseif drawing.pending.mode == 'square' then
         assert(#drawing.pending.vertices <= 2)
         if #drawing.pending.vertices == 2 then
-          local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+          local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
           if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
             local first = drawing.points[drawing.pending.vertices[1]]
             local second = drawing.points[drawing.pending.vertices[2]]
@@ -347,14 +347,14 @@ function Drawing.mouse_released(State, x,y, button)
           end
         end
       elseif drawing.pending.mode == 'circle' then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           local center = drawing.points[drawing.pending.center]
           drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
           table.insert(drawing.shapes, drawing.pending)
         end
       elseif drawing.pending.mode == 'arc' then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           local center = drawing.points[drawing.pending.center]
           drawing.pending.end_angle = geom.angle_with_hint(center.x,center.y, mx,my, drawing.pending.end_angle)
@@ -460,12 +460,12 @@ function Drawing.keychord_pressed(State, chord)
     drawing.pending.mode = 'square'
   elseif App.mouse_down(1) and chord == 'p' and State.current_drawing_mode == 'polygon' then
     local _,drawing = Drawing.current_drawing(State)
-    local mx,my = Drawing.coord(App.mouse_x()-State.margin_left), Drawing.coord(App.mouse_y()-drawing.y)
+    local mx,my = Drawing.coord(App.mouse_x()-State.left), Drawing.coord(App.mouse_y()-drawing.y)
     local j = Drawing.insert_point(drawing.points, mx,my)
     table.insert(drawing.pending.vertices, j)
   elseif App.mouse_down(1) and chord == 'p' and (State.current_drawing_mode == 'rectangle' or State.current_drawing_mode == 'square') then
     local _,drawing = Drawing.current_drawing(State)
-    local mx,my = Drawing.coord(App.mouse_x()-State.margin_left), Drawing.coord(App.mouse_y()-drawing.y)
+    local mx,my = Drawing.coord(App.mouse_x()-State.left), Drawing.coord(App.mouse_y()-drawing.y)
     local j = Drawing.insert_point(drawing.points, mx,my)
     while #drawing.pending.vertices >= 2 do
       table.remove(drawing.pending.vertices)
@@ -476,7 +476,7 @@ function Drawing.keychord_pressed(State, chord)
   elseif App.mouse_down(1) and chord == 'a' and State.current_drawing_mode == 'circle' then
     local _,drawing = Drawing.current_drawing(State)
     drawing.pending.mode = 'arc'
-    local mx,my = Drawing.coord(App.mouse_x()-State.margin_left), Drawing.coord(App.mouse_y()-drawing.y)
+    local mx,my = Drawing.coord(App.mouse_x()-State.left), Drawing.coord(App.mouse_y()-drawing.y)
     local center = drawing.points[drawing.pending.center]
     drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
     drawing.pending.start_angle = geom.angle(center.x,center.y, mx,my)
@@ -614,7 +614,7 @@ function Drawing.select_shape_at_mouse(State)
     if drawing.mode == 'drawing' then
       local x, y = App.mouse_x(), App.mouse_y()
       if Drawing.in_drawing(drawing, x,y) then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         for i,shape in ipairs(drawing.shapes) do
           assert(shape)
           if geom.on_shape(mx,my, drawing, shape) then
@@ -631,7 +631,7 @@ function Drawing.select_point_at_mouse(State)
     if drawing.mode == 'drawing' then
       local x, y = App.mouse_x(), App.mouse_y()
       if Drawing.in_drawing(drawing, x,y) then
-        local mx,my = Drawing.coord(x-State.margin_left), Drawing.coord(y-drawing.y)
+        local mx,my = Drawing.coord(x-State.left), Drawing.coord(y-drawing.y)
         for i,point in ipairs(drawing.points) do
           assert(point)
           if Drawing.near(point, mx,my) then
@@ -700,14 +700,14 @@ end
 function Drawing.near(point, x,y)
   local px,py = Drawing.pixels(x),Drawing.pixels(y)
   local cx,cy = Drawing.pixels(point.x), Drawing.pixels(point.y)
-  return (cx-px)*(cx-px) + (cy-py)*(cy-py) < Editor_state.margin_left
+  return (cx-px)*(cx-px) + (cy-py)*(cy-py) < Editor_state.left
 end
 
 function Drawing.pixels(n)  -- parts to pixels
-  return math.floor(n*(App.screen.width-Editor_state.margin_width)/256)
+  return math.floor(n*Editor_state.width/256)
 end
 function Drawing.coord(n)  -- pixels to parts
-  return math.floor(n*256/(App.screen.width-Editor_state.margin_width))
+  return math.floor(n*256/Editor_state.width)
 end
 
 function table.find(h, x)
diff --git a/drawing_tests.lua b/drawing_tests.lua
index 9f3889d..96e4bd8 100644
--- a/drawing_tests.lua
+++ b/drawing_tests.lua
@@ -5,11 +5,12 @@
 function test_creating_drawing_saves()
   io.write('\ntest_creating_drawing_saves')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.filename = 'foo'
   Editor_state.lines = load_array{}
   edit.draw(Editor_state)
   -- click on button to create drawing
-  edit.run_after_mouse_click(Editor_state, 8,Editor_state.margin_top+8, 1)
+  edit.run_after_mouse_click(Editor_state, 8,Editor_state.top+8, 1)
   -- file not immediately saved
   App.update(0.01)
   check_nil(App.filesystem['foo'], 'F - test_creating_drawing_saves/early')
@@ -24,18 +25,19 @@ function test_draw_line()
   io.write('\ntest_draw_line')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 2, 'F - test_draw_line/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_line/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_line/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_line/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_line/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_line/baseline/#shapes')
   -- draw a line
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_line/#shapes')
   check_eq(#drawing.points, 2, 'F - test_draw_line/#points')
@@ -67,18 +69,19 @@ end
 function test_draw_horizontal_line()
   io.write('\ntest_draw_horizontal_line')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'manhattan'
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 2, 'F - test_draw_horizontal_line/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_horizontal_line/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_horizontal_line/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_horizontal_line/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_horizontal_line/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_horizontal_line/baseline/#shapes')
   -- draw a line that is more horizontal than vertical
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_horizontal_line/#shapes')
   check_eq(#drawing.points, 2, 'F - test_draw_horizontal_line/#points')
@@ -94,20 +97,21 @@ end
 function test_draw_circle()
   io.write('\ntest_draw_circle')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 2, 'F - test_draw_circle/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_circle/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_circle/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_circle/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_circle/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_circle/baseline/#shapes')
   -- draw a circle
-  App.mouse_move(Editor_state.margin_left+4, Editor_state.margin_top+Editor_state.drawing_padding_top+4)  -- hover on drawing
+  App.mouse_move(Editor_state.left+4, Editor_state.top+Editor_state.drawing_padding_top+4)  -- hover on drawing
   edit.run_after_keychord(Editor_state, 'C-o')
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35+30, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35+30, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_circle/#shapes')
   check_eq(#drawing.points, 1, 'F - test_draw_circle/#points')
@@ -122,20 +126,21 @@ function test_cancel_stroke()
   io.write('\ntest_cancel_stroke')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 2, 'F - test_cancel_stroke/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_cancel_stroke/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_cancel_stroke/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_cancel_stroke/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_cancel_stroke/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_cancel_stroke/baseline/#shapes')
   -- start drawing a line
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
   -- cancel
   edit.run_after_keychord(Editor_state, 'escape')
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 0, 'F - test_cancel_stroke/#shapes')
 end
@@ -143,12 +148,13 @@ end
 function test_keys_do_not_affect_shape_when_mouse_up()
   io.write('\ntest_keys_do_not_affect_shape_when_mouse_up')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   -- hover over drawing and press 'o' without holding mouse
-  App.mouse_move(Editor_state.margin_left+4, Editor_state.margin_top+Editor_state.drawing_padding_top+4)  -- hover on drawing
+  App.mouse_move(Editor_state.left+4, Editor_state.top+Editor_state.drawing_padding_top+4)  -- hover on drawing
   edit.run_after_keychord(Editor_state, 'o')
   -- no change to drawing mode
   check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_keys_do_not_affect_shape_when_mouse_up/drawing_mode')
@@ -158,20 +164,21 @@ end
 function test_draw_circle_mid_stroke()
   io.write('\ntest_draw_circle_mid_stroke')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 2, 'F - test_draw_circle_mid_stroke/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_circle_mid_stroke/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_circle_mid_stroke/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_circle_mid_stroke/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_circle_mid_stroke/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_circle_mid_stroke/baseline/#shapes')
   -- draw a circle
-  App.mouse_move(Editor_state.margin_left+4, Editor_state.margin_top+Editor_state.drawing_padding_top+4)  -- hover on drawing
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  App.mouse_move(Editor_state.left+4, Editor_state.top+Editor_state.drawing_padding_top+4)  -- hover on drawing
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   edit.run_after_keychord(Editor_state, 'o')
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35+30, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35+30, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_circle_mid_stroke/#shapes')
   check_eq(#drawing.points, 1, 'F - test_draw_circle_mid_stroke/#points')
@@ -185,20 +192,21 @@ end
 function test_draw_arc()
   io.write('\ntest_draw_arc')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'circle'
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 2, 'F - test_draw_arc/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_arc/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_arc/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_arc/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_arc/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_arc/baseline/#shapes')
   -- draw an arc
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  App.mouse_move(Editor_state.margin_left+35+30, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  App.mouse_move(Editor_state.left+35+30, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'a')  -- arc mode
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35+50, Editor_state.margin_top+Editor_state.drawing_padding_top+36+50, 1)  -- 45°
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35+50, Editor_state.top+Editor_state.drawing_padding_top+36+50, 1)  -- 45°
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_arc/#shapes')
   check_eq(#drawing.points, 1, 'F - test_draw_arc/#points')
@@ -215,23 +223,24 @@ end
 function test_draw_polygon()
   io.write('\ntest_draw_polygon')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   edit.draw(Editor_state)
   check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_polygon/baseline/drawing_mode')
   check_eq(#Editor_state.lines, 2, 'F - test_draw_polygon/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_polygon/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_polygon/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_polygon/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_polygon/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_polygon/baseline/#shapes')
   -- first point
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
   edit.run_after_keychord(Editor_state, 'g')  -- polygon mode
   -- second point
-  App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  App.mouse_move(Editor_state.left+65, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'p')  -- add point
   -- final point
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_polygon/#shapes')
   check_eq(#drawing.points, 3, 'F - test_draw_polygon/vertices')
@@ -252,26 +261,27 @@ end
 function test_draw_rectangle()
   io.write('\ntest_draw_rectangle')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   edit.draw(Editor_state)
   check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_rectangle/baseline/drawing_mode')
   check_eq(#Editor_state.lines, 2, 'F - test_draw_rectangle/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_rectangle/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_rectangle/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_rectangle/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_rectangle/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_rectangle/baseline/#shapes')
   -- first point
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   edit.run_after_keychord(Editor_state, 'r')  -- rectangle mode
   -- second point/first edge
-  App.mouse_move(Editor_state.margin_left+42, Editor_state.margin_top+Editor_state.drawing_padding_top+45)
+  App.mouse_move(Editor_state.left+42, Editor_state.top+Editor_state.drawing_padding_top+45)
   edit.run_after_keychord(Editor_state, 'p')
   -- override second point/first edge
-  App.mouse_move(Editor_state.margin_left+75, Editor_state.margin_top+Editor_state.drawing_padding_top+76)
+  App.mouse_move(Editor_state.left+75, Editor_state.top+Editor_state.drawing_padding_top+76)
   edit.run_after_keychord(Editor_state, 'p')
   -- release (decides 'thickness' of rectangle perpendicular to first edge)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+15, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+15, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_rectangle/#shapes')
   check_eq(#drawing.points, 5, 'F - test_draw_rectangle/#points')  -- currently includes every point added
@@ -295,23 +305,24 @@ end
 function test_draw_rectangle_intermediate()
   io.write('\ntest_draw_rectangle_intermediate')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   edit.draw(Editor_state)
   check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_rectangle_intermediate/baseline/drawing_mode')
   check_eq(#Editor_state.lines, 2, 'F - test_draw_rectangle_intermediate/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_rectangle_intermediate/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_rectangle_intermediate/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_rectangle_intermediate/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_rectangle_intermediate/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_rectangle_intermediate/baseline/#shapes')
   -- first point
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   edit.run_after_keychord(Editor_state, 'r')  -- rectangle mode
   -- second point/first edge
-  App.mouse_move(Editor_state.margin_left+42, Editor_state.margin_top+Editor_state.drawing_padding_top+45)
+  App.mouse_move(Editor_state.left+42, Editor_state.top+Editor_state.drawing_padding_top+45)
   edit.run_after_keychord(Editor_state, 'p')
   -- override second point/first edge
-  App.mouse_move(Editor_state.margin_left+75, Editor_state.margin_top+Editor_state.drawing_padding_top+76)
+  App.mouse_move(Editor_state.left+75, Editor_state.top+Editor_state.drawing_padding_top+76)
   edit.run_after_keychord(Editor_state, 'p')
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.points, 3, 'F - test_draw_rectangle_intermediate/#points')  -- currently includes every point added
@@ -330,26 +341,27 @@ end
 function test_draw_square()
   io.write('\ntest_draw_square')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   edit.draw(Editor_state)
   check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_square/baseline/drawing_mode')
   check_eq(#Editor_state.lines, 2, 'F - test_draw_square/baseline/#lines')
   check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_square/baseline/mode')
-  check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_square/baseline/y')
+  check_eq(Editor_state.lines[1].y, Editor_state.top+Editor_state.drawing_padding_top, 'F - test_draw_square/baseline/y')
   check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_square/baseline/y')
   check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_square/baseline/#shapes')
   -- first point
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   edit.run_after_keychord(Editor_state, 's')  -- square mode
   -- second point/first edge
-  App.mouse_move(Editor_state.margin_left+42, Editor_state.margin_top+Editor_state.drawing_padding_top+45)
+  App.mouse_move(Editor_state.left+42, Editor_state.top+Editor_state.drawing_padding_top+45)
   edit.run_after_keychord(Editor_state, 'p')
   -- override second point/first edge
-  App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+66)
+  App.mouse_move(Editor_state.left+65, Editor_state.top+Editor_state.drawing_padding_top+66)
   edit.run_after_keychord(Editor_state, 'p')
   -- release (decides which side of first edge to draw square on)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+15, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+15, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_draw_square/#shapes')
   check_eq(#drawing.points, 5, 'F - test_draw_square/#points')  -- currently includes every point added
@@ -373,13 +385,14 @@ function test_name_point()
   io.write('\ntest_name_point')
   -- create a drawing with a line
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   -- draw a line
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_name_point/baseline/#shapes')
   check_eq(#drawing.points, 2, 'F - test_name_point/baseline/#points')
@@ -415,12 +428,13 @@ function test_move_point()
   io.write('\ntest_move_point')
   -- create a drawing with a line
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_move_point/baseline/#shapes')
   check_eq(#drawing.points, 2, 'F - test_move_point/baseline/#points')
@@ -448,13 +462,13 @@ function test_move_point()
   check_eq(drawing.pending.mode, 'move', 'F - test_move_point/mode:2')
   check_eq(drawing.pending.target_point, p2, 'F - test_move_point/target')
   -- move point
-  App.mouse_move(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44)
+  App.mouse_move(Editor_state.left+26, Editor_state.top+Editor_state.drawing_padding_top+44)
   App.update(0.05)
   local p2 = drawing.points[drawing.shapes[1].p2]
   check_eq(p2.x, 26, 'F - test_move_point/x')
   check_eq(p2.y, 44, 'F - test_move_point/y')
   -- exit 'move' mode
-  edit.run_after_mouse_click(Editor_state, Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44, 1)
+  edit.run_after_mouse_click(Editor_state, Editor_state.left+26, Editor_state.top+Editor_state.drawing_padding_top+44, 1)
   check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_move_point/mode:3')
   check_eq(drawing.pending, {}, 'F - test_move_point/pending')
   -- wait until save
@@ -471,12 +485,13 @@ function test_move_point_on_manhattan_line()
   io.write('\ntest_move_point_on_manhattan_line')
   -- create a drawing with a manhattan line
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'manhattan'
   edit.draw(Editor_state)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+46, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+46, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_move_point_on_manhattan_line/baseline/#shapes')
   check_eq(#drawing.points, 2, 'F - test_move_point_on_manhattan_line/baseline/#points')
@@ -486,7 +501,7 @@ function test_move_point_on_manhattan_line()
   edit.run_after_keychord(Editor_state, 'C-u')
   check_eq(Editor_state.current_drawing_mode, 'move', 'F - test_move_point_on_manhattan_line/mode:1')
   -- move point
-  App.mouse_move(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44)
+  App.mouse_move(Editor_state.left+26, Editor_state.top+Editor_state.drawing_padding_top+44)
   App.update(0.05)
   -- line is no longer manhattan
   check_eq(drawing.shapes[1].mode, 'line', 'F - test_move_point_on_manhattan_line/baseline/shape:1')
@@ -496,20 +511,21 @@ function test_delete_lines_at_point()
   io.write('\ntest_delete_lines_at_point')
   -- create a drawing with two lines connected at a point
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+55, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+55, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 2, 'F - test_delete_lines_at_point/baseline/#shapes')
   check_eq(drawing.shapes[1].mode, 'line', 'F - test_delete_lines_at_point/baseline/shape:1')
   check_eq(drawing.shapes[2].mode, 'line', 'F - test_delete_lines_at_point/baseline/shape:2')
   -- hover on the common point and delete
-  App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  App.mouse_move(Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'C-d')
   check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_lines_at_point/shape:1')
   check_eq(drawing.shapes[2].mode, 'deleted', 'F - test_delete_lines_at_point/shape:2')
@@ -524,20 +540,21 @@ end
 function test_delete_line_under_mouse_pointer()
   io.write('\ntest_delete_line_under_mouse_pointer')
   -- create a drawing with two lines connected at a point
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+55, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+55, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 2, 'F - test_delete_line_under_mouse_pointer/baseline/#shapes')
   check_eq(drawing.shapes[1].mode, 'line', 'F - test_delete_line_under_mouse_pointer/baseline/shape:1')
   check_eq(drawing.shapes[2].mode, 'line', 'F - test_delete_line_under_mouse_pointer/baseline/shape:2')
   -- hover on one of the lines and delete
-  App.mouse_move(Editor_state.margin_left+25, Editor_state.margin_top+Editor_state.drawing_padding_top+26)
+  App.mouse_move(Editor_state.left+25, Editor_state.top+Editor_state.drawing_padding_top+26)
   edit.run_after_keychord(Editor_state, 'C-d')
   -- only that line is deleted
   check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_line_under_mouse_pointer/shape:1')
@@ -547,27 +564,28 @@ end
 function test_delete_point_from_polygon()
   io.write('\ntest_delete_point_from_polygon')
   -- create a drawing with two lines connected at a point
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   -- first point
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
   edit.run_after_keychord(Editor_state, 'g')  -- polygon mode
   -- second point
-  App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  App.mouse_move(Editor_state.left+65, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'p')  -- add point
   -- third point
-  App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26)
+  App.mouse_move(Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+26)
   edit.run_after_keychord(Editor_state, 'p')  -- add point
   -- fourth point
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+14, Editor_state.margin_top+Editor_state.drawing_padding_top+16, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+14, Editor_state.top+Editor_state.drawing_padding_top+16, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_delete_point_from_polygon/baseline/#shapes')
   check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/baseline/mode')
   check_eq(#drawing.shapes[1].vertices, 4, 'F - test_delete_point_from_polygon/baseline/vertices')
   -- hover on a point and delete
-  App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26)
+  App.mouse_move(Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+26)
   edit.run_after_keychord(Editor_state, 'C-d')
   -- just the one point is deleted
   check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/shape')
@@ -577,24 +595,25 @@ end
 function test_delete_point_from_polygon()
   io.write('\ntest_delete_point_from_polygon')
   -- create a drawing with two lines connected at a point
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   -- first point
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
   edit.run_after_keychord(Editor_state, 'g')  -- polygon mode
   -- second point
-  App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  App.mouse_move(Editor_state.left+65, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'p')  -- add point
   -- third point
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+14, Editor_state.margin_top+Editor_state.drawing_padding_top+16, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+14, Editor_state.top+Editor_state.drawing_padding_top+16, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_delete_point_from_polygon/baseline/#shapes')
   check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/baseline/mode')
   check_eq(#drawing.shapes[1].vertices, 3, 'F - test_delete_point_from_polygon/baseline/vertices')
   -- hover on a point and delete
-  App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  App.mouse_move(Editor_state.left+65, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'C-d')
   -- there's < 3 points left, so the whole polygon is deleted
   check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_point_from_polygon')
@@ -604,13 +623,14 @@ function test_undo_name_point()
   io.write('\ntest_undo_name_point')
   -- create a drawing with a line
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
   -- draw a line
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_undo_name_point/baseline/#shapes')
   check_eq(#drawing.points, 2, 'F - test_undo_name_point/baseline/#points')
@@ -649,12 +669,13 @@ function test_undo_move_point()
   io.write('\ntest_undo_move_point')
   -- create a drawing with a line
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 1, 'F - test_undo_move_point/baseline/#shapes')
   check_eq(#drawing.points, 2, 'F - test_undo_move_point/baseline/#points')
@@ -668,13 +689,13 @@ function test_undo_move_point()
   check_nil(p2.name, 'F - test_undo_move_point/baseline/p2:name')
   -- move p2
   edit.run_after_keychord(Editor_state, 'C-u')
-  App.mouse_move(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44)
+  App.mouse_move(Editor_state.left+26, Editor_state.top+Editor_state.drawing_padding_top+44)
   App.update(0.05)
   local p2 = drawing.points[drawing.shapes[1].p2]
   check_eq(p2.x, 26, 'F - test_undo_move_point/x')
   check_eq(p2.y, 44, 'F - test_undo_move_point/y')
   -- exit 'move' mode
-  edit.run_after_mouse_click(Editor_state, Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44, 1)
+  edit.run_after_mouse_click(Editor_state, Editor_state.left+26, Editor_state.top+Editor_state.drawing_padding_top+44, 1)
   check_eq(Editor_state.next_history, 4, 'F - test_undo_move_point/next_history')
   -- undo
   edit.run_after_keychord(Editor_state, 'C-z')
@@ -698,20 +719,21 @@ function test_undo_delete_point()
   io.write('\ntest_undo_delete_point')
   -- create a drawing with two lines connected at a point
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_width+256, height=300}  -- drawing coordinates 1:1 with pixels
+  App.screen.init{width=Margin_left+256, height=300}  -- drawing coordinates 1:1 with pixels
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   Editor_state.current_drawing_mode = 'line'
   edit.draw(Editor_state)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+55, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+5, Editor_state.top+Editor_state.drawing_padding_top+6, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+55, Editor_state.top+Editor_state.drawing_padding_top+26, 1)
   local drawing = Editor_state.lines[1]
   check_eq(#drawing.shapes, 2, 'F - test_undo_delete_point/baseline/#shapes')
   check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_delete_point/baseline/shape:1')
   check_eq(drawing.shapes[2].mode, 'line', 'F - test_undo_delete_point/baseline/shape:2')
   -- hover on the common point and delete
-  App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
+  App.mouse_move(Editor_state.left+35, Editor_state.top+Editor_state.drawing_padding_top+36)
   edit.run_after_keychord(Editor_state, 'C-d')
   check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_undo_delete_point/shape:1')
   check_eq(drawing.shapes[2].mode, 'deleted', 'F - test_undo_delete_point/shape:2')
diff --git a/edit.lua b/edit.lua
index 2616487..629bae2 100644
--- a/edit.lua
+++ b/edit.lua
@@ -10,6 +10,10 @@ Icon_color = {r=0.7, g=0.7, b=0.7}  -- color of current mode icon in drawings
 Help_color = {r=0, g=0.5, b=0}
 Help_background_color = {r=0, g=0.5, b=0, a=0.1}
 
+Margin_top = 15
+Margin_left = 25
+Margin_right = 25
+
 utf8 = require 'utf8'
 
 require 'file'
@@ -22,7 +26,7 @@ require 'icons'
 edit = {}
 
 -- run in both tests and a real run
-function edit.initialize_state()
+function edit.initialize_state(top, left, right)  -- currently always draws to bottom of screen
   local result = {
     -- a line is either text or a drawing
     -- a text is a table with:
@@ -88,10 +92,10 @@ function edit.initialize_state()
     -- widest possible character width
     em = App.newText(love.graphics.getFont(), 'm'),
 
-    margin_top = 15,
-    margin_left = 25,
-    margin_right = 0,
-    margin_width = nil,
+    top = top,
+    left = left,
+    right = right,
+    width = right-left,
 
     drawing_padding_top = 10,
     drawing_padding_bottom = 10,
@@ -109,7 +113,6 @@ function edit.initialize_state()
     search_text = nil,
     search_backup = nil,  -- stuff to restore when cancelling search
   }
-  result.margin_width = result.margin_left + result.margin_right
   result.drawing_padding_height = result.drawing_padding_top + result.drawing_padding_bottom
   return result
 end  -- App.initialize_state
@@ -119,7 +122,7 @@ function edit.draw(State)
 --?   print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos)
   assert(Text.le1(State.screen_top1, State.cursor1))
   State.cursor_y = -1
-  local y = State.margin_top
+  local y = State.top
 --?   print('== draw')
   for line_index = State.screen_top1.line,#State.lines do
     local line = State.lines[line_index]
@@ -144,7 +147,7 @@ function edit.draw(State)
       })
       if State.search_term == nil then
         if line_index == State.cursor1.line then
-          Text.draw_cursor(State, State.margin_left, y)
+          Text.draw_cursor(State, State.left, y)
         end
       end
       State.screen_bottom1.pos = State.screen_top1.pos
@@ -161,7 +164,7 @@ function edit.draw(State)
         line.startpos = State.screen_top1.pos
       end
 --?       print('text.draw', y, line_index)
-      y, State.screen_bottom1.pos = Text.draw(State, line, line_index, line.starty, State.margin_left, App.screen.width-State.margin_right)
+      y, State.screen_bottom1.pos = Text.draw(State, line, line_index, line.starty, State.left, State.right)
       y = y + State.line_height
 --?       print('=> y', y)
     end
@@ -203,7 +206,7 @@ function edit.mouse_pressed(State, x,y, mouse_button)
 
   for line_index,line in ipairs(State.lines) do
     if line.mode == 'text' then
-      if Text.in_line(State, line, x,y, State.margin_left, App.screen.width-State.margin_right) then
+      if Text.in_line(State, line, x,y, State.left, State.right) then
         -- delicate dance between cursor, selection and old cursor/selection
         -- scenarios:
         --  regular press+release: sets cursor, clears selection
@@ -218,7 +221,7 @@ function edit.mouse_pressed(State, x,y, mouse_button)
         State.mousepress_shift = App.shift_down()
         State.selection1 = {
             line=line_index,
-            pos=Text.to_pos_on_line(State, line, x, y, State.margin_left, App.screen.width-State.margin_right),
+            pos=Text.to_pos_on_line(State, line, x, y, State.left, State.right),
         }
 --?         print('selection', State.selection1.line, State.selection1.pos)
         break
@@ -248,11 +251,11 @@ function edit.mouse_released(State, x,y, mouse_button)
   else
     for line_index,line in ipairs(State.lines) do
       if line.mode == 'text' then
-        if Text.in_line(State, line, x,y, State.margin_left, App.screen.width-State.margin_right) then
+        if Text.in_line(State, line, x,y, State.left, State.right) then
 --?           print('reset selection')
           State.cursor1 = {
               line=line_index,
-              pos=Text.to_pos_on_line(State, line, x, y, State.margin_left, App.screen.width-State.margin_right),
+              pos=Text.to_pos_on_line(State, line, x, y, State.left, State.right),
           }
 --?           print('cursor', State.cursor1.line, State.cursor1.pos)
           if State.mousepress_shift then
@@ -299,7 +302,7 @@ function edit.keychord_pressed(State, chord, key)
       -- (we're not creating any ctrl-shift- or alt-shift- combinations using regular/printable keys)
       (not App.shift_down() or utf8.len(key) == 1) and
       chord ~= 'C-c' and chord ~= 'C-x' and chord ~= 'backspace' and backspace ~= 'delete' and not App.is_cursor_movement(chord) then
-    Text.delete_selection(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.delete_selection(State, State.left, State.right)
   end
   if State.search_term then
     if chord == 'escape' then
@@ -371,7 +374,7 @@ function edit.keychord_pressed(State, chord, key)
     end
   elseif chord == 'C-x' then
     for _,line in ipairs(State.lines) do line.y = nil end  -- just in case we scroll
-    local s = Text.cut_selection(State, State.margin_left, App.screen.width-State.margin_right)
+    local s = Text.cut_selection(State, State.left, State.right)
     if s then
       App.setClipboardText(s)
     end
@@ -392,7 +395,7 @@ function edit.keychord_pressed(State, chord, key)
       end
     end
     if Text.cursor_past_screen_bottom(State) then
-      Text.snap_cursor_to_bottom_of_screen(State, State.margin_left, App.screen.height-State.margin_right)
+      Text.snap_cursor_to_bottom_of_screen(State, State.left, State.right)
     end
     schedule_save(State)
     record_undo_event(State, {before=before, after=snapshot(State, before_line, State.cursor1.line)})
diff --git a/help.lua b/help.lua
index fa75c31..c000fce 100644
--- a/help.lua
+++ b/help.lua
@@ -1,131 +1,131 @@
 function draw_help_without_mouse_pressed(State, drawing)
   App.color(Help_color)
   local y = drawing.y+10
-  love.graphics.print("Things you can do:", State.margin_left+30,y)
+  love.graphics.print("Things you can do:", State.left+30,y)
   y = y + State.line_height
-  love.graphics.print("* Press the mouse button to start drawing a "..current_shape(State), State.margin_left+30,y)
+  love.graphics.print("* Press the mouse button to start drawing a "..current_shape(State), State.left+30,y)
   y = y + State.line_height
-  love.graphics.print("* Hover on a point and press 'ctrl+u' to pick it up and start moving it,", State.margin_left+30,y)
+  love.graphics.print("* Hover on a point and press 'ctrl+u' to pick it up and start moving it,", State.left+30,y)
   y = y + State.line_height
-  love.graphics.print("then press the mouse button to drop it", State.margin_left+30+bullet_indent(),y)
+  love.graphics.print("then press the mouse button to drop it", State.left+30+bullet_indent(),y)
   y = y + State.line_height
-  love.graphics.print("* Hover on a point and press 'ctrl+n', type a name, then press 'enter'", State.margin_left+30,y)
+  love.graphics.print("* Hover on a point and press 'ctrl+n', type a name, then press 'enter'", State.left+30,y)
   y = y + State.line_height
-  love.graphics.print("* Hover on a point or shape and press 'ctrl+d' to delete it", State.margin_left+30,y)
+  love.graphics.print("* Hover on a point or shape and press 'ctrl+d' to delete it", State.left+30,y)
   y = y + State.line_height
   if State.current_drawing_mode ~= 'freehand' then
-    love.graphics.print("* Press 'ctrl+p' to switch to drawing freehand strokes", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+p' to switch to drawing freehand strokes", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'line' then
-    love.graphics.print("* Press 'ctrl+l' to switch to drawing lines", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+l' to switch to drawing lines", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'manhattan' then
-    love.graphics.print("* Press 'ctrl+m' to switch to drawing horizontal/vertical lines", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+m' to switch to drawing horizontal/vertical lines", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'circle' then
-    love.graphics.print("* Press 'ctrl+o' to switch to drawing circles/arcs", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+o' to switch to drawing circles/arcs", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'polygon' then
-    love.graphics.print("* Press 'ctrl+g' to switch to drawing polygons", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+g' to switch to drawing polygons", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'rectangle' then
-    love.graphics.print("* Press 'ctrl+r' to switch to drawing rectangles", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+r' to switch to drawing rectangles", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'square' then
-    love.graphics.print("* Press 'ctrl+s' to switch to drawing squares", State.margin_left+30,y)
+    love.graphics.print("* Press 'ctrl+s' to switch to drawing squares", State.left+30,y)
     y = y + State.line_height
   end
-  love.graphics.print("* Press 'ctrl+=' or 'ctrl+-' to zoom in or out, ctrl+0 to reset zoom", State.margin_left+30,y)
+  love.graphics.print("* Press 'ctrl+=' or 'ctrl+-' to zoom in or out, ctrl+0 to reset zoom", State.left+30,y)
   y = y + State.line_height
-  love.graphics.print("Press 'esc' now to hide this message", State.margin_left+30,y)
+  love.graphics.print("Press 'esc' now to hide this message", State.left+30,y)
   y = y + State.line_height
   App.color(Help_background_color)
-  love.graphics.rectangle('fill', State.margin_left,drawing.y, App.screen.width-State.margin_width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
+  love.graphics.rectangle('fill', State.left,drawing.y, State.width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
 end
 
 function draw_help_with_mouse_pressed(State, drawing)
   App.color(Help_color)
   local y = drawing.y+10
-  love.graphics.print("You're currently drawing a "..current_shape(State, drawing.pending), State.margin_left+30,y)
+  love.graphics.print("You're currently drawing a "..current_shape(State, drawing.pending), State.left+30,y)
   y = y + State.line_height
-  love.graphics.print('Things you can do now:', State.margin_left+30,y)
+  love.graphics.print('Things you can do now:', State.left+30,y)
   y = y + State.line_height
   if State.current_drawing_mode == 'freehand' then
-    love.graphics.print('* Release the mouse button to finish drawing the stroke', State.margin_left+30,y)
+    love.graphics.print('* Release the mouse button to finish drawing the stroke', State.left+30,y)
     y = y + State.line_height
   elseif State.current_drawing_mode == 'line' or State.current_drawing_mode == 'manhattan' then
-    love.graphics.print('* Release the mouse button to finish drawing the line', State.margin_left+30,y)
+    love.graphics.print('* Release the mouse button to finish drawing the line', State.left+30,y)
     y = y + State.line_height
   elseif State.current_drawing_mode == 'circle' then
     if drawing.pending.mode == 'circle' then
-      love.graphics.print('* Release the mouse button to finish drawing the circle', State.margin_left+30,y)
+      love.graphics.print('* Release the mouse button to finish drawing the circle', State.left+30,y)
       y = y + State.line_height
-      love.graphics.print("* Press 'a' to draw just an arc of a circle", State.margin_left+30,y)
+      love.graphics.print("* Press 'a' to draw just an arc of a circle", State.left+30,y)
     else
-      love.graphics.print('* Release the mouse button to finish drawing the arc', State.margin_left+30,y)
+      love.graphics.print('* Release the mouse button to finish drawing the arc', State.left+30,y)
     end
     y = y + State.line_height
   elseif State.current_drawing_mode == 'polygon' then
-    love.graphics.print('* Release the mouse button to finish drawing the polygon', State.margin_left+30,y)
+    love.graphics.print('* Release the mouse button to finish drawing the polygon', State.left+30,y)
     y = y + State.line_height
-    love.graphics.print("* Press 'p' to add a vertex to the polygon", State.margin_left+30,y)
+    love.graphics.print("* Press 'p' to add a vertex to the polygon", State.left+30,y)
     y = y + State.line_height
   elseif State.current_drawing_mode == 'rectangle' then
     if #drawing.pending.vertices < 2 then
-      love.graphics.print("* Press 'p' to add a vertex to the rectangle", State.margin_left+30,y)
+      love.graphics.print("* Press 'p' to add a vertex to the rectangle", State.left+30,y)
       y = y + State.line_height
     else
-      love.graphics.print('* Release the mouse button to finish drawing the rectangle', State.margin_left+30,y)
+      love.graphics.print('* Release the mouse button to finish drawing the rectangle', State.left+30,y)
       y = y + State.line_height
-      love.graphics.print("* Press 'p' to replace the second vertex of the rectangle", State.margin_left+30,y)
+      love.graphics.print("* Press 'p' to replace the second vertex of the rectangle", State.left+30,y)
       y = y + State.line_height
     end
   elseif State.current_drawing_mode == 'square' then
     if #drawing.pending.vertices < 2 then
-      love.graphics.print("* Press 'p' to add a vertex to the square", State.margin_left+30,y)
+      love.graphics.print("* Press 'p' to add a vertex to the square", State.left+30,y)
       y = y + State.line_height
     else
-      love.graphics.print('* Release the mouse button to finish drawing the square', State.margin_left+30,y)
+      love.graphics.print('* Release the mouse button to finish drawing the square', State.left+30,y)
       y = y + State.line_height
-      love.graphics.print("* Press 'p' to replace the second vertex of the square", State.margin_left+30,y)
+      love.graphics.print("* Press 'p' to replace the second vertex of the square", State.left+30,y)
       y = y + State.line_height
     end
   end
-  love.graphics.print("* Press 'esc' then release the mouse button to cancel the current shape", State.margin_left+30,y)
+  love.graphics.print("* Press 'esc' then release the mouse button to cancel the current shape", State.left+30,y)
   y = y + State.line_height
   y = y + State.line_height
   if State.current_drawing_mode ~= 'line' then
-    love.graphics.print("* Press 'l' to switch to drawing lines", State.margin_left+30,y)
+    love.graphics.print("* Press 'l' to switch to drawing lines", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'manhattan' then
-    love.graphics.print("* Press 'm' to switch to drawing horizontal/vertical lines", State.margin_left+30,y)
+    love.graphics.print("* Press 'm' to switch to drawing horizontal/vertical lines", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'circle' then
-    love.graphics.print("* Press 'o' to switch to drawing circles/arcs", State.margin_left+30,y)
+    love.graphics.print("* Press 'o' to switch to drawing circles/arcs", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'polygon' then
-    love.graphics.print("* Press 'g' to switch to drawing polygons", State.margin_left+30,y)
+    love.graphics.print("* Press 'g' to switch to drawing polygons", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'rectangle' then
-    love.graphics.print("* Press 'r' to switch to drawing rectangles", State.margin_left+30,y)
+    love.graphics.print("* Press 'r' to switch to drawing rectangles", State.left+30,y)
     y = y + State.line_height
   end
   if State.current_drawing_mode ~= 'square' then
-    love.graphics.print("* Press 's' to switch to drawing squares", State.margin_left+30,y)
+    love.graphics.print("* Press 's' to switch to drawing squares", State.left+30,y)
     y = y + State.line_height
   end
   App.color(Help_background_color)
-  love.graphics.rectangle('fill', State.margin_left,drawing.y, App.screen.width-State.margin_width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
+  love.graphics.rectangle('fill', State.left,drawing.y, State.width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
 end
 
 function current_shape(State, shape)
diff --git a/main.lua b/main.lua
index cd515ec..7f39cb5 100644
--- a/main.lua
+++ b/main.lua
@@ -14,7 +14,7 @@ Editor_state = {}
 
 -- called both in tests and real run
 function App.initialize_globals()
-  Editor_state = edit.initialize_state()
+  -- tests currently mostly clear their own state
 
   -- resize
   Last_resize_time = nil
@@ -33,7 +33,7 @@ function App.initialize(arg)
   if love.filesystem.getInfo('config') then
     load_settings()
   else
-    load_defaults()
+    initialize_default_settings()
   end
 
   if #arg > 0 then
@@ -60,9 +60,6 @@ function App.initialize(arg)
   end
   love.window.setTitle('lines.love - '..Editor_state.filename)
 
-  Editor_state.margin_right = 25
-  Editor_state.margin_width = Editor_state.margin_left + Editor_state.margin_right
-
   if #arg > 1 then
     print('ignoring commandline args after '..arg[1])
   end
@@ -86,24 +83,34 @@ function load_settings()
   App.screen.flags.minheight = math.min(App.screen.width, 200)
   App.screen.width, App.screen.height = settings.width, settings.height
   love.window.setMode(App.screen.width, App.screen.height, App.screen.flags)
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right)
   Editor_state.filename = settings.filename
-  initialize_font_settings(settings.font_height)
+  Editor_state.font_height = settings.font_height
+  love.graphics.setFont(love.graphics.newFont(Editor_state.font_height))
+  Editor_state.line_height = math.floor(Editor_state.font_height*1.3)
+  Editor_state.em = App.newText(love.graphics.getFont(), 'm')
   Editor_state.screen_top1 = settings.screen_top
   Editor_state.cursor1 = settings.cursor
 end
 
-function load_defaults()
-  initialize_font_settings(20)
-  initialize_window_geometry()
+function initialize_default_settings()
+  local font_height = 20
+  love.graphics.setFont(love.graphics.newFont(font_height))
+  local em = App.newText(love.graphics.getFont(), 'm')
+  initialize_window_geometry(App.width(em))
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right)
+  Editor_state.font_height = font_height
+  Editor_state.line_height = math.floor(font_height*1.3)
+  Editor_state.em = em
 end
 
-function initialize_window_geometry()
+function initialize_window_geometry(em_width)
   -- maximize window
   love.window.setMode(0, 0)  -- maximize
   App.screen.width, App.screen.height, App.screen.flags = love.window.getMode()
-  -- shrink slightly to account for window decoration
-  App.screen.width = 40*App.width(Editor_state.em)
+  -- shrink height slightly to account for window decoration
   App.screen.height = App.screen.height-100
+  App.screen.width = 40*em_width
   App.screen.flags.resizable = true
   App.screen.flags.minwidth = math.min(App.screen.width, 200)
   App.screen.flags.minheight = math.min(App.screen.width, 200)
@@ -115,18 +122,10 @@ function App.resize(w, h)
   App.screen.width, App.screen.height = w, h
   Text.redraw_all(Editor_state)
   Editor_state.selection1 = {}  -- no support for shift drag while we're resizing
-  Text.tweak_screen_top_and_cursor(Editor_state, Editor_state.margin_left, App.screen.height-Editor_state.margin_right)
+  Text.tweak_screen_top_and_cursor(Editor_state, Editor_state.left, Editor_state.right)
   Last_resize_time = App.getTime()
 end
 
-function initialize_font_settings(font_height)
-  Editor_state.font_height = font_height
-  love.graphics.setFont(love.graphics.newFont(Editor_state.font_height))
-  Editor_state.line_height = math.floor(font_height*1.3)
-
-  Editor_state.em = App.newText(love.graphics.getFont(), 'm')
-end
-
 function App.filedropped(file)
   -- first make sure to save edits on any existing file
   if Editor_state.next_save then
diff --git a/main_tests.lua b/main_tests.lua
index 114f3c6..0f5f675 100644
--- a/main_tests.lua
+++ b/main_tests.lua
@@ -1,8 +1,8 @@
 function test_resize_window()
   io.write('\ntest_resize_window')
   Editor_state.filename = 'foo'
-  App.screen.init{width=Editor_state.margin_left+300, height=300}
-  check_eq(App.screen.width, Editor_state.margin_left+300, 'F - test_resize_window/baseline/width')
+  App.screen.init{width=Editor_state.left+300, height=300}
+  check_eq(App.screen.width, Editor_state.left+300, 'F - test_resize_window/baseline/width')
   check_eq(App.screen.height, 300, 'F - test_resize_window/baseline/height')
   App.resize(200, 400)
   check_eq(App.screen.width, 200, 'F - test_resize_window/width')
@@ -12,7 +12,7 @@ end
 
 function test_drop_file()
   io.write('\ntest_drop_file')
-  App.screen.init{width=Editor_state.margin_left+300, height=300}
+  App.screen.init{width=Editor_state.left+300, height=300}
   App.filesystem['foo'] = 'abc\ndef\nghi\n'
   local fake_dropped_file = {
     opened = false,
@@ -39,7 +39,7 @@ end
 
 function test_drop_file_saves_previous()
   io.write('\ntest_drop_file_saves_previous')
-  App.screen.init{width=Editor_state.margin_left+300, height=300}
+  App.screen.init{width=Editor_state.left+300, height=300}
   -- initially editing a file called foo that hasn't been saved to filesystem yet
   Editor_state.lines = load_array{'abc', 'def'}
   Editor_state.filename = 'foo'
diff --git a/search.lua b/search.lua
index 499eb2b..2e86688 100644
--- a/search.lua
+++ b/search.lua
@@ -56,7 +56,7 @@ function Text.search_next(State)
   end
   if Text.lt1(State.cursor1, State.screen_top1) or Text.lt1(State.screen_bottom1, State.cursor1) then
     State.screen_top1.line = State.cursor1.line
-    local _, pos = Text.pos_at_start_of_cursor_screen_line(State, State.margin_left, App.screen.width-State.margin_right)
+    local _, pos = Text.pos_at_start_of_cursor_screen_line(State, State.left, State.right)
     State.screen_top1.pos = pos
   end
 end
@@ -96,7 +96,7 @@ function Text.search_previous(State)
   end
   if Text.lt1(State.cursor1, State.screen_top1) or Text.lt1(State.screen_bottom1, State.cursor1) then
     State.screen_top1.line = State.cursor1.line
-    local _, pos = Text.pos_at_start_of_cursor_screen_line(State, State.margin_left, App.screen.width-State.margin_right)
+    local _, pos = Text.pos_at_start_of_cursor_screen_line(State, State.left, State.right)
     State.screen_top1.pos = pos
   end
 end
diff --git a/text.lua b/text.lua
index 321d52e..2d2ae7a 100644
--- a/text.lua
+++ b/text.lua
@@ -141,8 +141,8 @@ function Text.textinput(State, t)
 --?   print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos)
   Text.insert_at_cursor(State, t)
   if State.cursor_y >= App.screen.height - State.line_height then
-    Text.populate_screen_line_starting_pos(State.lines[State.cursor1.line], State.margin_left, App.screen.width-State.margin_right)
-    Text.snap_cursor_to_bottom_of_screen(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.populate_screen_line_starting_pos(State.lines[State.cursor1.line], State.left, State.right)
+    Text.snap_cursor_to_bottom_of_screen(State, State.left, State.right)
 --?     print('=>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos)
   end
   record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
@@ -165,7 +165,7 @@ function Text.keychord_pressed(State, chord)
     Text.insert_return(State)
     State.selection1 = {}
     if (State.cursor_y + State.line_height) > App.screen.height then
-      Text.snap_cursor_to_bottom_of_screen(State, State.margin_left, App.screen.width-State.margin_right)
+      Text.snap_cursor_to_bottom_of_screen(State, State.left, State.right)
     end
     schedule_save(State)
     record_undo_event(State, {before=before, after=snapshot(State, before_line, State.cursor1.line)})
@@ -174,15 +174,15 @@ function Text.keychord_pressed(State, chord)
 --?     print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos)
     Text.insert_at_cursor(State, '\t')
     if State.cursor_y >= App.screen.height - State.line_height then
-      Text.populate_screen_line_starting_pos(State.lines[State.cursor1.line], State.margin_left, App.screen.width-State.margin_right)
-      Text.snap_cursor_to_bottom_of_screen(State, State.margin_left, App.screen.width-State.margin_right)
+      Text.populate_screen_line_starting_pos(State.lines[State.cursor1.line], State.left, State.right)
+      Text.snap_cursor_to_bottom_of_screen(State, State.left, State.right)
 --?       print('=>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos)
     end
     schedule_save(State)
     record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
   elseif chord == 'backspace' then
     if State.selection1.line then
-      Text.delete_selection(State, State.margin_left, App.screen.width-State.margin_right)
+      Text.delete_selection(State, State.left, State.right)
       schedule_save(State)
       return
     end
@@ -212,8 +212,8 @@ function Text.keychord_pressed(State, chord)
       State.cursor1.line = State.cursor1.line-1
     end
     if Text.lt1(State.cursor1, State.screen_top1) then
-      local top2 = Text.to2(State, State.screen_top1, State.margin_left, App.screen.width-State.margin_right)
-      top2 = Text.previous_screen_line(State, top2, State.margin_left, App.screen.width-State.margin_right)
+      local top2 = Text.to2(State, State.screen_top1, State.left, State.right)
+      top2 = Text.previous_screen_line(State, top2, State.left, State.right)
       State.screen_top1 = Text.to1(State, top2)
       Text.redraw_all(State)  -- if we're scrolling, reclaim all fragments to avoid memory leaks
     end
@@ -223,7 +223,7 @@ function Text.keychord_pressed(State, chord)
     record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
   elseif chord == 'delete' then
     if State.selection1.line then
-      Text.delete_selection(State, State.margin_left, App.screen.width-State.margin_right)
+      Text.delete_selection(State, State.left, State.right)
       schedule_save(State)
       return
     end
@@ -258,43 +258,43 @@ function Text.keychord_pressed(State, chord)
     record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
   --== shortcuts that move the cursor
   elseif chord == 'left' then
-    Text.left(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.left(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'right' then
-    Text.right(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.right(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'S-left' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.left(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.left(State, State.left, State.right)
   elseif chord == 'S-right' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.right(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.right(State, State.left, State.right)
   -- C- hotkeys reserved for drawings, so we'll use M-
   elseif chord == 'M-left' then
-    Text.word_left(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.word_left(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'M-right' then
-    Text.word_right(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.word_right(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'M-S-left' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.word_left(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.word_left(State, State.left, State.right)
   elseif chord == 'M-S-right' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.word_right(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.word_right(State, State.left, State.right)
   elseif chord == 'home' then
     Text.start_of_line(State)
     State.selection1 = {}
   elseif chord == 'end' then
-    Text.end_of_line(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.end_of_line(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'S-home' then
     if State.selection1.line == nil then
@@ -305,39 +305,39 @@ function Text.keychord_pressed(State, chord)
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.end_of_line(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.end_of_line(State, State.left, State.right)
   elseif chord == 'up' then
-    Text.up(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.up(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'down' then
-    Text.down(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.down(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'S-up' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.up(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.up(State, State.left, State.right)
   elseif chord == 'S-down' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.down(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.down(State, State.left, State.right)
   elseif chord == 'pageup' then
-    Text.pageup(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.pageup(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'pagedown' then
-    Text.pagedown(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.pagedown(State, State.left, State.right)
     State.selection1 = {}
   elseif chord == 'S-pageup' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.pageup(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.pageup(State, State.left, State.right)
   elseif chord == 'S-pagedown' then
     if State.selection1.line == nil then
       State.selection1 = {line=State.cursor1.line, pos=State.cursor1.pos}
     end
-    Text.pagedown(State, State.margin_left, App.screen.width-State.margin_right)
+    Text.pagedown(State, State.left, State.right)
   end
 end
 
@@ -357,7 +357,7 @@ function Text.pageup(State, left, right)
   local top2 = Text.to2(State, State.screen_top1, left, right)
 --?   print(App.screen.height)
   local y = App.screen.height - State.line_height
-  while y >= State.margin_top do
+  while y >= State.top do
 --?     print(y, top2.line, top2.screen_line, top2.screen_pos)
     if State.screen_top1.line == 1 and State.screen_top1.pos == 1 then break end
     if State.lines[State.screen_top1.line].mode == 'text' then
@@ -635,7 +635,7 @@ function Text.cursor_at_final_screen_line(State, left, right)
 end
 
 function Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State, left, right)
-  local y = State.margin_top
+  local y = State.top
   while State.cursor1.line <= #State.lines do
     if State.lines[State.cursor1.line].mode == 'text' then
       break
@@ -668,7 +668,7 @@ function Text.snap_cursor_to_bottom_of_screen(State, left, right)
     if top2.line == 1 and top2.screen_line == 1 then break end
     if top2.screen_line > 1 or State.lines[top2.line-1].mode == 'text' then
       local h = State.line_height
-      if y - h < State.margin_top then
+      if y - h < State.top then
         break
       end
       y = y - h
@@ -678,7 +678,7 @@ function Text.snap_cursor_to_bottom_of_screen(State, left, right)
       -- We currently can't draw partial drawings, so either skip it entirely
       -- or not at all.
       local h = State.drawing_padding_height + Drawing.pixels(State.lines[top2.line-1].h)
-      if y - h < State.margin_top then
+      if y - h < State.top then
         break
       end
 --?       print('skipping drawing of height', h)
diff --git a/text_tests.lua b/text_tests.lua
index 5850e5c..9feb14c 100644
--- a/text_tests.lua
+++ b/text_tests.lua
@@ -3,6 +3,7 @@
 function test_initial_state()
   io.write('\ntest_initial_state')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{}
   edit.draw(Editor_state)
   check_eq(#Editor_state.lines, 1, 'F - test_initial_state/#lines')
@@ -15,9 +16,10 @@ end
 function test_click_to_create_drawing()
   io.write('\ntest_click_to_create_drawing')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{}
   edit.draw(Editor_state)
-  edit.run_after_mouse_click(Editor_state, 8,Editor_state.margin_top+8, 1)
+  edit.run_after_mouse_click(Editor_state, 8,Editor_state.top+8, 1)
   -- cursor skips drawing to always remain on text
   check_eq(#Editor_state.lines, 2, 'F - test_click_to_create_drawing/#lines')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_click_to_create_drawing/cursor')
@@ -27,6 +29,7 @@ function test_backspace_to_delete_drawing()
   io.write('\ntest_backspace_to_delete_drawing')
   -- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'```lines', '```', ''}
   -- cursor is on text as always (outside tests this will get initialized correctly)
   Editor_state.cursor1.line = 2
@@ -39,10 +42,11 @@ end
 function test_insert_first_character()
   io.write('\ntest_insert_first_character')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{}
   edit.draw(Editor_state)
   edit.run_after_textinput(Editor_state, 'a')
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'a', 'F - test_insert_first_character/screen:1')
 end
 
@@ -50,6 +54,7 @@ function test_press_ctrl()
   io.write('\ntest_press_ctrl')
   -- press ctrl while the cursor is on text
   App.screen.init{width=50, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{''}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -60,6 +65,7 @@ end
 function test_move_left()
   io.write('\ntest_move_left')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'a'}
   Editor_state.cursor1 = {line=1, pos=2}
   edit.draw(Editor_state)
@@ -70,6 +76,7 @@ end
 function test_move_right()
   io.write('\ntest_move_right')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'a'}
   Editor_state.cursor1 = {line=1, pos=1}
   edit.draw(Editor_state)
@@ -80,6 +87,7 @@ end
 function test_move_left_to_previous_line()
   io.write('\ntest_move_left_to_previous_line')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def'}
   Editor_state.cursor1 = {line=2, pos=1}
   edit.draw(Editor_state)
@@ -91,6 +99,7 @@ end
 function test_move_right_to_next_line()
   io.write('\ntest_move_right_to_next_line')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def'}
   Editor_state.cursor1 = {line=1, pos=4}  -- past end of line
   edit.draw(Editor_state)
@@ -102,6 +111,7 @@ end
 function test_move_to_start_of_word()
   io.write('\ntest_move_to_start_of_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=3}
   edit.draw(Editor_state)
@@ -112,6 +122,7 @@ end
 function test_move_to_start_of_previous_word()
   io.write('\ntest_move_to_start_of_previous_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def'}
   Editor_state.cursor1 = {line=1, pos=4}  -- at the space between words
   edit.draw(Editor_state)
@@ -122,6 +133,7 @@ end
 function test_skip_to_previous_word()
   io.write('\ntest_skip_to_previous_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def'}
   Editor_state.cursor1 = {line=1, pos=5}  -- at the start of second word
   edit.draw(Editor_state)
@@ -132,6 +144,7 @@ end
 function test_skip_past_tab_to_previous_word()
   io.write('\ntest_skip_past_tab_to_previous_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def\tghi'}
   Editor_state.cursor1 = {line=1, pos=10}  -- within third word
   edit.draw(Editor_state)
@@ -142,6 +155,7 @@ end
 function test_skip_multiple_spaces_to_previous_word()
   io.write('\ntest_skip_multiple_spaces_to_previous_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc  def'}
   Editor_state.cursor1 = {line=1, pos=6}  -- at the start of second word
   edit.draw(Editor_state)
@@ -152,6 +166,7 @@ end
 function test_move_to_start_of_word_on_previous_line()
   io.write('\ntest_move_to_start_of_word_on_previous_line')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def', 'ghi'}
   Editor_state.cursor1 = {line=2, pos=1}
   edit.draw(Editor_state)
@@ -163,6 +178,7 @@ end
 function test_move_past_end_of_word()
   io.write('\ntest_move_past_end_of_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def'}
   Editor_state.cursor1 = {line=1, pos=1}
   edit.draw(Editor_state)
@@ -173,6 +189,7 @@ end
 function test_skip_to_next_word()
   io.write('\ntest_skip_to_next_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def'}
   Editor_state.cursor1 = {line=1, pos=4}  -- at the space between words
   edit.draw(Editor_state)
@@ -183,6 +200,7 @@ end
 function test_skip_past_tab_to_next_word()
   io.write('\ntest_skip_past_tab_to_next_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc\tdef'}
   Editor_state.cursor1 = {line=1, pos=1}  -- at the space between words
   edit.draw(Editor_state)
@@ -193,6 +211,7 @@ end
 function test_skip_multiple_spaces_to_next_word()
   io.write('\ntest_skip_multiple_spaces_to_next_word')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc  def'}
   Editor_state.cursor1 = {line=1, pos=4}  -- at the start of second word
   edit.draw(Editor_state)
@@ -203,6 +222,7 @@ end
 function test_move_past_end_of_word_on_next_line()
   io.write('\ntest_move_past_end_of_word_on_next_line')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def', 'ghi'}
   Editor_state.cursor1 = {line=1, pos=8}
   edit.draw(Editor_state)
@@ -215,13 +235,14 @@ function test_click_with_mouse()
   io.write('\ntest_click_with_mouse')
   -- display two lines with cursor on one of them
   App.screen.init{width=50, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   -- click on the other line
   edit.draw(Editor_state)
-  edit.run_after_mouse_click(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
+  edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- cursor moves
   check_eq(Editor_state.cursor1.line, 1, 'F - test_click_with_mouse/cursor')
   check_nil(Editor_state.selection1.line, 'F - test_click_with_mouse/selection is empty to avoid perturbing future edits')
@@ -231,13 +252,14 @@ function test_click_with_mouse_on_empty_line()
   io.write('\ntest_click_with_mouse_on_empty_line')
   -- display two lines with the first one empty
   App.screen.init{width=50, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'', 'def'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   -- click on the empty line
   edit.draw(Editor_state)
-  edit.run_after_mouse_click(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
+  edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- cursor moves
   check_eq(Editor_state.cursor1.line, 1, 'F - test_click_with_mouse_on_empty_line/cursor')
 end
@@ -245,12 +267,13 @@ end
 function test_draw_text()
   io.write('\ntest_draw_text')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_draw_text/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_draw_text/screen:2')
@@ -261,12 +284,13 @@ end
 function test_draw_wrapping_text()
   io.write('\ntest_draw_wrapping_text')
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'defgh', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_draw_wrapping_text/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_draw_wrapping_text/screen:2')
@@ -277,12 +301,13 @@ end
 function test_draw_word_wrapping_text()
   io.write('\ntest_draw_word_wrapping_text')
   App.screen.init{width=60, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def ghi', 'jkl'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc ', 'F - test_draw_word_wrapping_text/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def ', 'F - test_draw_word_wrapping_text/screen:2')
@@ -294,12 +319,13 @@ function test_draw_text_wrapping_within_word()
   -- arrange a screen line that needs to be split within a word
   io.write('\ntest_draw_text_wrapping_within_word')
   App.screen.init{width=60, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abcd e fghijk', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abcd ', 'F - test_draw_text_wrapping_within_word/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'e fghi', 'F - test_draw_text_wrapping_within_word/screen:2')
@@ -311,12 +337,13 @@ function test_draw_wrapping_text_containing_non_ascii()
   -- draw a long line containing non-ASCII
   io.write('\ntest_draw_wrapping_text_containing_non_ascii')
   App.screen.init{width=60, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'madam I’m adam', 'xyz'}  -- notice the non-ASCII apostrophe
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'mada', 'F - test_draw_wrapping_text_containing_non_ascii/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'm I’', 'F - test_draw_wrapping_text_containing_non_ascii/screen:2')
@@ -328,13 +355,14 @@ function test_click_on_wrapping_line()
   io.write('\ntest_click_on_wrapping_line')
   -- display a wrapping line
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
                   --  12345678901234
   Editor_state.lines = load_array{"madam I'm adam"}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'madam ', 'F - test_click_on_wrapping_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, "I'm ada", 'F - test_click_on_wrapping_line/baseline/screen:2')
@@ -350,13 +378,14 @@ function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen()
   io.write('\ntest_click_on_wrapping_line_rendered_from_partway_at_top_of_screen')
   -- display a wrapping line from its second screen line
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
                   --  12345678901234
   Editor_state.lines = load_array{"madam I'm adam"}
   Editor_state.cursor1 = {line=1, pos=8}
   Editor_state.screen_top1 = {line=1, pos=7}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, "I'm ada", 'F - test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen/baseline/screen:2')
   y = y + Editor_state.line_height
   -- click past end of second screen line
@@ -370,13 +399,14 @@ function test_click_past_end_of_wrapping_line()
   io.write('\ntest_click_past_end_of_wrapping_line')
   -- display a wrapping line
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
                   --  12345678901234
   Editor_state.lines = load_array{"madam I'm adam"}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'madam ', 'F - test_click_past_end_of_wrapping_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, "I'm ada", 'F - test_click_past_end_of_wrapping_line/baseline/screen:2')
@@ -393,13 +423,14 @@ function test_click_on_wrapping_line_containing_non_ascii()
   io.write('\ntest_click_on_wrapping_line_containing_non_ascii')
   -- display a wrapping line containing non-ASCII
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
                   --  12345678901234
   Editor_state.lines = load_array{'madam I’m adam'}  -- notice the non-ASCII apostrophe
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'madam ', 'F - test_click_on_wrapping_line_containing_non_ascii/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'I’m ada', 'F - test_click_on_wrapping_line_containing_non_ascii/baseline/screen:2')
@@ -416,6 +447,7 @@ function test_click_past_end_of_word_wrapping_line()
   io.write('\ntest_click_past_end_of_word_wrapping_line')
   -- display a long line wrapping at a word boundary on a screen of more realistic length
   App.screen.init{width=160, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
                    -- 0        1         2
                    -- 123456789012345678901
   Editor_state.lines = load_array{'the quick brown fox jumped over the lazy dog'}
@@ -423,7 +455,7 @@ function test_click_past_end_of_word_wrapping_line()
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'the quick brown fox ', 'F - test_click_past_end_of_word_wrapping_line/baseline/screen:1')
   y = y + Editor_state.line_height
   -- click past the end of the screen line
@@ -436,6 +468,7 @@ function test_select_text()
   io.write('\ntest_select_text')
   -- display a line of text
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -457,6 +490,7 @@ function test_cursor_movement_without_shift_resets_selection()
   io.write('\ntest_cursor_movement_without_shift_resets_selection')
   -- display a line of text with some part selected
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}
@@ -474,6 +508,7 @@ function test_edit_deletes_selection()
   io.write('\ntest_edit_deletes_selection')
   -- display a line of text with some part selected
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}
@@ -490,6 +525,7 @@ function test_edit_with_shift_key_deletes_selection()
   io.write('\ntest_edit_with_shift_key_deletes_selection')
   -- display a line of text with some part selected
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}
@@ -511,6 +547,7 @@ function test_copy_does_not_reset_selection()
   io.write('\ntest_copy_does_not_reset_selection')
   -- display a line of text with a selection
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}
@@ -528,6 +565,7 @@ function test_cut()
   io.write('\ntest_cut')
   -- display a line of text with some part selected
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}
@@ -545,6 +583,7 @@ function test_paste_replaces_selection()
   io.write('\ntest_paste_replaces_selection')
   -- display a line of text with a selection
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.selection1 = {line=1, pos=1}
@@ -564,12 +603,13 @@ function test_deleting_selection_may_scroll()
   io.write('\ntest_deleting_selection_may_scroll')
   -- display lines 2/3/4
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=3, pos=2}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_deleting_selection_may_scroll/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_deleting_selection_may_scroll/baseline/screen:2')
@@ -587,6 +627,7 @@ end
 function test_edit_wrapping_text()
   io.write('\ntest_edit_wrapping_text')
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'xyz'}
   Editor_state.cursor1 = {line=2, pos=4}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -596,7 +637,7 @@ function test_edit_wrapping_text()
   edit.run_after_textinput(Editor_state, 'h')
   edit.run_after_textinput(Editor_state, 'i')
   edit.run_after_textinput(Editor_state, 'j')
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_edit_wrapping_text/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_edit_wrapping_text/screen:2')
@@ -607,13 +648,14 @@ end
 function test_insert_newline()
   io.write('\ntest_insert_newline')
   -- display a few lines
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_insert_newline/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_insert_newline/baseline/screen:2')
@@ -624,7 +666,7 @@ function test_insert_newline()
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_insert_newline/screen_top')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_insert_newline/cursor:line')
   check_eq(Editor_state.cursor1.pos, 1, 'F - test_insert_newline/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'a', 'F - test_insert_newline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'bc', 'F - test_insert_newline/screen:2')
@@ -635,7 +677,8 @@ end
 function test_insert_newline_at_start_of_line()
   io.write('\ntest_insert_newline_at_start_of_line')
   -- display a line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -651,13 +694,14 @@ end
 function test_insert_from_clipboard()
   io.write('\ntest_insert_from_clipboard')
   -- display a few lines
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_insert_from_clipboard/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_insert_from_clipboard/baseline/screen:2')
@@ -669,7 +713,7 @@ function test_insert_from_clipboard()
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_insert_from_clipboard/screen_top')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_insert_from_clipboard/cursor:line')
   check_eq(Editor_state.cursor1.pos, 2, 'F - test_insert_from_clipboard/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'axy', 'F - test_insert_from_clipboard/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'zbc', 'F - test_insert_from_clipboard/screen:2')
@@ -680,13 +724,14 @@ end
 function test_move_cursor_using_mouse()
   io.write('\ntest_move_cursor_using_mouse')
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   Editor_state.selection1 = {}
   edit.draw(Editor_state)  -- populate line.y for each line in Editor_state.lines
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   check_eq(Editor_state.cursor1.line, 1, 'F - test_move_cursor_using_mouse/cursor:line')
   check_eq(Editor_state.cursor1.pos, 2, 'F - test_move_cursor_using_mouse/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_move_cursor_using_mouse/selection:line')
@@ -696,6 +741,7 @@ end
 function test_select_text_using_mouse()
   io.write('\ntest_select_text_using_mouse')
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -703,9 +749,9 @@ function test_select_text_using_mouse()
   Editor_state.selection1 = {}
   edit.draw(Editor_state)  -- populate line.y for each line in Editor_state.lines
   -- press and hold on first location
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- drag and release somewhere else
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+20,Editor_state.margin_top+Editor_state.line_height+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+20,Editor_state.top+Editor_state.line_height+5, 1)
   check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_using_mouse/selection:line')
   check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_using_mouse/selection:pos')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_using_mouse/cursor:line')
@@ -715,6 +761,7 @@ end
 function test_select_text_using_mouse_and_shift()
   io.write('\ntest_select_text_using_mouse_and_shift')
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -722,12 +769,12 @@ function test_select_text_using_mouse_and_shift()
   Editor_state.selection1 = {}
   edit.draw(Editor_state)  -- populate line.y for each line in Editor_state.lines
   -- click on first location
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- hold down shift and click somewhere else
   App.fake_key_press('lshift')
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+20,Editor_state.margin_top+5, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+20,Editor_state.margin_top+Editor_state.line_height+5, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+20,Editor_state.top+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+20,Editor_state.top+Editor_state.line_height+5, 1)
   App.fake_key_release('lshift')
   check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_using_mouse_and_shift/selection:line')
   check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_using_mouse_and_shift/selection:pos')
@@ -738,6 +785,7 @@ end
 function test_select_text_repeatedly_using_mouse_and_shift()
   io.write('\ntest_select_text_repeatedly_using_mouse_and_shift')
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -745,16 +793,16 @@ function test_select_text_repeatedly_using_mouse_and_shift()
   Editor_state.selection1 = {}
   edit.draw(Editor_state)  -- populate line.y for each line in Editor_state.lines
   -- click on first location
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+5, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- hold down shift and click on a second location
   App.fake_key_press('lshift')
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+20,Editor_state.margin_top+5, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+20,Editor_state.margin_top+Editor_state.line_height+5, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+20,Editor_state.top+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+20,Editor_state.top+Editor_state.line_height+5, 1)
   -- hold down shift and click at a third location
   App.fake_key_press('lshift')
-  edit.run_after_mouse_press(Editor_state, Editor_state.margin_left+20,Editor_state.margin_top+5, 1)
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+Editor_state.line_height+5, 1)
+  edit.run_after_mouse_press(Editor_state, Editor_state.left+20,Editor_state.top+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+Editor_state.line_height+5, 1)
   App.fake_key_release('lshift')
   -- selection is between first and third location. forget the second location, not the first.
   check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:line')
@@ -766,7 +814,8 @@ end
 function test_cut_without_selection()
   io.write('\ntest_cut_without_selection')
   -- display a few lines
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -782,13 +831,14 @@ end
 function test_pagedown()
   io.write('\ntest_pagedown')
   App.screen.init{width=120, height=45}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   -- initially the first two lines are displayed
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_pagedown/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_pagedown/baseline/screen:2')
@@ -796,7 +846,7 @@ function test_pagedown()
   edit.run_after_keychord(Editor_state, 'pagedown')
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_pagedown/screen_top')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_pagedown/cursor')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_pagedown/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_pagedown/screen:2')
@@ -806,7 +856,8 @@ function test_pagedown_skips_drawings()
   io.write('\ntest_pagedown_skips_drawings')
   -- some lines of text with a drawing intermixed
   local drawing_width = 50
-  App.screen.init{width=Editor_state.margin_left+drawing_width, height=80}
+  App.screen.init{width=Editor_state.left+drawing_width, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc',               -- height 15
                      '```lines', '```',   -- height 25
                      'def',               -- height 15
@@ -819,14 +870,14 @@ function test_pagedown_skips_drawings()
   -- initially the screen displays the first line and the drawing
   -- 15px margin + 15px line1 + 10px margin + 25px drawing + 10px margin = 75px < screen height 80px
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_pagedown_skips_drawings/baseline/screen:1')
   -- after pagedown the screen draws the drawing up top
   -- 15px margin + 10px margin + 25px drawing + 10px margin + 15px line3 = 75px < screen height 80px
   edit.run_after_keychord(Editor_state, 'pagedown')
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_pagedown_skips_drawings/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_pagedown_skips_drawings/cursor')
-  y = Editor_state.margin_top + drawing_height
+  y = Editor_state.top + drawing_height
   App.screen.check(y, 'def', 'F - test_pagedown_skips_drawings/screen:1')
 end
 
@@ -834,12 +885,13 @@ function test_pagedown_often_shows_start_of_wrapping_line()
   io.write('\ntest_pagedown_often_shows_start_of_wrapping_line')
   -- draw a few lines ending in part of a wrapping line
   App.screen.init{width=50, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def ghi jkl', 'mno'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def ', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:2')
@@ -851,7 +903,7 @@ function test_pagedown_often_shows_start_of_wrapping_line()
   check_eq(Editor_state.screen_top1.pos, 1, 'F - test_pagedown_often_shows_start_of_wrapping_line/screen_top:pos')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_pagedown_often_shows_start_of_wrapping_line/cursor:line')
   check_eq(Editor_state.cursor1.pos, 1, 'F - test_pagedown_often_shows_start_of_wrapping_line/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def ', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi ', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:2')
@@ -862,13 +914,14 @@ end
 function test_pagedown_can_start_from_middle_of_long_wrapping_line()
   io.write('\ntest_pagedown_can_start_from_middle_of_long_wrapping_line')
   -- draw a few lines starting from a very long wrapping line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def ghi jkl mno pqr stu vwx yza bcd efg hij', 'XYZ'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:2')
@@ -878,7 +931,7 @@ function test_pagedown_can_start_from_middle_of_long_wrapping_line()
   edit.run_after_keychord(Editor_state, 'pagedown')
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:line')
   check_eq(Editor_state.screen_top1.pos, 9, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'ghi ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl m', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:2')
@@ -889,13 +942,14 @@ end
 function test_down_arrow_moves_cursor()
   io.write('\ntest_down_arrow_moves_cursor')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   -- initially the first three lines are displayed
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_down_arrow_moves_cursor/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_down_arrow_moves_cursor/baseline/screen:2')
@@ -906,7 +960,7 @@ function test_down_arrow_moves_cursor()
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_down_arrow_moves_cursor/screen_top')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_down_arrow_moves_cursor/cursor')
   -- the screen is unchanged
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_down_arrow_moves_cursor/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_down_arrow_moves_cursor/screen:2')
@@ -918,12 +972,13 @@ function test_down_arrow_scrolls_down_by_one_line()
   io.write('\ntest_down_arrow_scrolls_down_by_one_line')
   -- display the first three lines with the cursor on the bottom line
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=3, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_down_arrow_scrolls_down_by_one_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_line/baseline/screen:2')
@@ -933,7 +988,7 @@ function test_down_arrow_scrolls_down_by_one_line()
   edit.run_after_keychord(Editor_state, 'down')
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_line/screen_top')
   check_eq(Editor_state.cursor1.line, 4, 'F - test_down_arrow_scrolls_down_by_one_line/cursor')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_down_arrow_scrolls_down_by_one_line/screen:2')
@@ -944,13 +999,14 @@ end
 function test_down_arrow_scrolls_down_by_one_screen_line()
   io.write('\ntest_down_arrow_scrolls_down_by_one_screen_line')
   -- display the first three lines with the cursor on the bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.cursor1 = {line=3, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_down_arrow_scrolls_down_by_one_screen_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line/baseline/screen:2')
@@ -961,7 +1017,7 @@ function test_down_arrow_scrolls_down_by_one_screen_line()
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:line')
   check_eq(Editor_state.cursor1.pos, 5, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi ', 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen:2')
@@ -972,13 +1028,14 @@ end
 function test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word()
   io.write('\ntest_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word')
   -- display the first three lines with the cursor on the bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghijkl', 'mno'}
   Editor_state.cursor1 = {line=3, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/baseline/screen:2')
@@ -989,7 +1046,7 @@ function test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/cursor:line')
   check_eq(Editor_state.cursor1.pos, 6, 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghijk', 'F - test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_word/screen:2')
@@ -999,13 +1056,14 @@ end
 
 function test_page_down_followed_by_down_arrow_does_not_scroll_screen_up()
   io.write('\ntest_page_down_followed_by_down_arrow_does_not_scroll_screen_up')
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghijkl', 'mno'}
   Editor_state.cursor1 = {line=3, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/baseline/screen:2')
@@ -1021,7 +1079,7 @@ function test_page_down_followed_by_down_arrow_does_not_scroll_screen_up()
   check_eq(Editor_state.screen_top1.line, 3, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/cursor:line')
   check_eq(Editor_state.cursor1.pos, 6, 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'ghijk', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'l', 'F - test_page_down_followed_by_down_arrow_does_not_scroll_screen_up/screen:2')
@@ -1033,12 +1091,13 @@ function test_up_arrow_moves_cursor()
   io.write('\ntest_up_arrow_moves_cursor')
   -- display the first 3 lines with the cursor on the bottom line
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=3, pos=1}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_up_arrow_moves_cursor/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_up_arrow_moves_cursor/baseline/screen:2')
@@ -1049,7 +1108,7 @@ function test_up_arrow_moves_cursor()
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_moves_cursor/screen_top')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_up_arrow_moves_cursor/cursor')
   -- the screen is unchanged
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_up_arrow_moves_cursor/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_up_arrow_moves_cursor/screen:2')
@@ -1061,12 +1120,13 @@ function test_up_arrow_scrolls_up_by_one_line()
   io.write('\ntest_up_arrow_scrolls_up_by_one_line')
   -- display the lines 2/3/4 with the cursor on line 2
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_by_one_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_by_one_line/baseline/screen:2')
@@ -1076,7 +1136,7 @@ function test_up_arrow_scrolls_up_by_one_line()
   edit.run_after_keychord(Editor_state, 'up')
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_by_one_line/screen_top')
   check_eq(Editor_state.cursor1.line, 1, 'F - test_up_arrow_scrolls_up_by_one_line/cursor')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_up_arrow_scrolls_up_by_one_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_by_one_line/screen:2')
@@ -1087,19 +1147,20 @@ end
 function test_up_arrow_scrolls_up_by_one_screen_line()
   io.write('\ntest_up_arrow_scrolls_up_by_one_screen_line')
   -- display lines starting from second screen line of a line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.cursor1 = {line=3, pos=6}
   Editor_state.screen_top1 = {line=3, pos=5}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_by_one_screen_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_by_one_screen_line/baseline/screen:2')
   -- after hitting the up arrow the screen scrolls up to first screen line
   edit.run_after_keychord(Editor_state, 'up')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'ghi ', 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_by_one_screen_line/screen:2')
@@ -1114,13 +1175,14 @@ end
 function test_up_arrow_scrolls_up_to_final_screen_line()
   io.write('\ntest_up_arrow_scrolls_up_to_final_screen_line')
   -- display lines starting just after a long line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:2')
@@ -1128,7 +1190,7 @@ function test_up_arrow_scrolls_up_to_final_screen_line()
   App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:3')
   -- after hitting the up arrow the screen scrolls up to final screen line of previous line
   edit.run_after_keychord(Editor_state, 'up')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:2')
@@ -1144,12 +1206,13 @@ function test_up_arrow_scrolls_up_to_empty_line()
   io.write('\ntest_up_arrow_scrolls_up_to_empty_line')
   -- display a screenful of text with an empty line just above it outside the screen
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'', 'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_up_arrow_scrolls_up_to_empty_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_to_empty_line/baseline/screen:2')
@@ -1159,7 +1222,7 @@ function test_up_arrow_scrolls_up_to_empty_line()
   edit.run_after_keychord(Editor_state, 'up')
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_to_empty_line/screen_top')
   check_eq(Editor_state.cursor1.line, 1, 'F - test_up_arrow_scrolls_up_to_empty_line/cursor')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   -- empty first line
   y = y + Editor_state.line_height
   App.screen.check(y, 'abc', 'F - test_up_arrow_scrolls_up_to_empty_line/screen:2')
@@ -1170,13 +1233,14 @@ end
 function test_pageup()
   io.write('\ntest_pageup')
   App.screen.init{width=120, height=45}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   -- initially the last two lines are displayed
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_pageup/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_pageup/baseline/screen:2')
@@ -1184,7 +1248,7 @@ function test_pageup()
   edit.run_after_keychord(Editor_state, 'pageup')
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_pageup/screen_top')
   check_eq(Editor_state.cursor1.line, 1, 'F - test_pageup/cursor')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_pageup/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_pageup/screen:2')
@@ -1193,13 +1257,14 @@ end
 function test_pageup_scrolls_up_by_screen_line()
   io.write('\ntest_pageup_scrolls_up_by_screen_line')
   -- display the first three lines with the cursor on the bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'ghi', 'F - test_pageup_scrolls_up_by_screen_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl', 'F - test_pageup_scrolls_up_by_screen_line/baseline/screen:2')
@@ -1210,7 +1275,7 @@ function test_pageup_scrolls_up_by_screen_line()
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_pageup_scrolls_up_by_screen_line/screen_top')
   check_eq(Editor_state.cursor1.line, 1, 'F - test_pageup_scrolls_up_by_screen_line/cursor:line')
   check_eq(Editor_state.cursor1.pos, 1, 'F - test_pageup_scrolls_up_by_screen_line/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc ', 'F - test_pageup_scrolls_up_by_screen_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_pageup_scrolls_up_by_screen_line/screen:2')
@@ -1221,13 +1286,14 @@ end
 function test_pageup_scrolls_up_from_middle_screen_line()
   io.write('\ntest_pageup_scrolls_up_from_middle_screen_line')
   -- display a few lines starting from the middle of a line (Editor_state.cursor1.pos > 1)
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def', 'ghi jkl', 'mno'}
   Editor_state.cursor1 = {line=2, pos=5}
   Editor_state.screen_top1 = {line=2, pos=5}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'jkl', 'F - test_pageup_scrolls_up_from_middle_screen_line/baseline/screen:2')
   y = y + Editor_state.line_height
   App.screen.check(y, 'mno', 'F - test_pageup_scrolls_up_from_middle_screen_line/baseline/screen:3')  -- line wrapping includes trailing whitespace
@@ -1236,7 +1302,7 @@ function test_pageup_scrolls_up_from_middle_screen_line()
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/screen_top')
   check_eq(Editor_state.cursor1.line, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/cursor:line')
   check_eq(Editor_state.cursor1.pos, 1, 'F - test_pageup_scrolls_up_from_middle_screen_line/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc ', 'F - test_pageup_scrolls_up_from_middle_screen_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_pageup_scrolls_up_from_middle_screen_line/screen:2')
@@ -1247,13 +1313,14 @@ end
 function test_enter_on_bottom_line_scrolls_down()
   io.write('\ntest_enter_on_bottom_line_scrolls_down')
   -- display a few lines with cursor on bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=3, pos=2}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_enter_on_bottom_line_scrolls_down/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_enter_on_bottom_line_scrolls_down/baseline/screen:2')
@@ -1264,7 +1331,7 @@ function test_enter_on_bottom_line_scrolls_down()
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_enter_on_bottom_line_scrolls_down/screen_top')
   check_eq(Editor_state.cursor1.line, 4, 'F - test_enter_on_bottom_line_scrolls_down/cursor:line')
   check_eq(Editor_state.cursor1.pos, 1, 'F - test_enter_on_bottom_line_scrolls_down/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_enter_on_bottom_line_scrolls_down/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'g', 'F - test_enter_on_bottom_line_scrolls_down/screen:2')
@@ -1275,20 +1342,21 @@ end
 function test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom()
   io.write('\ntest_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom')
   -- display just the bottom line on screen
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=4, pos=2}
   Editor_state.screen_top1 = {line=4, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'jkl', 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/baseline/screen:1')
   -- after hitting the enter key the screen does not scroll down
   edit.run_after_keychord(Editor_state, 'return')
   check_eq(Editor_state.screen_top1.line, 4, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen_top')
   check_eq(Editor_state.cursor1.line, 5, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:line')
   check_eq(Editor_state.cursor1.pos, 1, 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'j', 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'kl', 'F - test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen:2')
@@ -1297,7 +1365,8 @@ end
 function test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom()
   io.write('\ntest_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom')
   -- display just an empty bottom line on screen
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', ''}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
@@ -1308,20 +1377,21 @@ function test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bot
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen_top')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:line')
   check_eq(Editor_state.cursor1.pos, 2, 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/cursor:pos')
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'a', 'F - test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bottom/screen:1')
 end
 
 function test_typing_on_bottom_line_scrolls_down()
   io.write('\ntest_typing_on_bottom_line_scrolls_down')
   -- display a few lines with cursor on bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=3, pos=4}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_typing_on_bottom_line_scrolls_down/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_typing_on_bottom_line_scrolls_down/baseline/screen:2')
@@ -1334,7 +1404,7 @@ function test_typing_on_bottom_line_scrolls_down()
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_typing_on_bottom_line_scrolls_down/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_typing_on_bottom_line_scrolls_down/cursor:line')
   check_eq(Editor_state.cursor1.pos, 7, 'F - test_typing_on_bottom_line_scrolls_down/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_typing_on_bottom_line_scrolls_down/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghijk', 'F - test_typing_on_bottom_line_scrolls_down/screen:2')
@@ -1345,20 +1415,21 @@ end
 function test_left_arrow_scrolls_up_in_wrapped_line()
   io.write('\ntest_left_arrow_scrolls_up_in_wrapped_line')
   -- display lines starting from second screen line of a line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.screen_top1 = {line=3, pos=5}
   Editor_state.screen_bottom1 = {}
   -- cursor is at top of screen
   Editor_state.cursor1 = {line=3, pos=5}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'jkl', 'F - test_left_arrow_scrolls_up_in_wrapped_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'mno', 'F - test_left_arrow_scrolls_up_in_wrapped_line/baseline/screen:2')
   -- after hitting the left arrow the screen scrolls up to first screen line
   edit.run_after_keychord(Editor_state, 'left')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'ghi ', 'F - test_left_arrow_scrolls_up_in_wrapped_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl', 'F - test_left_arrow_scrolls_up_in_wrapped_line/screen:2')
@@ -1373,14 +1444,15 @@ end
 function test_right_arrow_scrolls_down_in_wrapped_line()
   io.write('\ntest_right_arrow_scrolls_down_in_wrapped_line')
   -- display the first three lines with the cursor on the bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   -- cursor is at bottom right of screen
   Editor_state.cursor1 = {line=3, pos=5}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_right_arrow_scrolls_down_in_wrapped_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_right_arrow_scrolls_down_in_wrapped_line/baseline/screen:2')
@@ -1391,7 +1463,7 @@ function test_right_arrow_scrolls_down_in_wrapped_line()
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_right_arrow_scrolls_down_in_wrapped_line/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_right_arrow_scrolls_down_in_wrapped_line/cursor:line')
   check_eq(Editor_state.cursor1.pos, 6, 'F - test_right_arrow_scrolls_down_in_wrapped_line/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_right_arrow_scrolls_down_in_wrapped_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi ', 'F - test_right_arrow_scrolls_down_in_wrapped_line/screen:2')
@@ -1402,20 +1474,21 @@ end
 function test_home_scrolls_up_in_wrapped_line()
   io.write('\ntest_home_scrolls_up_in_wrapped_line')
   -- display lines starting from second screen line of a line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.screen_top1 = {line=3, pos=5}
   Editor_state.screen_bottom1 = {}
   -- cursor is at top of screen
   Editor_state.cursor1 = {line=3, pos=5}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'jkl', 'F - test_home_scrolls_up_in_wrapped_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'mno', 'F - test_home_scrolls_up_in_wrapped_line/baseline/screen:2')
   -- after hitting home the screen scrolls up to first screen line
   edit.run_after_keychord(Editor_state, 'home')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'ghi ', 'F - test_home_scrolls_up_in_wrapped_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl', 'F - test_home_scrolls_up_in_wrapped_line/screen:2')
@@ -1430,14 +1503,15 @@ end
 function test_end_scrolls_down_in_wrapped_line()
   io.write('\ntest_end_scrolls_down_in_wrapped_line')
   -- display the first three lines with the cursor on the bottom line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   -- cursor is at bottom right of screen
   Editor_state.cursor1 = {line=3, pos=5}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_end_scrolls_down_in_wrapped_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_end_scrolls_down_in_wrapped_line/baseline/screen:2')
@@ -1448,7 +1522,7 @@ function test_end_scrolls_down_in_wrapped_line()
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_end_scrolls_down_in_wrapped_line/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_end_scrolls_down_in_wrapped_line/cursor:line')
   check_eq(Editor_state.cursor1.pos, 8, 'F - test_end_scrolls_down_in_wrapped_line/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_end_scrolls_down_in_wrapped_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi ', 'F - test_end_scrolls_down_in_wrapped_line/screen:2')
@@ -1460,12 +1534,13 @@ function test_position_cursor_on_recently_edited_wrapping_line()
   -- draw a line wrapping over 2 screen lines
   io.write('\ntest_position_cursor_on_recently_edited_wrapping_line')
   App.screen.init{width=100, height=200}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc def ghi jkl mno pqr ', 'xyz'}
   Editor_state.cursor1 = {line=1, pos=25}
   Editor_state.screen_top1 = {line=1, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc def ghi ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline1/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl mno pqr ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline1/screen:2')
@@ -1476,14 +1551,14 @@ function test_position_cursor_on_recently_edited_wrapping_line()
   edit.run_after_textinput(Editor_state, 't')
   edit.run_after_textinput(Editor_state, 'u')
   check_eq(Editor_state.cursor1.pos, 28, 'F - test_move_cursor_using_mouse/cursor:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc def ghi ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline2/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'jkl mno pqr ', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline2/screen:2')
   y = y + Editor_state.line_height
   App.screen.check(y, 'stu', 'F - test_position_cursor_on_recently_edited_wrapping_line/baseline2/screen:3')
   -- try to move the cursor earlier in the third screen line by clicking the mouse
-  edit.run_after_mouse_release(Editor_state, Editor_state.margin_left+8,Editor_state.margin_top+Editor_state.line_height*2+5, 1)
+  edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+Editor_state.line_height*2+5, 1)
   -- cursor should move
   check_eq(Editor_state.cursor1.line, 1, 'F - test_move_cursor_using_mouse/cursor:line')
   check_eq(Editor_state.cursor1.pos, 26, 'F - test_move_cursor_using_mouse/cursor:pos')
@@ -1493,12 +1568,13 @@ function test_backspace_can_scroll_up()
   io.write('\ntest_backspace_can_scroll_up')
   -- display the lines 2/3/4 with the cursor on line 2
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.screen_top1 = {line=2, pos=1}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_backspace_can_scroll_up/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_backspace_can_scroll_up/baseline/screen:2')
@@ -1508,7 +1584,7 @@ function test_backspace_can_scroll_up()
   edit.run_after_keychord(Editor_state, 'backspace')
   check_eq(Editor_state.screen_top1.line, 1, 'F - test_backspace_can_scroll_up/screen_top')
   check_eq(Editor_state.cursor1.line, 1, 'F - test_backspace_can_scroll_up/cursor')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abcdef', 'F - test_backspace_can_scroll_up/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'ghi', 'F - test_backspace_can_scroll_up/screen:2')
@@ -1519,19 +1595,21 @@ end
 function test_backspace_can_scroll_up_screen_line()
   io.write('\ntest_backspace_can_scroll_up_screen_line')
   -- display lines starting from second screen line of a line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
   Editor_state.cursor1 = {line=3, pos=5}
   Editor_state.screen_top1 = {line=3, pos=5}
   Editor_state.screen_bottom1 = {}
   edit.draw(Editor_state)
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'jkl', 'F - test_backspace_can_scroll_up_screen_line/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'mno', 'F - test_backspace_can_scroll_up_screen_line/baseline/screen:2')
   -- after hitting backspace the screen scrolls up by one screen line
   edit.run_after_keychord(Editor_state, 'backspace')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'ghijk', 'F - test_backspace_can_scroll_up_screen_line/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'l', 'F - test_backspace_can_scroll_up_screen_line/screen:2')
@@ -1546,7 +1624,9 @@ end
 function test_backspace_past_line_boundary()
   io.write('\ntest_backspace_past_line_boundary')
   -- position cursor at start of a (non-first) line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def'}
   Editor_state.cursor1 = {line=2, pos=1}
   -- backspace joins with previous line
@@ -1560,7 +1640,9 @@ end
 function test_backspace_over_selection()
   io.write('\ntest_backspace_over_selection')
   -- select just one character within a line with cursor before selection
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}
@@ -1577,7 +1659,9 @@ end
 function test_backspace_over_selection_reverse()
   io.write('\ntest_backspace_over_selection_reverse')
   -- select just one character within a line with cursor after selection
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.selection1 = {line=1, pos=1}
@@ -1594,7 +1678,9 @@ end
 function test_backspace_over_multiple_lines()
   io.write('\ntest_backspace_over_multiple_lines')
   -- select just one character within a line with cursor after selection
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.selection1 = {line=4, pos=2}
@@ -1612,7 +1698,9 @@ end
 function test_backspace_to_end_of_line()
   io.write('\ntest_backspace_to_end_of_line')
   -- select region from cursor to end of line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=1, pos=2}
   Editor_state.selection1 = {line=1, pos=4}
@@ -1630,7 +1718,9 @@ end
 function test_backspace_to_start_of_line()
   io.write('\ntest_backspace_to_start_of_line')
   -- select region from cursor to start of line
-  App.screen.init{width=Editor_state.margin_left+30, height=60}
+  App.screen.init{width=Editor_state.left+30, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl', 'mno'}
   Editor_state.cursor1 = {line=2, pos=1}
   Editor_state.selection1 = {line=2, pos=3}
@@ -1648,6 +1738,7 @@ end
 function test_undo_insert_text()
   io.write('\ntest_undo_insert_text')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'def', 'xyz'}
   Editor_state.cursor1 = {line=2, pos=4}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -1659,7 +1750,7 @@ function test_undo_insert_text()
   check_eq(Editor_state.cursor1.pos, 5, 'F - test_undo_insert_text/baseline/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_undo_insert_text/baseline/selection:line')
   check_nil(Editor_state.selection1.pos, 'F - test_undo_insert_text/baseline/selection:pos')
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_undo_insert_text/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'defg', 'F - test_undo_insert_text/baseline/screen:2')
@@ -1671,7 +1762,7 @@ function test_undo_insert_text()
   check_eq(Editor_state.cursor1.pos, 4, 'F - test_undo_insert_text/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_undo_insert_text/selection:line')
   check_nil(Editor_state.selection1.pos, 'F - test_undo_insert_text/selection:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_undo_insert_text/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_undo_insert_text/screen:2')
@@ -1682,6 +1773,7 @@ end
 function test_undo_delete_text()
   io.write('\ntest_undo_delete_text')
   App.screen.init{width=120, height=60}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc', 'defg', 'xyz'}
   Editor_state.cursor1 = {line=2, pos=5}
   Editor_state.screen_top1 = {line=1, pos=1}
@@ -1692,7 +1784,7 @@ function test_undo_delete_text()
   check_eq(Editor_state.cursor1.pos, 4, 'F - test_undo_delete_text/baseline/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_undo_delete_text/baseline/selection:line')
   check_nil(Editor_state.selection1.pos, 'F - test_undo_delete_text/baseline/selection:pos')
-  local y = Editor_state.margin_top
+  local y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_undo_delete_text/baseline/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'def', 'F - test_undo_delete_text/baseline/screen:2')
@@ -1707,7 +1799,7 @@ function test_undo_delete_text()
   check_nil(Editor_state.selection1.pos, 'F - test_undo_delete_text/selection:pos')
 --?   check_eq(Editor_state.selection1.line, 2, 'F - test_undo_delete_text/selection:line')
 --?   check_eq(Editor_state.selection1.pos, 4, 'F - test_undo_delete_text/selection:pos')
-  y = Editor_state.margin_top
+  y = Editor_state.top
   App.screen.check(y, 'abc', 'F - test_undo_delete_text/screen:1')
   y = y + Editor_state.line_height
   App.screen.check(y, 'defg', 'F - test_undo_delete_text/screen:2')
@@ -1719,6 +1811,7 @@ function test_undo_restores_selection()
   io.write('\ntest_undo_restores_selection')
   -- display a line of text with some part selected
   App.screen.init{width=75, height=80}
+  Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width)  -- zero right margin
   Editor_state.lines = load_array{'abc'}
   Editor_state.cursor1 = {line=1, pos=1}
   Editor_state.selection1 = {line=1, pos=2}