This makes the keyboard navigation feel more solid.
I'm not bothering to do the same for panning with the mouse. Mostly because I'm lazy, but also as an escape hatch in case I find myself wanting to move the top lower down the screen or something. But it'll still snap back the first time I pan using the keyboard. Let's see how much it matters.
ZHEJFKSLMORNRVOM7ZY7P4WAXIKGTQ5JVRJRWICXNXKF6HJWEFCQC
R5HNWYMH47LWVHS5VVXNR6TCBDXDURVXZ6RCUNFTTTMIXF275ULQC
R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC
OF4P6TYQA7SUF4N2KPDN7LRTIRNXME2IZJHRLFGF3EMDTWZSGOYAC
ZXQ2MMPAOIA4TN3TWMFPXZUL7NUE3EWXLV2JHBQXEINE7WCKFSIQC
7TQAF4BYIK75EEYCCK7VEUSZHNCWMWIA3HZGQKIILYESUZ5ZZRVQC
BF7TW3EKRIDYC6J2Q2J4YOBAVQF55Y3H6KGZIHNXMH4N72MR6GXQC
VZ6UKPE6CW7ZUKUBPUY3XAZL37WILDOTUZLNOM7NZGHS7WVQAXLQC
X7HYGAL2QVKG7M5EMZ2VSH37UYWGE3EPUXYQBJOVL6IGJFZ2I5AAC
compute_viewport_bounds = function()
local xmin, ymin, xmax, ymax
for i,node in ipairs(Surface) do
if node.type == 'text' or node.type == 'rows' or node.type == 'cols' then
if xmin == nil or xmin > node.x then
xmin = node.x
end
if xmax == nil or xmax < node.x+node.w then
xmax = node.x+node.w
end
if ymin == nil or ymin > node.y then
ymin = node.y
end
if ymax == nil or ymax < node.y + node.h then
ymax = node.y+node.w
end
end
end
xmin, ymin = xmin-50, ymin-50
Viewport_bounds.xmin, Viewport_bounds.xmax, Viewport_bounds.ymin, Viewport_bounds.ymax = xmin,xmax, ymin, ymax
end
Viewport_bounds = {}
Viewport.x = Viewport.x + scale(50)
B()
elseif chord == 'pageup' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
B()
elseif chord == 'S-up' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
Viewport.x = math.min(
math.max(Viewport_bounds.xmin, Viewport_bounds.xmax - App.screen.width/Viewport.zoom),
Viewport.x + scale(50))
elseif chord == 'S-down' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
elseif chord == 'pagedown' or chord == 'S-down' then
Viewport.y = math.min(
math.max(
Viewport_bounds.ymin,
Viewport_bounds.ymax - App.screen.width/2/Viewport.zoom), -- conservative; unclear why removing the '/2' makes the bottom inaccessible
Viewport.y + App.screen.height/Viewport.zoom)