Merge lines.love

[?]
Sep 17, 2022, 5:49 PM
AYX33NBCPCBFWEZI5KZXHP3Y2Q62GYVT4WHYJUYRIPYV67KPSYZAC

Dependencies

  • [2] C3NYQP57 Merge lines.love
  • [3] NNTMVNVO .
  • [4] ENENSZLK bugfix: source margins when toggling log browser
  • [5] JMUD7T3O get rid of ugly side-effects in tests
  • [6] NFI42KGX more correct absolute path detection
  • [7] RSZD5A7G forgot to add json.lua
  • [8] 2L5MEZV3 experiment: new edit namespace
  • [9] BLWAYPKV extract a module
  • [10] AVTNUQYR basic test-enabled framework
  • [11] VXORMHME delete experimental REPL
  • [12] 32V6ZHQB Merge lines.love
  • [13] KKMFQDR4 editing source code from within the app
  • [14] XX7G2FFJ intermingle freehand line drawings with text
  • [15] D2GCFTTT clean up repl functionality
  • [16] T4FRZSYL delete an ancient, unused file
  • [17] BJ5X5O4A let's prevent the text cursor from ever getting on a drawing
  • [18] X3CQLBTR set window title within each app
  • [19] SXTQMD44 include some missing source files
  • [20] 3PSFWAIL Merge lines.love
  • [21] ZJOSQFN6 bugfix: path munging on Windows
  • [22] 4YDBYBA4 clean up memory leak experiments
  • [23] 2CTN2IEF Merge lines.love
  • [24] 2WGHUWE6 self-documenting 0 Test_right_margin
  • [25] OGUV4HSA remove some memory leaks from rendered fragments
  • [26] 4VQGE7RA new test
  • [27] MD3W5IRA new fork: rip out drawing support
  • [28] OTIBCAUJ love2d scaffold
  • [29] 3QNOKBFM beginnings of a test harness
  • [30] GUOQRUL7 Merge lines.love
  • [31] TFM6F5OD Merge lines.love
  • [32] R5QXEHUI somebody stop me
  • [33] JOPVPUSA editing source code from within the app
  • [34] TVCPXAAU rename
  • [35] VHQCNMAR several more modules
  • [36] D4B52CQ2 Merge lines.love
  • [37] BULPIBEG beginnings of a module for the text editor
  • [38] KMSL74GA support selections in the source editor
  • [39] CE4LZV4T drop last couple of manual tests
  • [40] VHUNJHXB Merge lines.love
  • [41] 6SMGKYDR .
  • [42] 66X36NZN a little more prose describing manual_tests
  • [43] FS2ITYYH record a known issue
  • [44] K2X6G75Z start writing some tests for drawings
  • [45] 6LJZN727 handle chords
  • [46] OI4FPFIN support drawings in the source editor
  • [47] 73OCE2MC after much struggle, a brute-force undo
  • [48] P3K7UH5C Merge lines.love
  • [49] LXTTOB33 extract a couple of files
  • [50] AKZWDWIA Merge lines.love
  • [51] TLOAPLBJ add a license

