If you're willing to bring a function into the mix I whipped this up. I won't pretend it's super pretty or slick but it seems to do the trick...
let max_gap = 10
let adjust_trigger = 5
let to_scr_end = winheight(0) - winline()
let to_buf_end = getpos('$') - getpos('.')
if to_buf_end < adjust_trigger && to_scr_end > max_gap
exe "norm! " . (to_scr_end - max_gap) . "\<c-y>"
Along with this override of
nnoremap zz :call ModifiedZZ()<cr>
The script checks cursor position relative to end of buffer and its distance to the bottom of the screen right after the
If the cursor is within 5 lines of the end of the buffer but there's a gap of more than 10 between the cursor and window edge then the screen is shifted down, shrinking the gap to no more than 10.
You can tune it by adjusting
Update: Here's a cleaned up, simplified and improved version of the function. With the original function, the logic for adjusting the screen is wacky. Where text will end up afterwards is hard to predict and depends on where the cursor is (though it does fulfill the main objective of limiting the number of gap lines).
With the version below, if after
zz is run the number of empty/gap lines is more than
l:max_gap_lines then the script will adjust the buffer so that the number of gap lines is exactly
l:max_gap_lines. (If line wrapping is turned on and there are wrapping lines after the cursor there may be slight discrepancies...but, hey, this is a freebie what do you want? ;)
What that means is that the function will position the buffer text identically for any cursor position that would cause the baseline
zz operation to show more gap lines than allowed. For all other cursor positions the function will operate exactly like baseline
Just try it, you'll see what I mean. :)
" maximum allowed gap lines (lines beyond buffer text)
let l:max_gap_lines = 10
let l:to_scr_end = winheight(0) - winline()
let l:to_buf_end = getpos('$') - getpos('.')
let l:adjustment = l:to_scr_end - l:to_buf_end - l:max_gap_lines
if l:adjustment > 0
exe "norm! " . l:adjustment . "\<c-y>"
Notice that there's only one tunable value in this version.