~akkartik/text.love

3aec915559514e8294f80447fcac9c4b34df9dc4 — Kartik K. Agaram 1 year, 18 days ago 5c5a8a8 + bd6f7d4
Merge lines.love
5 files changed, 102 insertions(+), 26 deletions(-)

M edit.lua
M source_edit.lua
M source_text_tests.lua
M text_tests
M text_tests.lua
M edit.lua => edit.lua +26 -13
@@ 192,7 192,7 @@ function edit.mouse_press(State, x,y, mouse_button)
    end
  end

  -- still here? click is below all screen lines
  -- still here? mouse press is below all screen lines
  State.old_cursor1 = State.cursor1
  State.old_selection1 = State.selection1
  State.mousepress_shift = App.shift_down()


@@ 205,6 205,11 @@ end
function edit.mouse_release(State, x,y, mouse_button)
  if State.search_term then return end
--?   print_and_log(('edit.mouse_release(%d,%d): cursor at %d,%d'):format(x,y, State.cursor1.line, State.cursor1.pos))
  if y < State.top then
    State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos}
    edit.clean_up_mouse_press(State)
    return
  end
  for line_index,line in ipairs(State.lines) do
    if Text.in_line(State, line_index, x,y) then
--?       print_and_log(('edit.mouse_release: in line %d'):format(line_index))


@@ 213,23 218,31 @@ function edit.mouse_release(State, x,y, mouse_button)
          pos=Text.to_pos_on_line(State, line_index, x, y),
      }
--?       print_and_log(('edit.mouse_release: cursor now %d,%d'):format(State.cursor1.line, State.cursor1.pos))
      if State.mousepress_shift then
        if State.old_selection1.line == nil then
          State.selection1 = State.old_cursor1
        else
          State.selection1 = State.old_selection1
        end
      end
      State.old_cursor1, State.old_selection1, State.mousepress_shift = nil
      if eq(State.cursor1, State.selection1) then
        State.selection1 = {}
      end
      break
      edit.clean_up_mouse_press(State)
      return
    end
  end

  -- still here? mouse release is below all screen lines
  State.cursor1.line, State.cursor1.pos = State.screen_bottom1.line, Text.pos_at_end_of_screen_line(State, State.screen_bottom1)
  edit.clean_up_mouse_press(State)
--?   print_and_log(('edit.mouse_release: finally selection %s,%s cursor %d,%d'):format(tostring(State.selection1.line), tostring(State.selection1.pos), State.cursor1.line, State.cursor1.pos))
end

function edit.clean_up_mouse_press(State)
  if State.mousepress_shift then
    if State.old_selection1.line == nil then
      State.selection1 = State.old_cursor1
    else
      State.selection1 = State.old_selection1
    end
  end
  State.old_cursor1, State.old_selection1, State.mousepress_shift = nil
  if eq(State.cursor1, State.selection1) then
    State.selection1 = {}
  end
end

function edit.mouse_wheel_move(State, dx,dy)
  if dy > 0 then
    State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos}

M source_edit.lua => source_edit.lua +27 -13
@@ 295,7 295,7 @@ function edit.mouse_press(State, x,y, mouse_button)
    end
  end

  -- still here? click is below all screen lines
  -- still here? mouse press is below all screen lines
  State.old_cursor1 = State.cursor1
  State.old_selection1 = State.selection1
  State.mousepress_shift = App.shift_down()


@@ 317,6 317,12 @@ function edit.mouse_release(State, x,y, mouse_button)
    end
  else
--?     print_and_log('edit.mouse_release: no current drawing')
    if y < State.top then
      State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos}
      edit.clean_up_mouse_press(State)
      return
    end

    for line_index,line in ipairs(State.lines) do
      if line.mode == 'text' then
        if Text.in_line(State, line_index, x,y) then


@@ 326,25 332,33 @@ function edit.mouse_release(State, x,y, mouse_button)
              pos=Text.to_pos_on_line(State, line_index, x, y),
          }