Change contents

  • file deletion: source_tests.lua (----------)source_tests.lua (----------)
    [6.2][6.150199:150239](),[6.2][6.150199:150239](),[6.150239][6.147103:147103]()
    end
    function test_show_log_browser_side()
    io.write('\ntest_show_log_browser_side')
    App.screen.init{width=300, height=300}
    Editor_state = edit.initialize_test_state()
    Editor_state.filename = 'foo'
    Text.redraw_all(Editor_state)
    Log_browser_state = edit.initialize_test_state()
    Text.redraw_all(Log_browser_state)
    log_browser.parse(Log_browser_state)
    check(not Show_log_browser_side, 'F - test_show_log_browser_side/baseline')
    App.wait_fake_time(0.1)
    App.run_after_keychord('C-l')
    check(Show_log_browser_side, 'F - test_show_log_browser_side')
    function test_show_log_browser_side_doubles_window_width_if_possible()
    io.write('\ntest_show_log_browser_side_doubles_window_width_if_possible')
    -- initialize screen dimensions to half width
    App.screen.init{width=300, height=300}
    Display_width = App.screen.width*2
    -- initialize source app with left side occupying entire window (half the display)
    Current_app = 'source'
    Editor_state = edit.initialize_test_state()
    Editor_state.filename = 'foo'
    Editor_state.left = Margin_left
    Editor_state.right = App.screen.width - Margin_right
    local old_editor_right = Editor_state.right
    Text.redraw_all(Editor_state)
    Log_browser_state = edit.initialize_test_state()
    -- log browser has some arbitrary margins
    Log_browser_state.left = 200 + Margin_left
    Log_browser_state.right = 400
    Text.redraw_all(Log_browser_state)
    log_browser.parse(Log_browser_state)
    -- display log browser
    App.wait_fake_time(0.1)
    App.run_after_keychord('C-l')
    -- window width is doubled
    check_eq(App.screen.width, 600, 'F - test_show_log_browser_side_doubles_window_width_if_possible/display:width')
    -- left side margins are unchanged
    check_eq(Editor_state.left, Margin_left, 'F - test_show_log_browser_side_doubles_window_width_if_possible/edit:left')
    check_eq(Editor_state.right, old_editor_right, 'F - test_show_log_browser_side_doubles_window_width_if_possible/edit:right')
    -- log browser margins are adjusted
    check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'F - test_show_log_browser_side_doubles_window_width_if_possible/log:left')
    check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'F - test_show_log_browser_side_doubles_window_width_if_possible/log:right')
    end
    function test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width()
    io.write('\ntest_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width')
    -- initialize screen dimensions and indicate that it is maximized
    App.screen.init{width=300, height=300}
    Display_width = 300
    -- initialize source app with left side occupying more than half the display
    Current_app = 'source'
    Editor_state = edit.initialize_test_state()
    Editor_state.filename = 'foo'
    Editor_state.left = Margin_left
    Editor_state.right = 200
    Text.redraw_all(Editor_state)
    Log_browser_state = edit.initialize_test_state()
    -- log browser has some arbitrary margins
    Log_browser_state.left = 200 + Margin_left
    Log_browser_state.right = 400
    Text.redraw_all(Log_browser_state)
    log_browser.parse(Log_browser_state)
    -- display log browser
    App.wait_fake_time(0.1)
    App.run_after_keychord('C-l')
    -- margins are now adjusted
    check_eq(Editor_state.left, Margin_left, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/edit:left')
    check_eq(Editor_state.right, App.screen.width/2 - Margin_right, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/edit:right')
    check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/log:left')
    check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/log:right')
    end
    function test_drop_file()
    io.write('\ntest_drop_file')
    App.screen.init{width=Editor_state.left+300, height=300}
    Editor_state = edit.initialize_test_state()
    App.filesystem['foo'] = 'abc\ndef\nghi\n'
    local fake_dropped_file = {
    opened = false,
    getFilename = function(self)
    return 'foo'
    end,
    open = function(self)
    self.opened = true
    end,
    lines = function(self)
    assert(self.opened)
    return App.filesystem['foo']:gmatch('[^\n]+')
    end,
    close = function(self)
    self.opened = false
    end,
    }
    App.filedropped(fake_dropped_file)
    check_eq(#Editor_state.lines, 3, 'F - test_drop_file/#lines')
    check_eq(Editor_state.lines[1].data, 'abc', 'F - test_drop_file/lines:1')
    check_eq(Editor_state.lines[2].data, 'def', 'F - test_drop_file/lines:2')
    check_eq(Editor_state.lines[3].data, 'ghi', 'F - test_drop_file/lines:3')
    edit.draw(Editor_state)
    end
    function test_drop_file_saves_previous()
    io.write('\ntest_drop_file_saves_previous')
    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'
    schedule_save(Editor_state)
    -- now drag a new file bar from the filesystem
    App.filesystem['bar'] = 'abc\ndef\nghi\n'
    local fake_dropped_file = {
    opened = false,
    getFilename = function(self)
    return 'bar'
    end,
    open = function(self)
    self.opened = true
    end,
    lines = function(self)
    assert(self.opened)
    return App.filesystem['bar']:gmatch('[^\n]+')
    end,
    close = function(self)
    self.opened = false
    end,
    }
    App.filedropped(fake_dropped_file)
    -- filesystem now contains a file called foo
    check_eq(App.filesystem['foo'], 'abc\ndef\n', 'F - test_drop_file_saves_previous')
    end
    end
    -- pressing ctrl+l shows log-browser side
    Display_width = App.screen.width
    Current_app = 'source'
    check_eq(Editor_state.right, 300 - Test_margin_right, 'F - test_resize_window/baseline/right_margin')
    App.resize(200, 400)
  • file deletion: source_edit.lua (----------)source_edit.lua (----------)
    [6.2][6.165725:165764](),[6.2][6.165725:165764](),[6.165764][6.152440:152440]()
    if #State.lines ~= #State.line_cache then
    print(('line_cache is out of date; %d when it should be %d'):format(#State.line_cache, #State.lines))
    assert(false)
    end
    if not Text.le1(State.screen_top1, State.cursor1) then
    print(State.screen_top1.line, State.screen_top1.pos, State.screen_top1.posB, State.cursor1.line, State.cursor1.pos, State.cursor1.posB)
    assert(false)
    end
    State.cursor_x = nil
    State.cursor_y = nil
    local y = State.top
    --? 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.177652:177686](),[6.2][6.177652:177686](),[6.177686][6.165766:165766]()
    Menu_status_bar_height = 5 + --[[line height in tests]] 15 + 5
    App.screen.width = math.min(Display_width, App.screen.width*2)
    Editor_state.right = App.screen.width/2 - Margin_right
    Log_browser_state.left = App.screen.width/2 + Margin_left
    Log_browser_state.right = App.screen.width - Margin_right
    App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
    --? print('done setting window')
    -- try to restore position if possible
    -- if the window gets wider the window manager may not respect this
    source.set_window_position_from_settings(Settings.source)
    return
    end
    if chord == 'C-g' then
    Show_file_navigator = true
    File_navigation.index = 1
    return
    end
    if Focus == 'edit' then
    return edit.keychord_pressed(Editor_state, chord, key)
    else
    return log_browser.keychord_pressed(Log_browser_state, chord, key)
    end
    end
    function source.key_released(key, scancode)
    Cursor_time = 0 -- ensure cursor is visible immediately after it moves
    if Focus == 'edit' then
    return edit.key_released(Editor_state, key, scancode)
    else
    return log_browser.keychord_pressed(Log_browser_state, chordkey, scancode)
    end
    end
    -- use this sparingly
    function to_text(s)
    if Text_cache[s] == nil then
    Text_cache[s] = App.newText(love.graphics.getFont(), s)
    end
    return Text_cache[s]
    end
    else
    App.screen.width = Editor_state.right + Margin_right
    end
    --? print('setting window:', App.screen.width, App.screen.height)
    Settings.source.x, Settings.source.y, Settings.source.displayindex = App.screen.position()
    end
    local filename = Editor_state.filename
    Settings.source.x, Settings.source.y, Settings.source.displayindex = App.screen.position()
    end
    function source.resize(w, h)
    --? print(("Window resized to width: %d and height: %d."):format(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
    if Show_log_browser_side then
    Editor_state.right = App.screen.width/2 - Margin_right
    else
    Editor_state.right = App.screen.width-Margin_right
    end
    Log_browser_state.left = App.screen.width/2 + Margin_right
    Log_browser_state.right = App.screen.width-Margin_right
    Editor_state.width = Editor_state.right-Editor_state.left
    Text.tweak_screen_top_and_cursor(Editor_state, Editor_state.left, Editor_state.right)
    --? print('end resize')
    end
    function source.filedropped(file)
    -- first make sure to save edits on any existing file
    if Editor_state.next_save then
    save_to_disk(Editor_state)
    end
    -- clear the slate for the new file
    Editor_state.filename = file:getFilename()
    file:open('r')
    Editor_state.lines = load_from_file(file)
    file:close()
    Text.redraw_all(Editor_state)
    Editor_state.screen_top1 = {line=1, pos=1}
    Editor_state.cursor1 = {line=1, pos=1}
    App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
    print('initializing source position')
    if Settings == nil then Settings = {} end
    if Settings.source == nil then Settings.source = {} end
    App.screen.resize(0, 0) -- maximize
    Display_width, Display_height, App.screen.flags = App.screen.size()
    -- shrink height slightly to account for window decoration
    App.screen.height = Display_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)
    App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
    --? print('loading source position', settings.x, settings.y, settings.displayindex)
    source.set_window_position_from_settings(settings)
    Show_log_browser_side = settings.show_log_browser_side
    local right = App.screen.width - Margin_right
    if Show_log_browser_side then
    right = App.screen.width/2 - Margin_right
    end
    Editor_state = edit.initialize_state(Margin_top, Margin_left, right, settings.font_height, math.floor(settings.font_height*1.3))
    Editor_state.filename = settings.filename
    Editor_state.screen_top1 = settings.screen_top
    Editor_state.cursor1 = settings.cursor
    end
    function source.set_window_position_from_settings(settings)
    -- setPosition doesn't quite seem to do what is asked of it on Linux.
    love.window.setPosition(settings.x, settings.y-37, settings.displayindex)
    end
    function source.initialize_default_settings()
    local font_height = 20
    love.graphics.setFont(love.graphics.newFont(font_height))
    local em = App.newText(love.graphics.getFont(), 'm')
    source.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 source.initialize_window_geometry(em_width)
    -- maximize window
    App.screen.resize(0, 0) -- maximize
    Display_width, Display_height, App.screen.flags = App.screen.size()
    -- set up desired window dimensions
    App.screen.flags.resizable = true
    App.screen.flags.minwidth = math.min(Display_width, 200)
    App.screen.flags.minheight = math.min(Display_height, 200)
    App.screen.width, App.screen.height = settings.width, settings.height
    --? print('setting window from settings:', App.screen.width, App.screen.height)
    -- a few text objects we can avoid recomputing unless the font changes
    Text_cache = {}
    -- blinking cursor
    Cursor_time = 0
    end
    -- called only for real run
    function source.initialize()
    love.keyboard.setTextInput(true) -- bring up keyboard on touch screen
    love.keyboard.setKeyRepeat(true)
    love.graphics.setBackgroundColor(1,1,1)
    if Settings and Settings.source then
    source.load_settings()
    else
    source.initialize_default_settings()
    end
    source.initialize_edit_side{'run.lua'}
    source.initialize_log_browser_side()
    Menu_status_bar_height = 5 + Editor_state.line_height + 5
    Editor_state.top = Editor_state.top + Menu_status_bar_height
    Log_browser_state.top = Log_browser_state.top + Menu_status_bar_height
  • replacement in source_tests.lua at line 10
    [6.147649][6.8:111]()
    check_eq(Editor_state.right, 300 - Test_margin_right, 'F - test_resize_window/baseline/left_margin')
    [6.147649]
    [6.147649]
    check_eq(Editor_state.right, 300 - Test_margin_right, 'F - test_resize_window/baseline/right_margin')
  • edit in source_tests.lua at line 19
    [6.148220]
    [6.148220]
    end
    function test_show_log_browser_side()
    io.write('\ntest_show_log_browser_side')
    App.screen.init{width=300, height=300}
    Display_width = App.screen.width
    Current_app = 'source'
    Editor_state = edit.initialize_test_state()
    Editor_state.filename = 'foo'
    Text.redraw_all(Editor_state)
    Log_browser_state = edit.initialize_test_state()
    Text.redraw_all(Log_browser_state)
    log_browser.parse(Log_browser_state)
    check(not Show_log_browser_side, 'F - test_show_log_browser_side/baseline')
    -- pressing ctrl+l shows log-browser side
    App.wait_fake_time(0.1)
    App.run_after_keychord('C-l')
    check(Show_log_browser_side, 'F - test_show_log_browser_side')
    end
    function test_show_log_browser_side_doubles_window_width_if_possible()
    io.write('\ntest_show_log_browser_side_doubles_window_width_if_possible')
    -- initialize screen dimensions to half width
    App.screen.init{width=300, height=300}
    Display_width = App.screen.width*2
    -- initialize source app with left side occupying entire window (half the display)
    Current_app = 'source'
    Editor_state = edit.initialize_test_state()
    Editor_state.filename = 'foo'
    Editor_state.left = Margin_left
    Editor_state.right = App.screen.width - Margin_right
    local old_editor_right = Editor_state.right
    Text.redraw_all(Editor_state)
    Log_browser_state = edit.initialize_test_state()
    -- log browser has some arbitrary margins
    Log_browser_state.left = 200 + Margin_left
    Log_browser_state.right = 400
    Text.redraw_all(Log_browser_state)
    log_browser.parse(Log_browser_state)
    -- display log browser
    App.wait_fake_time(0.1)
    App.run_after_keychord('C-l')
    -- window width is doubled
    check_eq(App.screen.width, 600, 'F - test_show_log_browser_side_doubles_window_width_if_possible/display:width')
    -- left side margins are unchanged
    check_eq(Editor_state.left, Margin_left, 'F - test_show_log_browser_side_doubles_window_width_if_possible/edit:left')
    check_eq(Editor_state.right, old_editor_right, 'F - test_show_log_browser_side_doubles_window_width_if_possible/edit:right')
    -- log browser margins are adjusted
    check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'F - test_show_log_browser_side_doubles_window_width_if_possible/log:left')
    check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'F - test_show_log_browser_side_doubles_window_width_if_possible/log:right')
    end
    function test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width()
    io.write('\ntest_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width')
    -- initialize screen dimensions and indicate that it is maximized
    App.screen.init{width=300, height=300}
    Display_width = 300
    -- initialize source app with left side occupying more than half the display
    Current_app = 'source'
    Editor_state = edit.initialize_test_state()
    Editor_state.filename = 'foo'
    Editor_state.left = Margin_left
    Editor_state.right = 200
    Text.redraw_all(Editor_state)
    Log_browser_state = edit.initialize_test_state()
    -- log browser has some arbitrary margins
    Log_browser_state.left = 200 + Margin_left
    Log_browser_state.right = 400
    Text.redraw_all(Log_browser_state)
    log_browser.parse(Log_browser_state)
    -- display log browser
    App.wait_fake_time(0.1)
    App.run_after_keychord('C-l')
    -- margins are now adjusted
    check_eq(Editor_state.left, Margin_left, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/edit:left')
    check_eq(Editor_state.right, App.screen.width/2 - Margin_right, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/edit:right')
    check_eq(Log_browser_state.left, App.screen.width/2 + Margin_left, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/log:left')
    check_eq(Log_browser_state.right, App.screen.width - Margin_right, 'F - test_show_log_browser_side_resizes_both_sides_if_cannot_double_window_width/log:right')
  • replacement in source_edit.lua at line 130
    [6.155492][6.155492:155536]()
    assert(#State.lines == #State.line_cache)
    [6.155492]
    [6.155536]
    if #State.lines ~= #State.line_cache then
    print(('line_cache is out of date; %d when it should be %d'):format(#State.line_cache, #State.lines))
    assert(false)
    end
  • replacement in source.lua at line 48
    [6.166582][6.166582:166635]()
    Menu_status_bar_height = nil -- initialized below
    [6.166582]
    [6.166635]
    Menu_status_bar_height = 5 + --[[line height in tests]] 15 + 5
  • replacement in source.lua at line 119
    [6.168663][6.168663:168778]()
    love.window.setMode(0, 0) -- maximize
    Display_width, Display_height, App.screen.flags = love.window.getMode()
    [6.168663]
    [6.168778]
    App.screen.resize(0, 0) -- maximize
    Display_width, Display_height, App.screen.flags = App.screen.size()
  • replacement in source.lua at line 127
    [6.169126][6.169126:169203]()
    love.window.setMode(App.screen.width, App.screen.height, App.screen.flags)
    [6.169126]
    [6.169203]
    App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
  • replacement in source.lua at line 159
    [6.170546][6.170546:170661]()
    love.window.setMode(0, 0) -- maximize
    Display_width, Display_height, App.screen.flags = love.window.getMode()
    [6.170546]
    [6.170661]
    App.screen.resize(0, 0) -- maximize
    Display_width, Display_height, App.screen.flags = App.screen.size()
  • replacement in source.lua at line 167
    [6.170957][6.170957:171034]()
    love.window.setMode(App.screen.width, App.screen.height, App.screen.flags)
    [6.170957]
    [6.171034]
    App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
  • replacement in source.lua at line 171
    [6.171176][6.171176:171273]()
    Settings.source.x, Settings.source.y, Settings.source.displayindex = love.window.getPosition()
    [6.171176]
    [6.171273]
    Settings.source.x, Settings.source.y, Settings.source.displayindex = App.screen.position()
  • replacement in source.lua at line 257
    [6.173872][6.173872:173971]()
    Settings.source.x, Settings.source.y, Settings.source.displayindex = love.window.getPosition()
    [6.173872]
    [6.173971]
    Settings.source.x, Settings.source.y, Settings.source.displayindex = App.screen.position()
  • replacement in source.lua at line 325
    [6.176452][6.176452:176516]()
    App.screen.width = Log_browser_state.right + Margin_right
    [6.176452]
    [6.176516]
    App.screen.width = math.min(Display_width, App.screen.width*2)
    Editor_state.right = App.screen.width/2 - Margin_right
    Log_browser_state.left = App.screen.width/2 + Margin_left
    Log_browser_state.right = App.screen.width - Margin_right
  • replacement in source.lua at line 333
    [6.176662][6.176662:176741]()
    love.window.setMode(App.screen.width, App.screen.height, App.screen.flags)
    [6.176662]
    [6.176741]
    App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)