https://www.hogbaysoftware.com/posts/moby-dick-workout
R53OF3ONKT5VL5BGK63YSN6GXIIAVNYDG4UMHITK72WXFWPJ25MQC
A2NV3WVOKBOWBCSV3K4I6MO5LSVSSUZVNH226HV2HDCOMSPRVSSAC
IMEJA43L3OX7S5KIYLZJ4F3ITACLAA5SZBHSCIJMULCPRSW7LXBAC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
YTSPVDZHEN5LLNMGIBUBLPWFWSFM3SOHBRGWYSDEVFKRTH24ARRQC
PFT5Y2ZYGQA6XXOZ5HH75WVUGA4B3KTDRHSFOZRAUKTPSFOPMNRAC
MGT5FTJ35MGYCQO3TZVK3RYUIN5YX475R4XG7RO42SYLYF4AIKFAC
2RXZ3PGOTTZ6M4R372JXIKPLBQKPVBMAXNPIEO2HZDN4EMYW4GNAC
3CSIZJ33MAZTTJUJX7H2VDJRGZ3A5AWKVSAQIMV3UQACVWNZA6ZAC
C42QQZSFFGU6DZ73MCPGYZJQ675YTMEOJAPQLHKRJLWQH5GMWHMQC
PYGMASTVHDTGX3LDTL364UWXEHVSWQ7STAJLZZI5YY6EA6EEICOAC
AVTNUQYRBW7IX2YQ3KDLVQ23RGW3BAKTAE7P73ASBYNKOHMQMH5AC
3QNOKBFMKBGXBVJIRHR2444JRRMBTABHE4674NR3DT67RRM2X6GAC
function test_up_arrow_scrolls_up_to_final_screen_line()
print('test_up_arrow_scrolls_up_to_final_screen_line')
-- display lines starting just after a long line
App.screen.init{width=25+30, height=60}
Lines = load_array{'abc def', 'ghi', 'jkl', 'mno'}
Line_width = App.screen.width
Cursor1 = {line=2, pos=1}
Screen_top1 = {line=2, pos=1}
Screen_bottom1 = {}
Zoom = 1
local screen_top_margin = 15 -- pixels
local line_height = math.floor(15*Zoom) -- pixels
App.draw()
local y = screen_top_margin
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:1')
y = y + line_height
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:2')
y = y + line_height
App.screen.check(y, 'mno', 'F - test_up_arrow_scrolls_up_to_final_screen_line/baseline/screen:3')
-- after hitting the up arrow the screen scrolls up to final screen line of previous line
App.run_after_keychord('up')
y = screen_top_margin
App.screen.check(y, 'def', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:1')
y = y + line_height
App.screen.check(y, 'ghi', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:2')
y = y + line_height
App.screen.check(y, 'jkl', 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen:3')
check_eq(Screen_top1.line, 1, 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen_top')
check_eq(Screen_top1.pos, 5, 'F - test_up_arrow_scrolls_up_to_final_screen_line/screen_top')
check_eq(Cursor1.line, 1, 'F - test_up_arrow_scrolls_up_to_final_screen_line/cursor')
check_eq(Cursor1.pos, 5, 'F - test_up_arrow_scrolls_up_to_final_screen_line/cursor')
end
function Text.populate_screen_line_starting_pos(line_index)
-- duplicate some logic from Text.draw
local line = Lines[line_index]
if line.fragments == nil then
Text.compute_fragments(line, Line_width)
end
local x = 25
local pos = 1
for _, f in ipairs(line.fragments) do
local frag, frag_text = f.data, f.text
--? print(x, frag)
-- render fragment
local frag_width = math.floor(App.width(frag_text)*Zoom)
if x + frag_width > Line_width then
x = 25
if line.screen_line_starting_pos == nil then
line.screen_line_starting_pos = {1, pos}
else
table.insert(line.screen_line_starting_pos, pos)
end
end
x = x + frag_width
local frag_len = utf8.len(frag)
pos = pos + frag_len
end
end