--?           print_and_log(('edit.mouse_release: cursor now %d,%d'):format(State.cursor1.line, State.cursor1.pos))
          if State.mousepress_shift then
            if State.old_selection1.line == nil then
              State.selection1 = State.old_cursor1
            else
              State.selection1 = State.old_selection1
            end
          end
          State.old_cursor1, State.old_selection1, State.mousepress_shift = nil
          if eq(State.cursor1, State.selection1) then
            State.selection1 = {}
          end
          break
          edit.clean_up_mouse_press(State)
          return
        end
      end
    end

    -- still here? mouse release is below all screen lines
    State.cursor1.line, State.cursor1.pos = State.screen_bottom1.line, Text.pos_at_end_of_screen_line(State, State.screen_bottom1)
    edit.clean_up_mouse_press(State)
--?     print_and_log(('edit.mouse_release: finally selection %s,%s cursor %d,%d'):format(tostring(State.selection1.line), tostring(State.selection1.pos), State.cursor1.line, State.cursor1.pos))
  end
end

function edit.clean_up_mouse_press(State)
  if State.mousepress_shift then
    if State.old_selection1.line == nil then
      State.selection1 = State.old_cursor1
    else
      State.selection1 = State.old_selection1
    end
  end
  State.old_cursor1, State.old_selection1, State.mousepress_shift = nil
  if eq(State.cursor1, State.selection1) then
    State.selection1 = {}
  end
end

function edit.mouse_wheel_move(State, dx,dy)
  if dy > 0 then
    State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos}

M source_text_tests.lua => source_text_tests.lua +24 -0
@@ 275,6 275,7 @@ function test_click_to_left_of_line()
  Editor_state.cursor1 = {line=1, pos=3}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click to the left of the line
  edit.draw(Editor_state)
  edit.run_after_mouse_click(Editor_state, Editor_state.left-4,Editor_state.top+5, 1)


@@ 294,6 295,7 @@ function test_click_takes_margins_into_account()
  Editor_state.cursor1 = {line=2, pos=1}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click on the other line
  edit.draw(Editor_state)
  edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)


@@ 312,11 314,33 @@ function test_click_on_empty_line()
  Editor_state.cursor1 = {line=2, pos=1}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click on the empty line
  edit.draw(Editor_state)
  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, 'cursor')
  -- selection remains empty
  check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
end

function test_click_below_all_lines()
  -- display one line
  App.screen.init{width=50, height=80}
  Editor_state = edit.initialize_test_state()
  Editor_state.lines = load_array{'abc'}
  Text.redraw_all(Editor_state)
  Editor_state.cursor1 = {line=1, pos=1}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click below first line
  edit.draw(Editor_state)
  edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+50, 1)
  -- cursor doesn't move
  check_eq(Editor_state.cursor1.line, 1, 'cursor')
  -- selection remains empty
  check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
end

function test_draw_text()

M text_tests => text_tests +1 -0
@@ 23,6 23,7 @@ click on wrapping line rendered from partway at top of screen
click past end of wrapping line
click past end of wrapping line containing non ascii
click past end of word wrapping line
click below final line does nothing

# cursor movement
move left

M text_tests.lua => text_tests.lua +24 -0
@@ 249,6 249,7 @@ function test_click_to_left_of_line()
  Editor_state.cursor1 = {line=1, pos=3}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click to the left of the line
  edit.draw(Editor_state)
  edit.run_after_mouse_click(Editor_state, Editor_state.left-4,Editor_state.top+5, 1)


@@ 268,6 269,7 @@ function test_click_takes_margins_into_account()
  Editor_state.cursor1 = {line=2, pos=1}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click on the other line
  edit.draw(Editor_state)
  edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)


@@ 286,11 288,33 @@ function test_click_on_empty_line()
  Editor_state.cursor1 = {line=2, pos=1}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click on the empty line
  edit.draw(Editor_state)
  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, 'cursor')
  -- selection remains empty
  check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
end

function test_click_below_all_lines()
  -- display one line
  App.screen.init{width=50, height=80}
  Editor_state = edit.initialize_test_state()
  Editor_state.lines = load_array{'abc'}
  Text.redraw_all(Editor_state)
  Editor_state.cursor1 = {line=1, pos=1}
  Editor_state.screen_top1 = {line=1, pos=1}
  Editor_state.screen_bottom1 = {}
  Editor_state.selection1 = {}
  -- click below first line
  edit.draw(Editor_state)
  edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+50, 1)
  -- cursor doesn't move
  check_eq(Editor_state.cursor1.line, 1, 'cursor')
  -- selection remains empty
  check_nil(Editor_state.selection1.line, 'selection is empty to avoid perturbing future edits')
end

function test_draw_text()