我正在尝试修改Terry Ma的vim-smooth-scroll,以学习vimscript。此插件可创建“平滑”滚动,因此当我按下<c-j>
时,光标一次向下移动几步,而不是一次向下50行。
脚本如下:
" Scroll the screen up
function! smooth_scroll#up(dist, duration, speed)
call s:smooth_scroll('u', a:dist, a:duration, a:speed)
endfunction
" Scroll the screen down
function! smooth_scroll#down(dist, duration, speed)
call s:smooth_scroll('d', a:dist, a:duration, a:speed)
endfunction
function! s:smooth_scroll(dir, dist, duration, speed)
let s:curr_dir = a:dir
for i in range(a:dist/a:speed)
let start = reltime()
if a:dir ==# 'd'
" break if current direction changes
if s:curr_dir ==# 'u'
break
endif
exec "normal! ".a:speed."\j".a:speed."j"
else
if s:curr_dir ==# 'd'
break
endif
exec "normal! ".a:speed."\k".a:speed."k"
endif
redraw
let elapsed = s:get_ms_since(start)
let snooze = float2nr(a:duration-elapsed)
if snooze > 0
exec "sleep ".snooze."m"
endif
endfor
endfunction
function! s:get_ms_since(time)
let cost = split(reltimestr(reltime(a:time)), '\.')
return str2nr(cost[0])*1000 + str2nr(cost[1])/1000.0
endfunction
noremap <silent> <c-k> :call smooth_scroll#up(&scroll, 150, 2)<CR>
noremap <silent> <c-j> :call smooth_scroll#down(&scroll, 150, 2)<CR>
noremap <silent> <c-b> :call smooth_scroll#up(&scroll*2, 150, 4)<CR>
noremap <silent> <c-f> :call smooth_scroll#down(&scroll*2, 150, 4)<CR>
我有一个变量s:curr_dir
,它理想地跟踪光标移动的当前方向。据我了解,如果我先击<c-j>
,然后再击<c-k>
,则函数smooth_scroll
的两个实例将同时运行。然后,由于s:curr_dir
会发生变化,导致<c-j>
对smooth_scroll
的呼叫被取消。我正在使用neovim,因此我认为这会起作用,因为neovim是“异步的”,但是我肯定会误解。
拥有一个先前被调用但仍在运行的函数的最佳方法是什么,从而意识到某些全局状态已经改变?