On any event we might update the cursor pane's screen top (if it's editable) or the viewport.
Updating the cursor pane's screen top will modify the viewport.
We then update all pane bounds based on the viewport. Pane bounds include screen top. If that was updated already in the event we skip it for that pane.
Still not perfect. Scrolling is jerky in the editable cursor pane.
CZY3IDERLI6MTKKKMX6QLLERSPM2ZJ57NGQRKILJBM7S5PYPQ3XAC TGHAJBESCIEGWUE2D3FGLNOIAYT4D2IRGZKRXRMTUFW7QZETC7OAC UMRNXBPB2VOBLHHWVNFQDF5YYQ3IWYHSGFUTXURKYW4MZLPB33BQC SKMUH5RWOBUHRAQ3TUEIH5EEHN3YOC35GJOJY7GPY7VY6QXLSODAC HOSPP2ANSW654DYRTC6CQUQA2GUKV6T2FI7QBKXD2DZS3R32IMGAC ODLKHO7BO2AODYO2OEQ6D4NSNBT5GR3CKLUXWMDLRYXL7DJOI7BAC BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC J3ER7DFO2TXYUMJAXZUFEHQNLFDNIXSYDTE7HEFGQ2RYB3A6RFPAC OTIBCAUJ3KDQJLVDN3A536DLZGNRYMGJLORZVR3WLCGXGO6UGO6AC 7AKT7IKOP6VQW3CABAVXCEZTHYNAETVXGFIQWB2L6I7LM7T57HAAC HCLCAFHPRUDGNFOYXKNHME2ELQKSXUTN3E4NV3PT4DGG2VJV7KOAC AJB4LFRBMIRBEDWJ3OW7GQIMD2BZBVQ62GH4TE2FISWZKSAHRF4QC MO4B3HJQL7KU2CETG74EV367YPREQN3Z5DJP2MNHITVW2KQRXRCAC C6URZ2NHYH7PIIP4Q2ZB52LQAVNRENTVMNFQPH6L72QY6OR2NB6QC EWK46OTWI2QK7ZZGYOCWWBHXHBXZQWR2FDW6LRTTKCN4K3ZFE5JAC SYS77RM72TL7SLUQIJBN6D7DI5I6HSHCHXLPXREPADUNBBFM5TYAC NR4MDLT4RL46HGPFOH24XD5TWF4WJIWJZQGQEQAGZ2EUM5C7FUZQC 4BX4GJEWW7Z5LA4SJUXADYLAHOYFL4IBOYH4J4DJYRAVKKGGFHGQC VSMPAAJDBVZXZIUFCXY53VM5F63B3ZOS63MCIHH43OA3SKVMJJ7AC DGMHQDVOII6WF2OJNHP42AYYMCMAIM266I3KHED74OBYMIWWAQXQC LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC 2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC ILOA5BYFTQKBSHLFMMZUVPQ2JXBFJD62ERQFBTDK2WSRXUN525VQC function update_pane_bounds(options)local sx = Padding_horizontal + Margin_leftfor column_index, column in ipairs(Surface) doif overlap(sx, sx+Display_settings.column_width, Display_settings.x, Display_settings.x + App.screen.width) thenlocal sy = Margin_topfor pane_index, pane in ipairs(column) doif overlap(sy, sy + Margin_above + Cache[pane.id].height + Margin_below, Display_settings.y, Display_settings.y + App.screen.height) thenif column_index == Cursor_pane.col and pane_index == Cursor_pane.row then-- update the cursor pane either if it's not editable, or-- if it was explicitly requestedif not pane.show_cursor or options == nil or not options.ignore_editable_cursor_pane thenif sy < Display_settings.y thenpane.screen_top1 = schema1_of_y(pane, Display_settings.y - Margin_top)elsepane.screen_top1 = {line=1, pos=1}endendend--? print(('%d,%d: adjusting pane top %d; screen_top is at line %d (max %d)'):format(column_index, pane_index, pane.top, pane.screen_top1.line, #pane.lines))pane.top = sy - Display_settings.y + Margin_above--? print(('pane top is %d'):format(pane.top))pane.left = sx - Display_settings.xpane.right = pane.left + Display_settings.column_widthpane.width = pane.right - pane.leftendsy = sy + Margin_above + Cache[pane.id].height + Margin_below + Padding_verticalendendsx = sx + Margin_right + Display_settings.column_width + Padding_horizontal + Margin_leftendend
--? print('draw pane')if Surface.dirty then--? print(('%d,%d: adjusting pane top %d; screen_top is at line %d (max %d)'):format(column_index, pane_index, pane.top, pane.screen_top1.line, #pane.lines))pane.top = sy - Display_settings.y + Margin_above--? print(('pane top is %d'):format(pane.top))pane.left = sx - Display_settings.xpane.right = pane.left + Display_settings.column_widthpane.width = pane.right - pane.leftend--? print(column_index, pane_index, pane.cursor1.line, pane.cursor1.pos, pane.selection1.line, pane.selection1.pos)
--? print('draw pane', column_index, pane_index, pane.cursor1.line, pane.cursor1.pos, pane.selection1.line, pane.selection1.pos)
local y_offset = ylocal line,pos_index = 1,1Text.populate_screen_line_starting_pos(pane, line)while y_offset >= Line_height dopos_index = pos_index + 1if pos_index > #pane.line_cache[line].screen_line_starting_pos thenline = line+1pos_index = 1Text.populate_screen_line_starting_pos(pane, line)endy_offset = y_offset - Line_heightendreturn {line=line, pos=pane.line_cache[line].screen_line_starting_pos[pos_index]}, y_offset
assert(Text.le1(State.screen_top1, State.cursor1))
if State.show_cursor thenif not Text.le1(State.screen_top1, State.cursor1) thenprint('assertion failure: cursor is above screen top')print('screen top', State.screen_top1.line, State.screen_top1.pos)print('cursor', State.cursor1.line, State.cursor1.pos)assert(false)endend