Merge text.love

[?]
Jun 4, 2023, 10:25 PM
X43ZIKR3WHHUHTIBN76H25FLACL7SMKXXHFX7GDD552UF3V2UDPAC

Dependencies

Change contents

  • file deletion: source_select.lua (----------)source_select.lua (----------)
    [6.2][6.30050:30091](),[6.2][6.30050:30091](),[6.30091][6.23288:23288]()
    return State.screen_bottom1.line, Text.pos_at_end_of_screen_line(State, State.screen_bottom1)
    end
    function Text.cut_selection(State)
    if State.selection1.line == nil then return end
    local result = Text.selection(State)
    Text.delete_selection(State)
    return result
    end
    function Text.delete_selection(State)
    if State.selection1.line == nil then return end
    local minl,maxl = minmax(State.selection1.line, State.cursor1.line)
    local before = snapshot(State, minl, maxl)
    Text.delete_selection_without_undo(State)
    record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
    end
    function Text.delete_selection_without_undo(State)
    if State.selection1.line == nil then return end
    -- min,max = sorted(State.selection1,State.cursor1)
    local minl,minp = State.selection1.line,State.selection1.pos
    local maxl,maxp = State.cursor1.line,State.cursor1.pos
    if minl > maxl then
    minl,maxl = maxl,minl
    minp,maxp = maxp,minp
    elseif minl == maxl then
    if minp > maxp then
    minp,maxp = maxp,minp
    end
    end
    -- update State.cursor1 and State.selection1
    State.cursor1.line = minl
    State.cursor1.pos = minp
    if Text.lt1(State.cursor1, State.screen_top1) then
    State.screen_top1.line = State.cursor1.line
    State.screen_top1.pos = Text.pos_at_start_of_screen_line(State, State.cursor1)
    end
    State.selection1 = {}
    -- delete everything between min (inclusive) and max (exclusive)
    Text.clear_screen_line_cache(State, minl)
    local min_offset = Text.offset(State.lines[minl].data, minp)
    local max_offset = Text.offset(State.lines[maxl].data, maxp)
    if minl == maxl then
    --? print('minl == maxl')
    State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..State.lines[minl].data:sub(max_offset)
    return
    end
    assert(minl < maxl)
    local rhs = State.lines[maxl].data:sub(max_offset)
    for i=maxl,minl+1,-1 do
    table.remove(State.lines, i)
    table.remove(State.line_cache, i)
    end
    State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..rhs
    end
    function Text.selection(State)
    if State.selection1.line == nil then return end
    -- min,max = sorted(State.selection1,State.cursor1)
    local minl,minp = State.selection1.line,State.selection1.pos
    local maxl,maxp = State.cursor1.line,State.cursor1.pos
    if minl > maxl then
    minl,maxl = maxl,minl
    minp,maxp = maxp,minp
    elseif minl == maxl then
    if minp > maxp then
    minp,maxp = maxp,minp
    end
    end
    local min_offset = Text.offset(State.lines[minl].data, minp)
    local max_offset = Text.offset(State.lines[maxl].data, maxp)
    if minl == maxl then
    return State.lines[minl].data:sub(min_offset, max_offset-1)
    end
    assert(minl < maxl)
    local result = {State.lines[minl].data:sub(min_offset)}
    for i=minl+1,maxl-1 do
    if State.lines[i].mode == 'text' then
    table.insert(result, State.lines[i].data)
    end
    end
    table.insert(result, State.lines[maxl].data:sub(1, max_offset-1))
    return table.concat(result, '\n')
    end
    local x,y = App.mouse_x(), App.mouse_y()
    if y < State.line_cache[State.screen_top1.line].starty then
    return State.screen_top1.line, State.screen_top1.pos
    end
  • file deletion: source_text_tests.lua (----------)source_text_tests.lua (----------)
    [6.2][6.83739:83784](),[6.2][6.83739:83784](),[6.83784][6.3561:3561]()
    end
    function test_select_all_text()
    -- display a single line of text
    App.screen.init{width=75, height=80}
    Editor_state = edit.initialize_test_state()
    Editor_state.lines = load_array{'abc def'}
    Text.redraw_all(Editor_state)
    Editor_state.cursor1 = {line=1, pos=1}
    Editor_state.screen_top1 = {line=1, pos=1}
    Editor_state.screen_bottom1 = {}
    edit.draw(Editor_state)
    -- select all
    App.fake_key_press('lctrl')
    edit.run_after_keychord(Editor_state, 'C-a')
    App.fake_key_release('lctrl')
    edit.key_release(Editor_state, 'lctrl')
    -- selection
    check_eq(Editor_state.selection1.line, 1, 'selection:line')
    check_eq(Editor_state.selection1.pos, 1, 'selection:pos')
    check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
    check_eq(Editor_state.cursor1.pos, 8, 'cursor:pos')
    end
    function test_select_text_using_mouse_starting_above_text_wrapping_line()
    -- first screen line starts in the middle of a line
    App.screen.init{width=50, height=60}
    Editor_state = edit.initialize_test_state()
    Editor_state.lines = load_array{'abc', 'defgh', 'xyz'}
    Text.redraw_all(Editor_state)
    Editor_state.cursor1 = {line=2, pos=5}
    Editor_state.screen_top1 = {line=2, pos=3}
    Editor_state.screen_bottom1 = {}
    -- press mouse above first line of text
    edit.run_after_mouse_press(Editor_state, Editor_state.left+8,5, 1)
    -- selection is at screen top
    check(Editor_state.selection1.line ~= nil, 'selection:line-not-nil')
    check_eq(Editor_state.selection1.line, 2, 'selection:line')
    check_eq(Editor_state.selection1.pos, 3, 'selection:pos')
    end
    function test_select_text_using_mouse_starting_below_text()
    -- I'd like to test what happens when a mouse click is below some page of
    -- text, potentially even in the middle of a line.
    -- However, it's brittle to set up a text line boundary just right.
    -- So I'm going to just check things below the bottom of the final line of
    -- text when it's in the middle of the screen.
    -- final screen line ends in the middle of screen
    App.screen.init{width=50, height=60}
    Editor_state = edit.initialize_test_state()
    Editor_state.lines = load_array{'abcde'}
    Text.redraw_all(Editor_state)
    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.top
    App.screen.check(y, 'ab', 'baseline:screen:1')
    y = y + Editor_state.line_height
    App.screen.check(y, 'cde', 'baseline:screen:2')
    -- press mouse above first line of text
    edit.run_after_mouse_press(Editor_state, 5,App.screen.height-5, 1)
    -- selection is past bottom-most text in screen
    check(Editor_state.selection1.line ~= nil, 'selection:line-not-nil')
    check_eq(Editor_state.selection1.line, 1, 'selection:line')
    check_eq(Editor_state.selection1.pos, 6, 'selection:pos')
    end
    function test_select_text_using_mouse_and_shift()
    end
    function test_select_text_using_mouse_starting_above_text()
    App.screen.init{width=50, height=60}
    Editor_state = edit.initialize_test_state()
    Editor_state.lines = load_array{'abc', 'def', 'xyz'}
    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 = {}
    edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache
    -- press mouse above first line of text
    edit.run_after_mouse_press(Editor_state, Editor_state.left+8,5, 1)
    check(Editor_state.selection1.line ~= nil, 'selection:line-not-nil')
    check_eq(Editor_state.selection1.line, 1, 'selection:line')
    check_eq(Editor_state.selection1.pos, 1, 'selection:pos')
    end
    -- Arguably this should be called source_edit_tests.lua,
    -- but that would mess up the git blame at this point.
    function test_initial_state()
  • file deletion: source_text.lua (----------)source_text.lua (----------)
    [6.2][6.147125:147164](),[6.2][6.147125:147164](),[6.147164][6.83786:83786]()
    function Text.pos_at_end_of_screen_line(State, loc1)
    Text.populate_screen_line_starting_pos(State, loc1.line)
    local line_cache = State.line_cache[loc1.line]
    local most_recent_final_pos = utf8.len(State.lines[loc1.line].data)+1
    for i=#line_cache.screen_line_starting_pos,1,-1 do
    local spos = line_cache.screen_line_starting_pos[i]
    if spos <= loc1.pos then
    return most_recent_final_pos
    end
    most_recent_final_pos = spos-1
    end
    assert(false)
    end
    function Text.cursor_at_final_screen_line(State)
    Text.populate_screen_line_starting_pos(State, State.cursor1.line)
    -- result: pos, index of screen line
    function Text.pos_at_start_of_screen_line(State, loc1)
    Text.populate_screen_line_starting_pos(State, loc1.line)
    local line_cache = State.line_cache[loc1.line]
    for i=#line_cache.screen_line_starting_pos,1,-1 do
    local spos = line_cache.screen_line_starting_pos[i]
    if spos <= loc1.pos then
    return spos,i
  • file deletion: source_edit.lua (----------)source_edit.lua (----------)
    [6.2][6.165788:165827](),[6.2][6.165788:165827](),[6.165827][6.152503:152503]()
    --? 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.mouse_wheel_move(State, dx,dy)
    if dy > 0 then
    State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos}
    for i=1,math.floor(dy) do
    Text.up(State)
    end
    elseif dy < 0 then
    State.cursor1 = {line=State.screen_bottom1.line, pos=State.screen_bottom1.pos}
    for i=1,math.floor(-dy) do
    Text.down(State)
    end
    --? 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
    end
    end
    end
    --? print_and_log(('edit.mouse_release: in line %d'):format(line_index))
    State.cursor1 = {
    line=line_index,
    pos=Text.to_pos_on_line(State, line_index, x, y),
    }
    --? print_and_log('edit.mouse_release: no current drawing')
    for line_index,line in ipairs(State.lines) do
    if line.mode == 'text' then
    if Text.in_line(State, line_index, x,y) then
    --? print_and_log(('edit.mouse_release: cursor at %d,%d'):format(State.cursor1.line, State.cursor1.pos))
    if State.lines.current_drawing then
    -- still here? click is below all screen lines
    State.old_cursor1 = State.cursor1
    State.old_selection1 = State.selection1
    State.mousepress_shift = App.shift_down()
    State.selection1 = {
    line=State.screen_bottom1.line,
    pos=Text.pos_at_end_of_screen_line(State, State.screen_bottom1),
    }
    end
    return
    end
    return
    end
    elseif line.mode == 'drawing' then
    local line_cache = State.line_cache[line_index]
    if Drawing.in_drawing(line, line_cache, x, y, State.left,State.right) then
    State.lines.current_drawing_index = line_index
    State.lines.current_drawing = line
    Drawing.before = snapshot(State, line_index)
    --? print_and_log(('edit.mouse_press: in line %d'):format(line_index))
    State.old_cursor1 = State.cursor1
    State.old_selection1 = State.selection1
    State.mousepress_shift = App.shift_down()
    if y < State.top then
    State.old_cursor1 = State.cursor1
    State.old_selection1 = State.selection1
    State.mousepress_shift = App.shift_down()
    State.selection1 = {
    line=State.screen_top1.line,
    pos=State.screen_top1.pos,
    }
    return
    end
    for line_index,line in ipairs(State.lines) do
    --? print_and_log(('edit.mouse_press: cursor at %d,%d'):format(State.cursor1.line, State.cursor1.pos))
    if mouse_press_consumed_by_any_button_handler(State, x,y, mouse_button) then
    -- press on a button and it returned 'true' to short-circuit
    return
    end
    State.screen_bottom1 = screen_bottom1
    if State.search_term then
    Text.draw_search_bar(State)
    end
    end
    function edit.update(State, dt)
    y, screen_bottom1.pos = Text.draw(State, line_index, y, startpos, hide_cursor)
    --? print('=> y', y)
    elseif line.mode == 'drawing' then
    y = y+Drawing_padding_top
    Drawing.draw(State, line_index, y)
    y = y + Drawing.pixels(line.h, State.width) + Drawing_padding_bottom
    else
    print(line.mode)
    assert(false)
    screen_bottom1.line = line_index
    if line.mode == 'text' then
    local screen_bottom1 = {line=nil, pos=nil}
    --? print('== draw')
    for line_index = State.screen_top1.line,#State.lines do
    local line = State.lines[line_index]
  • file deletion: source.lua (----------)source.lua (----------)
    [6.2][6.177715:177749](),[6.2][6.177715:177749](),[6.177749][6.165829:165829]()
    function print_and_log(s)
    print(s)
    log(3, s)
    end
    function source.load_settings()
    local settings = Settings.source
    love.graphics.setFont(love.graphics.newFont(settings.font_height))
  • file deletion: run.lua (----------)run.lua (----------)
    [6.2][6.183867:183898](),[6.2][6.183867:183898](),[6.183898][6.178107:178107]()
    function print_and_log(s)
    print(s)
    log(3, s)
    end
    function run.load_settings()
    love.graphics.setFont(love.graphics.newFont(Settings.font_height))
  • edit in main.lua at line 81
    [6.3084]
    [6.3084]
    function print_and_log(s)
    print(s)
    log(3, s)
    end
  • edit in edit.lua at line 115
    [6.3095][6.3634:3688]()
    State.screen_bottom1 = {line=line_index, pos=nil}
  • edit in edit.lua at line 124
    [6.5923][6.8081:8211]()
    --? print('screen bottom: '..tostring(State.screen_bottom1.pos)..' in '..tostring(State.lines[State.screen_bottom1.line].data))