This code implements what you suggest, saving the initial position into the jump list when using a series of Ctrl+D or Ctrl+U motions.
let m = a:motion
let m = v:count.m
execute 'normal!' m
autocmd CursorMoved * autocmd! SaveJump
nnoremap <silent> <C-u> :<C-u>call SaveJump("\<lt>C-u>")<CR>:call SetJump()<CR>
nnoremap <silent> <C-d> :<C-u>call SaveJump("\<lt>C-d>")<CR>:call SetJump()<CR>
The way this works is by creating a
CursorMoved autocmd to track whether the cursor was moved in between a sequence of Ctrl+D and Ctrl+U movements.
Since using a Ctrl+D/Ctrl+U will create the autocmd, we don't need an additional flag to tell whether the last motion was a Ctrl+D/Ctrl+U, we can simply check whether the autocmd exists. If it does, we just remove it, if it doesn't, then we know we're the first of a sequence, so we set a mark with
m' to get us into the jumplist.
The autocmd itself just needs to reset itself, since it's triggered for a motion other than Ctrl+D/Ctrl+U, so just dropping the autocmd will make the next Ctrl+D/Ctrl+U recognize it's the first of a sequence.
Note that the code had to be broken into two separate functions, since the first function (actually executing the motion itself) needs to complete in order for the motion to have effect. Setting the autocmd in that same function has the effect of it triggering right as the function completes, which prevents us from using it to detect repeated motions of the same kind...
This idea could be extended, for instance to check whether the cursor has been moved within the same line and not reset the motion block in that case. (For example, if you'd like to allow for horizontal motion, perhaps to use
$ to inspect the end of a line under
nowrap in between a sequence of Ctrl+D/Ctrl+U motions.) It shouldn't be hard to extend it to cover other similar motions as well.