wrap lines like lines2 forks

akkartik
Aug 16, 2025, 5:45 PM
RLCO2SNKO5OJBEQFRXTB7TCAES6KML4IBOCW5SA7Q24RALW6JCWQC

Dependencies

  • [2] AQMZJXUR use editor state font for width calculations
  • [3] F4RUTOND split up editor tests between LÖVE 11 and LÖVE 12
  • [4] JLU2RMC4 allow Text.nearest_pos_less_than to return 0
  • [5] R5OKMVVC fix a regression in line wrapping
  • [6] HGC5RGJP switch to line index in a function
  • [7] ISOFHXB2 App.width can no longer take a Text
  • [8] UPCIYZEU drop an unnecessary level of indent
  • [9] H4R5BHVY no more Text allocations
  • [10] QYIFOHW3 first test!
  • [11] 3OC7AIC7 exclude left margin from my word-split heuristic
  • [12] OI4FPFIN support drawings in the source editor
  • [13] NDHQN23G done passing left/right margins everywhere
  • [14] ILOA5BYF separate data structure for each line's cache data
  • [15] AIHGJ4BT bugfix: infinite loop inside a very narrow window
  • [16] LAW2O3NW extract variable Margin_left
  • [17] FBVUNLS4 clean up some debug prints
  • [18] S2QMLRXL stop creating a singleton table for every word
  • [19] OYVFFWBK move
  • [20] I64IPGJX avoid saving fragments in lines
  • [21] PFT5Y2ZY move
  • [*] BULPIBEG beginnings of a module for the text editor
  • [*] PLKNHYZ4 extract a function

Change contents

  • replacement in text_tests_love12.lua at line 364
    [3.13938][3.13938:13978]()
    App.screen.check(y, 'de', 'screen:2')
    [3.13938]
    [3.13978]
    App.screen.check(y, 'def', 'screen:2')
  • replacement in text_tests_love12.lua at line 366
    [3.14013][3.14013:14054]()
    App.screen.check(y, 'fgh', 'screen:3')
    [3.14013]
    [3.14054]
    App.screen.check(y, 'gh', 'screen:3')
  • replacement in text_tests_love12.lua at line 370
    [3.14099][3.14099:14138]()
    App.screen.init{width=60, height=60}
    [3.14099]
    [3.14138]
    App.screen.init{width=54, height=60}
  • replacement in text_tests_love12.lua at line 432
    [3.16680][3.16680:16723]()
    App.screen.check(y, 'e fgh', 'screen:2')
    [3.16680]
    [3.16723]
    App.screen.check(y, 'e fghi', 'screen:2')
  • replacement in text_tests_love12.lua at line 434
    [3.16758][3.16758:16799]()
    App.screen.check(y, 'ijk', 'screen:3')
    [3.16758]
    [3.16799]
    App.screen.check(y, 'jk', 'screen:3')
  • replacement in text_tests_love12.lua at line 447
    [3.17258][3.17258:17299]()
    App.screen.check(y, 'mad', 'screen:1')
    [3.17258]
    [3.17299]
    App.screen.check(y, 'mada', 'screen:1')
  • replacement in text_tests_love12.lua at line 449
    [3.17334][3.17334:17376]()
    App.screen.check(y, 'am I', 'screen:2')
    [3.17334]
    [3.17376]
    App.screen.check(y, 'm ', 'screen:2')
  • replacement in text_tests_love12.lua at line 451
    [3.17411][3.17411:17455]()
    App.screen.check(y, '’m a', 'screen:3')
    [3.17411]
    [3.17455]
    App.screen.check(y, 'I’m ad', 'screen:3')
  • replacement in text_tests_love12.lua at line 467
    [3.17983][3.17983:18036]()
    App.screen.check(y, "I'm ad", 'baseline/screen:2')
    [3.17983]
    [3.18036]
    App.screen.check(y, "I'm ada", 'baseline/screen:2')
  • replacement in text_tests_love12.lua at line 473
    [3.18317][3.18317:18372]()
    check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
    [3.18317]
    [3.18372]
    check_eq(Editor_state.cursor1.pos, 14, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 487
    [3.18872][3.18872:18925]()
    App.screen.check(y, "I'm ad", 'baseline/screen:2')
    [3.18872]
    [3.18925]
    App.screen.check(y, "I'm ada", 'baseline/screen:2')
  • replacement in text_tests_love12.lua at line 493
    [3.19206][3.19206:19261]()
    check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
    [3.19206]
    [3.19261]
    check_eq(Editor_state.cursor1.pos, 14, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 509
    [3.19791][3.19791:19844]()
    App.screen.check(y, "I'm ad", 'baseline/screen:2')
    [3.19791]
    [3.19844]
    App.screen.check(y, "I'm ada", 'baseline/screen:2')
  • replacement in text_tests_love12.lua at line 511
    [3.19879][3.19879:19928]()
    App.screen.check(y, 'am', 'baseline/screen:3')
    [3.19879]
    [3.19928]
    App.screen.check(y, 'm', 'baseline/screen:3')
  • replacement in text_tests_love12.lua at line 532
    [3.20807][3.20807:20862]()
    App.screen.check(y, 'I’m ad', 'baseline/screen:2')
    [3.20807]
    [3.20862]
    App.screen.check(y, 'I’m ada', 'baseline/screen:2')
  • replacement in text_tests_love12.lua at line 534
    [3.20897][3.20897:20946]()
    App.screen.check(y, 'am', 'baseline/screen:3')
    [3.20897]
    [3.20946]
    App.screen.check(y, 'm', 'baseline/screen:3')
  • replacement in text_tests_love12.lua at line 726
    [3.28390][3.28390:28430]()
    App.screen.check(y, 'de', 'screen:2')
    [3.28390]
    [3.28430]
    App.screen.check(y, 'def', 'screen:2')
  • replacement in text_tests_love12.lua at line 728
    [3.28465][3.28465:28505]()
    App.screen.check(y, 'fg', 'screen:3')
    [3.28465]
    [3.28505]
    App.screen.check(y, 'g', 'screen:3')
  • replacement in text_tests_love12.lua at line 871
    [3.34571][3.34571:34620]()
    App.screen.check(y, 'ab', 'baseline:screen:1')
    [3.34571]
    [3.34620]
    App.screen.check(y, 'abc', 'baseline:screen:1')
  • replacement in text_tests_love12.lua at line 873
    [3.34655][3.34655:34705]()
    App.screen.check(y, 'cde', 'baseline:screen:2')
    [3.34655]
    [3.34705]
    App.screen.check(y, 'de', 'baseline:screen:2')
  • replacement in text_tests_love12.lua at line 1034
    [3.42080][3.42080:42131]()
    App.screen.check(y, 'def ', 'baseline/screen:2')
    [3.42080]
    [3.42131]
    App.screen.check(y, 'def g', 'baseline/screen:2')
  • replacement in text_tests_love12.lua at line 1036
    [3.42166][3.42166:42217]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3')
    [3.42166]
    [3.42217]
    App.screen.check(y, 'hi ', 'baseline/screen:3')
  • replacement in text_tests_love12.lua at line 1040
    [3.42408][3.42408:42470]()
    check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')
    [3.42408]
    [3.42470]
    check_eq(Editor_state.screen_top1.pos, 10, 'screen_top:pos')
  • replacement in text_tests_love12.lua at line 1042
    [3.42493][3.42493:42535]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.42493]
    [3.42535]
    App.screen.check(y, 'hi ', 'screen:1')
  • replacement in text_tests_love12.lua at line 1044
    [3.42570][3.42570:42612]()
    App.screen.check(y, 'jkl ', 'screen:2')
    [3.42570]
    [3.42612]
    App.screen.check(y, 'jkl m', 'screen:2')
  • replacement in text_tests_love12.lua at line 1046
    [3.42647][3.42647:42689]()
    App.screen.check(y, 'mno ', 'screen:3')
    [3.42647]
    [3.42689]
    App.screen.check(y, 'no p', 'screen:3')
  • replacement in text_tests_love12.lua at line 1055
    [3.42969][3.42969:43055]()
    Editor_state.cursor1 = {line=1, pos=9}
    Editor_state.screen_top1 = {line=1, pos=9}
    [3.42969]
    [3.43055]
    Editor_state.cursor1 = {line=1, pos=10}
    Editor_state.screen_top1 = {line=1, pos=10}
  • replacement in text_tests_love12.lua at line 1061
    [3.43239][3.43239:43301]()
    check_eq(Editor_state.screen_top1.pos, 9, 'screen_top:pos')
    [3.43239]
    [3.43301]
    check_eq(Editor_state.screen_top1.pos, 10, 'screen_top:pos')
  • replacement in text_tests_love12.lua at line 1147
    [3.46847][3.46847:46913]()
    Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
    [3.46847]
    [3.46913]
    Editor_state.lines = load_array{'abc', 'def', 'ghij kl', 'mno'}
  • replacement in text_tests_love12.lua at line 1157
    [3.47256][3.47256:47354]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
    [3.47256]
    [3.47354]
    App.screen.check(y, 'ghij ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
  • replacement in text_tests_love12.lua at line 1162
    [3.47595][3.47595:47649]()
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
    [3.47595]
    [3.47649]
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 1166
    [3.47748][3.47748:47790]()
    App.screen.check(y, 'ghi ', 'screen:2')
    [3.47748]
    [3.47790]
    App.screen.check(y, 'ghij ', 'screen:2')
  • replacement in text_tests_love12.lua at line 1168
    [3.47825][3.47825:47866]()
    App.screen.check(y, 'jkl', 'screen:3')
    [3.47825]
    [3.47866]
    App.screen.check(y, 'kl', 'screen:3')
  • replacement in text_tests_love12.lua at line 1185
    [3.48539][3.48539:48590]()
    App.screen.check(y, 'ghij', 'baseline/screen:3')
    [3.48539]
    [3.48590]
    App.screen.check(y, 'ghijk', 'baseline/screen:3')
  • replacement in text_tests_love12.lua at line 1190
    [3.48831][3.48831:48885]()
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
    [3.48831]
    [3.48885]
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 1194
    [3.48984][3.48984:49026]()
    App.screen.check(y, 'ghij', 'screen:2')
    [3.48984]
    [3.49026]
    App.screen.check(y, 'ghijk', 'screen:2')
  • replacement in text_tests_love12.lua at line 1196
    [3.49061][3.49061:49101]()
    App.screen.check(y, 'kl', 'screen:3')
    [3.49061]
    [3.49101]
    App.screen.check(y, 'l', 'screen:3')
  • replacement in text_tests_love12.lua at line 1212
    [3.49691][3.49691:49742]()
    App.screen.check(y, 'ghij', 'baseline/screen:3')
    [3.49691]
    [3.49742]
    App.screen.check(y, 'ghijk', 'baseline/screen:3')
  • replacement in text_tests_love12.lua at line 1222
    [3.50354][3.50354:50408]()
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
    [3.50354]
    [3.50408]
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 1224
    [3.50431][3.50431:50473]()
    App.screen.check(y, 'ghij', 'screen:1')
    [3.50431]
    [3.50473]
    App.screen.check(y, 'ghijk', 'screen:1')
  • replacement in text_tests_love12.lua at line 1226
    [3.50508][3.50508:50548]()
    App.screen.check(y, 'kl', 'screen:2')
    [3.50508]
    [3.50548]
    App.screen.check(y, 'l', 'screen:2')
  • replacement in text_tests_love12.lua at line 1338
    [3.55198][3.55198:55243]()
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.55198]
    [3.55243]
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1341
    [3.55298][3.55298:55348]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.55298]
    [3.55348]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love12.lua at line 1347
    [3.55583][3.55583:55625]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.55583]
    [3.55625]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love12.lua at line 1349
    [3.55660][3.55660:55701]()
    App.screen.check(y, 'jkl', 'screen:2')
    [3.55660]
    [3.55701]
    App.screen.check(y, 'kl', 'screen:2')
  • replacement in text_tests_love12.lua at line 1471
    [3.60872][3.60872:60958]()
    Editor_state.cursor1 = {line=2, pos=5}
    Editor_state.screen_top1 = {line=2, pos=5}
    [3.60872]
    [3.60958]
    Editor_state.cursor1 = {line=2, pos=6}
    Editor_state.screen_top1 = {line=2, pos=6}
  • replacement in text_tests_love12.lua at line 1475
    [3.61013][3.61013:61063]()
    App.screen.check(y, 'jkl', 'baseline/screen:2')
    [3.61013]
    [3.61063]
    App.screen.check(y, 'kl', 'baseline/screen:2')
  • replacement in text_tests_love12.lua at line 1488
    [3.61664][3.61664:61706]()
    App.screen.check(y, 'ghi ', 'screen:3')
    [3.61664]
    [3.61706]
    App.screen.check(y, 'ghi j', 'screen:3')
  • replacement in text_tests_love12.lua at line 1563
    [3.64816][3.64816:64878]()
    Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
    [3.64816]
    [3.64878]
    Editor_state.lines = load_array{'abc', 'def', 'ghi', 'pqr'}
  • replacement in text_tests_love12.lua at line 1584
    [3.65751][3.65751:65793]()
    App.screen.check(y, 'ghij', 'screen:2')
    [3.65751]
    [3.65793]
    App.screen.check(y, 'ghijk', 'screen:2')
  • replacement in text_tests_love12.lua at line 1586
    [3.65828][3.65828:65868]()
    App.screen.check(y, 'kl', 'screen:3')
    [3.65828]
    [3.65868]
    App.screen.check(y, 'l', 'screen:3')
  • replacement in text_tests_love12.lua at line 1595
    [3.66190][3.66190:66235]()
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.66190]
    [3.66235]
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1597
    [3.66267][3.66267:66308]()
    Editor_state.cursor1 = {line=3, pos=5}
    [3.66267]
    [3.66308]
    Editor_state.cursor1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1600
    [3.66363][3.66363:66413]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.66363]
    [3.66413]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love12.lua at line 1606
    [3.66654][3.66654:66696]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.66654]
    [3.66696]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love12.lua at line 1608
    [3.66731][3.66731:66772]()
    App.screen.check(y, 'jkl', 'screen:2')
    [3.66731]
    [3.66772]
    App.screen.check(y, 'kl', 'screen:2')
  • replacement in text_tests_love12.lua at line 1614
    [3.67030][3.67030:67084]()
    check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
    [3.67030]
    [3.67084]
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 1625
    [3.67503][3.67503:67544]()
    Editor_state.cursor1 = {line=3, pos=5}
    [3.67503]
    [3.67544]
    Editor_state.cursor1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1632
    [3.67769][3.67769:67867]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
    [3.67769]
    [3.67867]
    App.screen.check(y, 'ghi j', 'baseline/screen:3') -- line wrapping includes trailing whitespace
  • replacement in text_tests_love12.lua at line 1637
    [3.68111][3.68111:68165]()
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
    [3.68111]
    [3.68165]
    check_eq(Editor_state.cursor1.pos, 7, 'cursor:pos')
  • replacement in text_tests_love12.lua at line 1641
    [3.68264][3.68264:68306]()
    App.screen.check(y, 'ghi ', 'screen:2')
    [3.68264]
    [3.68306]
    App.screen.check(y, 'ghi j', 'screen:2')
  • replacement in text_tests_love12.lua at line 1643
    [3.68341][3.68341:68382]()
    App.screen.check(y, 'jkl', 'screen:3')
    [3.68341]
    [3.68382]
    App.screen.check(y, 'kl', 'screen:3')
  • replacement in text_tests_love12.lua at line 1652
    [3.68698][3.68698:68743]()
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.68698]
    [3.68743]
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1654
    [3.68775][3.68775:68816]()
    Editor_state.cursor1 = {line=3, pos=5}
    [3.68775]
    [3.68816]
    Editor_state.cursor1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1657
    [3.68871][3.68871:68921]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.68871]
    [3.68921]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love12.lua at line 1663
    [3.69152][3.69152:69194]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.69152]
    [3.69194]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love12.lua at line 1665
    [3.69229][3.69229:69270]()
    App.screen.check(y, 'jkl', 'screen:2')
    [3.69229]
    [3.69270]
    App.screen.check(y, 'kl', 'screen:2')
  • replacement in text_tests_love12.lua at line 1689
    [3.70259][3.70259:70357]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
    [3.70259]
    [3.70357]
    App.screen.check(y, 'ghi j', 'baseline/screen:3')
  • replacement in text_tests_love12.lua at line 1698
    [3.70738][3.70738:70780]()
    App.screen.check(y, 'ghi ', 'screen:2')
    [3.70738]
    [3.70780]
    App.screen.check(y, 'ghi j', 'screen:2')
  • replacement in text_tests_love12.lua at line 1700
    [3.70815][3.70815:70856]()
    App.screen.check(y, 'jkl', 'screen:3')
    [3.70815]
    [3.70856]
    App.screen.check(y, 'kl', 'screen:3')
  • replacement in text_tests_love12.lua at line 1769
    [3.73816][3.73816:73902]()
    Editor_state.cursor1 = {line=3, pos=5}
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.73816]
    [3.73902]
    Editor_state.cursor1 = {line=3, pos=6}
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love12.lua at line 1773
    [3.73957][3.73957:74007]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.73957]
    [3.74007]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love12.lua at line 1779
    [3.74251][3.74251:74293]()
    App.screen.check(y, 'ghij', 'screen:1')
    [3.74251]
    [3.74293]
    App.screen.check(y, 'ghi k', 'screen:1')
  • replacement in text_tests_love12.lua at line 1781
    [3.74328][3.74328:74368]()
    App.screen.check(y, 'kl', 'screen:2')
    [3.74328]
    [3.74368]
    App.screen.check(y, 'l', 'screen:2')
  • replacement in text_tests_love12.lua at line 1787
    [3.74626][3.74626:74680]()
    check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
    [3.74626]
    [3.74680]
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 364
    [3.101547][3.101547:101587]()
    App.screen.check(y, 'de', 'screen:2')
    [3.101547]
    [3.101587]
    App.screen.check(y, 'def', 'screen:2')
  • replacement in text_tests_love11.lua at line 366
    [3.101622][3.101622:101663]()
    App.screen.check(y, 'fgh', 'screen:3')
    [3.101622]
    [3.101663]
    App.screen.check(y, 'gh', 'screen:3')
  • replacement in text_tests_love11.lua at line 370
    [3.101708][3.101708:101747]()
    App.screen.init{width=60, height=60}
    [3.101708]
    [3.101747]
    App.screen.init{width=54, height=60}
  • replacement in text_tests_love11.lua at line 432
    [3.104289][3.104289:104332]()
    App.screen.check(y, 'e fgh', 'screen:2')
    [3.104289]
    [3.104332]
    App.screen.check(y, 'e fghi', 'screen:2')
  • replacement in text_tests_love11.lua at line 434
    [3.104367][3.104367:104408]()
    App.screen.check(y, 'ijk', 'screen:3')
    [3.104367]
    [3.104408]
    App.screen.check(y, 'jk', 'screen:3')
  • replacement in text_tests_love11.lua at line 447
    [3.104867][3.104867:104908]()
    App.screen.check(y, 'mad', 'screen:1')
    [3.104867]
    [3.104908]
    App.screen.check(y, 'mada', 'screen:1')
  • replacement in text_tests_love11.lua at line 449
    [3.104943][3.104943:104985]()
    App.screen.check(y, 'am I', 'screen:2')
    [3.104943]
    [3.104985]
    App.screen.check(y, 'm I’', 'screen:2')
  • replacement in text_tests_love11.lua at line 451
    [3.105020][3.105020:105064]()
    App.screen.check(y, '’m a', 'screen:3')
    [3.105020]
    [3.105064]
    App.screen.check(y, 'm ad', 'screen:3')
  • replacement in text_tests_love11.lua at line 467
    [3.105592][3.105592:105645]()
    App.screen.check(y, "I'm ad", 'baseline/screen:2')
    [3.105592]
    [3.105645]
    App.screen.check(y, "I'm ada", 'baseline/screen:2')
  • replacement in text_tests_love11.lua at line 473
    [3.105926][3.105926:105981]()
    check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
    [3.105926]
    [3.105981]
    check_eq(Editor_state.cursor1.pos, 14, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 487
    [3.106481][3.106481:106534]()
    App.screen.check(y, "I'm ad", 'baseline/screen:2')
    [3.106481]
    [3.106534]
    App.screen.check(y, "I'm ada", 'baseline/screen:2')
  • replacement in text_tests_love11.lua at line 493
    [3.106815][3.106815:106870]()
    check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
    [3.106815]
    [3.106870]
    check_eq(Editor_state.cursor1.pos, 14, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 509
    [3.107400][3.107400:107453]()
    App.screen.check(y, "I'm ad", 'baseline/screen:2')
    [3.107400]
    [3.107453]
    App.screen.check(y, "I'm ada", 'baseline/screen:2')
  • replacement in text_tests_love11.lua at line 511
    [3.107488][3.107488:107537]()
    App.screen.check(y, 'am', 'baseline/screen:3')
    [3.107488]
    [3.107537]
    App.screen.check(y, 'm', 'baseline/screen:3')
  • replacement in text_tests_love11.lua at line 532
    [3.108416][3.108416:108471]()
    App.screen.check(y, 'I’m ad', 'baseline/screen:2')
    [3.108416]
    [3.108471]
    App.screen.check(y, 'I’m ada', 'baseline/screen:2')
  • replacement in text_tests_love11.lua at line 534
    [3.108506][3.108506:108555]()
    App.screen.check(y, 'am', 'baseline/screen:3')
    [3.108506]
    [3.108555]
    App.screen.check(y, 'm', 'baseline/screen:3')
  • replacement in text_tests_love11.lua at line 726
    [3.115999][3.115999:116039]()
    App.screen.check(y, 'de', 'screen:2')
    [3.115999]
    [3.116039]
    App.screen.check(y, 'def', 'screen:2')
  • replacement in text_tests_love11.lua at line 728
    [3.116074][3.116074:116114]()
    App.screen.check(y, 'fg', 'screen:3')
    [3.116074]
    [3.116114]
    App.screen.check(y, 'g', 'screen:3')
  • replacement in text_tests_love11.lua at line 871
    [3.122180][3.122180:122229]()
    App.screen.check(y, 'ab', 'baseline:screen:1')
    [3.122180]
    [3.122229]
    App.screen.check(y, 'abc', 'baseline:screen:1')
  • replacement in text_tests_love11.lua at line 873
    [3.122264][3.122264:122314]()
    App.screen.check(y, 'cde', 'baseline:screen:2')
    [3.122264]
    [3.122314]
    App.screen.check(y, 'de', 'baseline:screen:2')
  • replacement in text_tests_love11.lua at line 1036
    [3.129775][3.129775:129826]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3')
    [3.129775]
    [3.129826]
    App.screen.check(y, 'ghi j', 'baseline/screen:3')
  • replacement in text_tests_love11.lua at line 1042
    [3.130102][3.130102:130144]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.130102]
    [3.130144]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love11.lua at line 1044
    [3.130179][3.130179:130221]()
    App.screen.check(y, 'jkl ', 'screen:2')
    [3.130179]
    [3.130221]
    App.screen.check(y, 'kl m', 'screen:2')
  • replacement in text_tests_love11.lua at line 1046
    [3.130256][3.130256:130296]()
    App.screen.check(y, 'mn', 'screen:3')
    [3.130256]
    [3.130296]
    App.screen.check(y, 'no p', 'screen:3')
  • replacement in text_tests_love11.lua at line 1147
    [3.134454][3.134454:134520]()
    Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'}
    [3.134454]
    [3.134520]
    Editor_state.lines = load_array{'abc', 'def', 'ghij kl', 'mno'}
  • replacement in text_tests_love11.lua at line 1157
    [3.134863][3.134863:134961]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
    [3.134863]
    [3.134961]
    App.screen.check(y, 'ghij ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
  • replacement in text_tests_love11.lua at line 1162
    [3.135202][3.135202:135256]()
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
    [3.135202]
    [3.135256]
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 1166
    [3.135355][3.135355:135397]()
    App.screen.check(y, 'ghi ', 'screen:2')
    [3.135355]
    [3.135397]
    App.screen.check(y, 'ghij ', 'screen:2')
  • replacement in text_tests_love11.lua at line 1168
    [3.135432][3.135432:135473]()
    App.screen.check(y, 'jkl', 'screen:3')
    [3.135432]
    [3.135473]
    App.screen.check(y, 'kl', 'screen:3')
  • replacement in text_tests_love11.lua at line 1185
    [3.136146][3.136146:136197]()
    App.screen.check(y, 'ghij', 'baseline/screen:3')
    [3.136146]
    [3.136197]
    App.screen.check(y, 'ghijk', 'baseline/screen:3')
  • replacement in text_tests_love11.lua at line 1190
    [3.136438][3.136438:136492]()
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
    [3.136438]
    [3.136492]
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 1194
    [3.136591][3.136591:136633]()
    App.screen.check(y, 'ghij', 'screen:2')
    [3.136591]
    [3.136633]
    App.screen.check(y, 'ghijk', 'screen:2')
  • replacement in text_tests_love11.lua at line 1196
    [3.136668][3.136668:136708]()
    App.screen.check(y, 'kl', 'screen:3')
    [3.136668]
    [3.136708]
    App.screen.check(y, 'l', 'screen:3')
  • replacement in text_tests_love11.lua at line 1212
    [3.137298][3.137298:137349]()
    App.screen.check(y, 'ghij', 'baseline/screen:3')
    [3.137298]
    [3.137349]
    App.screen.check(y, 'ghijk', 'baseline/screen:3')
  • replacement in text_tests_love11.lua at line 1222
    [3.137961][3.137961:138015]()
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
    [3.137961]
    [3.138015]
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 1224
    [3.138038][3.138038:138080]()
    App.screen.check(y, 'ghij', 'screen:1')
    [3.138038]
    [3.138080]
    App.screen.check(y, 'ghijk', 'screen:1')
  • replacement in text_tests_love11.lua at line 1226
    [3.138115][3.138115:138155]()
    App.screen.check(y, 'kl', 'screen:2')
    [3.138115]
    [3.138155]
    App.screen.check(y, 'l', 'screen:2')
  • replacement in text_tests_love11.lua at line 1338
    [3.142805][3.142805:142850]()
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.142805]
    [3.142850]
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1341
    [3.142905][3.142905:142955]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.142905]
    [3.142955]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love11.lua at line 1347
    [3.143190][3.143190:143232]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.143190]
    [3.143232]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love11.lua at line 1349
    [3.143267][3.143267:143308]()
    App.screen.check(y, 'jkl', 'screen:2')
    [3.143267]
    [3.143308]
    App.screen.check(y, 'kl', 'screen:2')
  • replacement in text_tests_love11.lua at line 1471
    [3.148479][3.148479:148565]()
    Editor_state.cursor1 = {line=2, pos=5}
    Editor_state.screen_top1 = {line=2, pos=5}
    [3.148479]
    [3.148565]
    Editor_state.cursor1 = {line=2, pos=6}
    Editor_state.screen_top1 = {line=2, pos=6}
  • replacement in text_tests_love11.lua at line 1475
    [3.148620][3.148620:148670]()
    App.screen.check(y, 'jkl', 'baseline/screen:2')
    [3.148620]
    [3.148670]
    App.screen.check(y, 'kl', 'baseline/screen:2')
  • replacement in text_tests_love11.lua at line 1488
    [3.149271][3.149271:149313]()
    App.screen.check(y, 'ghi ', 'screen:3')
    [3.149271]
    [3.149313]
    App.screen.check(y, 'ghi j', 'screen:3')
  • replacement in text_tests_love11.lua at line 1563
    [3.152423][3.152423:152485]()
    Editor_state.lines = load_array{'abc', 'def', 'ghi', 'jkl'}
    [3.152423]
    [3.152485]
    Editor_state.lines = load_array{'abc', 'def', 'ghi', 'pqr'}
  • replacement in text_tests_love11.lua at line 1584
    [3.153358][3.153358:153400]()
    App.screen.check(y, 'ghij', 'screen:2')
    [3.153358]
    [3.153400]
    App.screen.check(y, 'ghijk', 'screen:2')
  • replacement in text_tests_love11.lua at line 1586
    [3.153435][3.153435:153475]()
    App.screen.check(y, 'kl', 'screen:3')
    [3.153435]
    [3.153475]
    App.screen.check(y, 'l', 'screen:3')
  • replacement in text_tests_love11.lua at line 1595
    [3.153797][3.153797:153842]()
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.153797]
    [3.153842]
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1597
    [3.153874][3.153874:153915]()
    Editor_state.cursor1 = {line=3, pos=5}
    [3.153874]
    [3.153915]
    Editor_state.cursor1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1600
    [3.153970][3.153970:154020]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.153970]
    [3.154020]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love11.lua at line 1606
    [3.154261][3.154261:154303]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.154261]
    [3.154303]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love11.lua at line 1608
    [3.154338][3.154338:154379]()
    App.screen.check(y, 'jkl', 'screen:2')
    [3.154338]
    [3.154379]
    App.screen.check(y, 'kl', 'screen:2')
  • replacement in text_tests_love11.lua at line 1614
    [3.154637][3.154637:154691]()
    check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
    [3.154637]
    [3.154691]
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 1625
    [3.155110][3.155110:155151]()
    Editor_state.cursor1 = {line=3, pos=5}
    [3.155110]
    [3.155151]
    Editor_state.cursor1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1632
    [3.155376][3.155376:155474]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
    [3.155376]
    [3.155474]
    App.screen.check(y, 'ghi j', 'baseline/screen:3') -- line wrapping includes trailing whitespace
  • replacement in text_tests_love11.lua at line 1637
    [3.155718][3.155718:155772]()
    check_eq(Editor_state.cursor1.pos, 6, 'cursor:pos')
    [3.155718]
    [3.155772]
    check_eq(Editor_state.cursor1.pos, 7, 'cursor:pos')
  • replacement in text_tests_love11.lua at line 1641
    [3.155871][3.155871:155913]()
    App.screen.check(y, 'ghi ', 'screen:2')
    [3.155871]
    [3.155913]
    App.screen.check(y, 'ghi j', 'screen:2')
  • replacement in text_tests_love11.lua at line 1643
    [3.155948][3.155948:155989]()
    App.screen.check(y, 'jkl', 'screen:3')
    [3.155948]
    [3.155989]
    App.screen.check(y, 'kl', 'screen:3')
  • replacement in text_tests_love11.lua at line 1652
    [3.156305][3.156305:156350]()
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.156305]
    [3.156350]
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1654
    [3.156382][3.156382:156423]()
    Editor_state.cursor1 = {line=3, pos=5}
    [3.156382]
    [3.156423]
    Editor_state.cursor1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1657
    [3.156478][3.156478:156528]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.156478]
    [3.156528]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love11.lua at line 1663
    [3.156759][3.156759:156801]()
    App.screen.check(y, 'ghi ', 'screen:1')
    [3.156759]
    [3.156801]
    App.screen.check(y, 'ghi j', 'screen:1')
  • replacement in text_tests_love11.lua at line 1665
    [3.156836][3.156836:156877]()
    App.screen.check(y, 'jkl', 'screen:2')
    [3.156836]
    [3.156877]
    App.screen.check(y, 'kl', 'screen:2')
  • replacement in text_tests_love11.lua at line 1689
    [3.157866][3.157866:157964]()
    App.screen.check(y, 'ghi ', 'baseline/screen:3') -- line wrapping includes trailing whitespace
    [3.157866]
    [3.157964]
    App.screen.check(y, 'ghi j', 'baseline/screen:3')
  • replacement in text_tests_love11.lua at line 1698
    [3.158345][3.158345:158387]()
    App.screen.check(y, 'ghi ', 'screen:2')
    [3.158345]
    [3.158387]
    App.screen.check(y, 'ghi j', 'screen:2')
  • replacement in text_tests_love11.lua at line 1700
    [3.158422][3.158422:158463]()
    App.screen.check(y, 'jkl', 'screen:3')
    [3.158422]
    [3.158463]
    App.screen.check(y, 'kl', 'screen:3')
  • replacement in text_tests_love11.lua at line 1769
    [3.161423][3.161423:161509]()
    Editor_state.cursor1 = {line=3, pos=5}
    Editor_state.screen_top1 = {line=3, pos=5}
    [3.161423]
    [3.161509]
    Editor_state.cursor1 = {line=3, pos=6}
    Editor_state.screen_top1 = {line=3, pos=6}
  • replacement in text_tests_love11.lua at line 1773
    [3.161564][3.161564:161614]()
    App.screen.check(y, 'jkl', 'baseline/screen:1')
    [3.161564]
    [3.161614]
    App.screen.check(y, 'kl', 'baseline/screen:1')
  • replacement in text_tests_love11.lua at line 1779
    [3.161858][3.161858:161900]()
    App.screen.check(y, 'ghij', 'screen:1')
    [3.161858]
    [3.161900]
    App.screen.check(y, 'ghi k', 'screen:1')
  • replacement in text_tests_love11.lua at line 1781
    [3.161935][3.161935:161975]()
    App.screen.check(y, 'kl', 'screen:2')
    [3.161935]
    [3.161975]
    App.screen.check(y, 'l', 'screen:2')
  • replacement in text_tests_love11.lua at line 1787
    [3.162233][3.162233:162287]()
    check_eq(Editor_state.cursor1.pos, 4, 'cursor:pos')
    [3.162233]
    [3.162287]
    check_eq(Editor_state.cursor1.pos, 5, 'cursor:pos')
  • replacement in text.lua at line 94
    [4.124][4.124:168](),[4.168][2.222:271](),[2.271][4.1613:1820](),[4.128][4.1613:1820](),[4.1820][4.234:331](),[4.234][4.234:331](),[4.331][2.272:355](),[2.355][4.0:192](),[4.1892][4.0:192](),[4.192][4.1962:1987](),[4.1962][4.1962:1987](),[4.299][4.509:581](),[4.1987][4.509:581](),[4.509][4.509:581](),[4.362][4.1056:1097](),[4.401][4.1056:1097](),[4.1056][4.1056:1097](),[4.1097][4.1988:2074](),[4.2074][2.356:403](),[4.212][4.1367:1377](),[2.403][4.1367:1377](),[4.621][4.1367:1377](),[4.732][4.1367:1377](),[4.1202][4.1367:1377](),[4.2341][4.1367:1377](),[4.1367][4.1367:1377](),[4.1377][4.2075:2112]()
    for frag in line.data:gmatch('%S*%s*') do
    local frag_width = State.font:getWidth(frag)
    --? print('-- frag:', frag, pos, x, frag_width, State.width)
    while x + frag_width > State.width do
    --? print('frag:', frag, pos, x, frag_width, State.width)
    if x < 0.8 * State.width then
    -- long word; chop it at some letter
    -- We're not going to reimplement TeX here.
    local bpos = Text.nearest_pos_less_than(State.font, frag, State.width - x)
    if x == 0 and bpos == 0 then
    assert(false, ("Infinite loop while line-wrapping. Editor is %dpx wide; window is %dpx wide"):format(State.width, App.screen.width))
    end
    pos = pos + bpos
    local boffset = Text.offset(frag, bpos+1) -- byte _after_ bpos
    frag = string.sub(frag, boffset)
    --? if bpos > 0 then
    --? print('after chop:', frag)
    --? end
    frag_width = State.font:getWidth(frag)
    end
    --? print('screen line:', pos)
    [4.124]
    [4.2112]
    for pos,char in utf8chars(line.data) do
    local w = State.font:getWidth(char)
    if Text.should_word_wrap(State, line.data, pos, char, x)
    or x+w > State.width -- truncate within a word
    then
  • replacement in text.lua at line 100
    [4.2173][4.2173:2205]()
    x = 0 -- new screen line
    [4.2173]
    [4.1549]
    x = 0
    end
    x = x + w
    end
    end
    -- Check whether to word-wrap line at pos which will be positioned at x.
    --
    -- We wrap at the start of a word (non-space just after space) if the word
    -- (non-spaces followed by spaces) wouldn't fit in the rest of the line.
    --
    -- x lies between 0 and editor.width.
    --
    -- Postcondition:
    -- Current line is not wider than editor.width
    --
    -- Desired properties in priority order:
    -- Next line doesn't start with whitespace
    -- Current line ends with whitespace (a.k.a. word wrap)
    -- Current line is close to full
    -- None of these is guaranteed. But we should never satisfy a lower priority
    -- before a higher one.
    function Text.should_word_wrap(editor, line, pos, char, x)
    if char:match('%s') then return false end
    if pos == 1 then return false end
    if Text.match(line, pos-1, '%S') then return false end
    local offset = Text.offset(line, pos)
    -- most of the time a word is printable chars + whitespace
    local s = line:match('%S+%s*', offset)
    assert(s)
    local w = editor.font:getWidth(s)
    if x+w < editor.width then return false end
    if w > editor.width then return false end -- we're going to need to truncate the next word anyway
    if x < 0.8*editor.width then
    local s2 = line:match('%S+', offset)
    local w2 = editor.font:getWidth(s2)
    if x+w2 > editor.width then
    -- there'll be some non-whitespace left over for the next line
    return false
  • edit in text.lua at line 140
    [4.1557][4.1604:1627](),[4.1627][4.2206:2237]()
    x = x + frag_width
    pos = pos + utf8.len(frag)
  • edit in text.lua at line 141
    [4.1563]
    [4.1563]
    return true
  • edit in text.lua at line 1119
    [24.442]
    -- create a new iterator for s which provides the index and UTF-8 bytes corresponding to each codepoint
    function utf8chars(s, startpos)
    local next_pos = startpos or 1 -- in code points
    local next_offset = utf8.offset(s, next_pos) -- in bytes
    return function()
    assert(next_offset) -- never call the iterator after it returns nil
    local curr_pos = next_pos
    next_pos = next_pos+1
    local curr_offset = next_offset
    next_offset = utf8.offset(s, 2, next_offset)
    if next_offset == nil then return end
    local curr_char = s:sub(curr_offset, next_offset-1)
    return curr_pos, curr_char
    end
    end