Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support zt, zz, zb and others #24

Open
schaden-freude opened this issue Oct 4, 2017 · 2 comments
Open

Support zt, zz, zb and others #24

schaden-freude opened this issue Oct 4, 2017 · 2 comments

Comments

@schaden-freude
Copy link

Hey!

Thanks for the plugin; it's amazing.

I was wondering if support for re-positioning the edit window, i.e zt, zz and zb could be added. In addition, it would also be nice to see support for forward and backward searches(n and N), move to top and bottom(gg and G).

@yuttie
Copy link
Owner

yuttie commented Feb 22, 2018

@schaden-freude Thank you for your nice ideas!

Currently, it is not easy to implement a function to let it scroll to a desired position because we need to calculate the adequate impulse for that in advance.

I think an appropriate algorithm for animations of your ideas will be different from the current physical-based implementation.
We need to discuss how can we make these different scrolling algorithms co-exist.

@vilari-mickopf
Copy link

If you are using default params for friction/air drag, then you can use this function:

function! ComforableMotionFindImpulse(diff)
    let l:X = pow(abs(a:diff), 0.5)
    let l:impulse =  0.7642497185838693
                \  +11.916201835589376*l:X
                \   +1.4842847475051253*(pow(l:X, 2))
                \   +0.01733669295908215*(pow(l:X, 3))
                \   -0.00034498320824916107*(pow(l:X, 4))
                \   +2.941264385825093e-06*(pow(l:X, 5))
    return l:impulse
endfunction

Basically, I've played around with simple regression model for predicting the optimal impulse for given amount of lines. Because dataset was completely based on default friction(=80)/air drag(=2), this won't work for any other configuration.

This is my setup based on this configuration:

" Find impulse for given amount of lines
function! ComforableMotionFindImpulse(diff)
    let l:X = pow(abs(a:diff), 0.5)
    let l:impulse =  0.7642497185838693
                \  +11.916201835589376*l:X
                \   +1.4842847475051253*(pow(l:X, 2))
                \   +0.01733669295908215*(pow(l:X, 3))
                \   -0.00034498320824916107*(pow(l:X, 4))
                \   +2.941264385825093e-06*(pow(l:X, 5))
    return l:impulse
endfunction

" Comforable-motion equivalent to zz
function! ComforableMotionCenter(...)
    " Save original cursor position
    let s:orig_line = line('.')
    let s:orig_curs = col('.')

    " Count visble difference to top
    let s:abs_top = line('w0')
    let s:vis_top_diff = 0
    while (line('.') > s:abs_top)
        normal 1k
        let s:vis_top_diff += 1
    endwhile

    let s:vis_center = winheight('.')/2
    let s:vis_center_diff = s:vis_top_diff - s:vis_center

    " Restore original cursor position
    call cursor(s:orig_line, s:orig_curs)

    if s:vis_center_diff == 0
        return
    endif

    if (a:0 > 0 && ((a:1 == 'up' && s:vis_center_diff > 0) ||
                  \ (a:1 == 'down' && s:vis_center_diff < 0)))
        return
    endif

    let l:impulse = ComforableMotionFindImpulse(s:vis_center_diff)
    call comfortable_motion#flick(s:vis_center_diff/abs(s:vis_center_diff)*l:impulse)
endfunction

" Comforable-motion equivalent to zt
function! ComforableMotionTop()
    let s:curLine = line('.')
    let s:curCurs = col('.')
    let s:absTop =  line('w0')
    let s:visTopDif = 0
    while (line('.') > s:absTop )
        normal 1k
        let s:visTopDif = s:visTopDif + 1
    endwhile

    let l:impulse = ComforableMotionFindImpulse(s:visTopDif)
    call comfortable_motion#flick(l:impulse)
    call cursor(s:curLine, s:curCurs)
endfunction

" Comforable-motion equivalent to zb
function! ComforableMotionBottom()
    let s:curLine = line('.')
    let s:curCurs = col('.')
    let s:absTop =  line('w0')
    let s:visTopDif = 0

    " counts difference to top
    while (line('.') > s:absTop )
        normal 1k
        let s:visTopDif = (s:visTopDif + 1)
    endwhile

    let s:visBotDif = winheight('.') - s:visTopDif
    let l:impulse = ComforableMotionFindImpulse(s:visBotDif-1)
    call comfortable_motion#flick(-l:impulse)
    call cursor(s:curLine, s:curCurs)
endfunction

nmap <silent> zz :call ComforableMotionCenter()<CR>
nmap <silent> zt :call ComforableMotionTop()<CR>
nmap <silent> zb :call ComforableMotionBottom()<CR>
nmap <silent> {  {:call ComforableMotionCenter('up')<CR>
nmap <silent> }  }:call ComforableMotionCenter('down')<CR>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants