Text.redraw_all(State)  -- if we're scrolling, reclaim all line caches to avoid memory leaks
  Text.redraw_all(State)  -- if we're scrolling, reclaim all line caches to avoid memory leaks
  Text.redraw_all(State)  -- if we're scrolling, reclaim all line caches to avoid memory leaks
    Text.redraw_all(State)  -- if we're scrolling, reclaim all line caches to avoid memory leaks
    Text.redraw_all(State)  -- if we're scrolling, reclaim all line caches to avoid memory leaks
  Text.redraw_all(State)  -- if we're scrolling, reclaim all line caches to avoid memory leaks
--?   print('clearing line caches')
  -- Perform some early sanity checking here, in hopes that we correctly call
  -- this whenever we change editor state.
  if State.right <= State.left then
    assert(false, ('Right margin %d must be to the right of the left margin %d'):format(State.right, State.left))
  end
end
function Text.in_line(State, line_index, x,y)
  local line = State.lines[line_index]
  local line_cache = State.line_cache[line_index]
  end
end
  end
end
end
-- return the location of the start of the bottom-most line on screen
function Text.screen_bottom1(State)
  -- duplicate some logic from love.draw
  -- does not modify State (except to populate line_cache)
  local loc2 = Text.to2(State, State.screen_top1)
  local y = State.top
  while true do
    if State.lines[loc2.line].mode == 'text' then
      y = y + State.line_height
    elseif State.lines[loc2.line].mode == 'drawing' then
      y = y + Drawing_padding_height + Drawing.pixels(State.lines[loc2.line].h, State.width)
    end
    if y + State.line_height > App.screen.height then break end
    local next_loc2 = Text.next_screen_line(State, loc2)
    if Text.eq2(next_loc2, loc2) then break end
    loc2 = next_loc2
  end
  return Text.to1(State, loc2)
end
-- return the top y coordinate of a given line_index,
-- or nil if no part of it is on screen
function Text.starty(State, line_index)
    end
    Text.clear_screen_line_cache(State, State.cursor1.line)