2

I'm trying to make the EasyMotion-like (cursor jumping) Lightspeed plugin work with Repmo which repeats a previous motion.

So far, (and after many hours), I've come up with the following:

let g:lightspeed_last_motion = ''
augroup lightspeed_last_motion
  autocmd!
  autocmd User LightspeedSxEnter let g:lightspeed_last_motion = 'sx'
  autocmd User LightspeedFtEnter let g:lightspeed_last_motion = 'ft'
augroup end

function! s:LightspeedRepeatMotion(direction) abort
  if index([';', ','], a:direction) < 0
    echomsg 'Invalid direction ' . string(a:direction) . ' passed to ' . FnName()
    return
  endif

  if g:lightspeed_last_motion == 'sx'
    execute "normal \<Plug>Lightspeed_" . a:direction . '_sx'
  else  " Default to ft
    execute "normal \<Plug>Lightspeed_" . a:direction . '_ft'
  endif
endfunction

noremap <Plug>Lightspeed_; :call <SID>LightspeedRepeatMotion(';')<CR>
noremap <Plug>Lightspeed_, :call <SID>LightspeedRepeatMotion(',')<CR>
map  <expr> ; repmo#LastKey("<Plug>Lightspeed_;")|sunmap ;
map  <expr> , repmo#LastRevKey("<Plug>Lightspeed_,")|sunmap ,

map  <expr> s repmo#ZapKey('<Plug>Lightspeed_s')|ounmap s|sunmap s
map  <expr> S repmo#ZapKey('<Plug>Lightspeed_S')|ounmap S|sunmap S
omap <expr> z repmo#ZapKey('<Plug>Lightspeed_s')
omap <expr> Z repmo#ZapKey('<Plug>Lightspeed_S')
map  <expr> f repmo#ZapKey('<Plug>Lightspeed_f')|sunmap f
map  <expr> F repmo#ZapKey('<Plug>Lightspeed_F')|sunmap F
map  <expr> t repmo#ZapKey('<Plug>Lightspeed_t')|sunmap t
map  <expr> T repmo#ZapKey('<Plug>Lightspeed_T')|sunmap T

FnName is defined here.

My problems with the above are:

  • When I try to repeat a motion by pressing ;, I see in the status area:

    • Bottom left: :call <SNR>3_LightspeedRepeatMotion(';')
    • Bottom right: ghtspeed_;

    I want neither of these to display. My attempt at silent didn't work.

    Also, there is a delay, like vim is waiting for another keystroke - the cursor doesn't move immediately.

  • It doesn't work in visual selection mode. I can't work out how to use <Cmd> and still have the mappings work.

  • I don't like using global variable g:lightspeed_last_motion. Different buffers should remember their last motion independent of each other. A simple rename to b: doesn't work. How do I achieve this?

3
  • 1
    You might use <silent> for the mappings for the first bullet. Not sure about the delay or the rest.
    – D. Ben Knoble
    Dec 27 '21 at 22:42
  • 1
    You may also want to try :help map-<nowait>. That will fix the "waiting for another keystroke" problem. With proper application of <silent> and <nowait>, your mappings should work. Jan 7 at 21:51
  • 1
    And also just say :map ; to see if there are conflicts. Also try adding <unique> if you want your scripts to fail if you're worried you're getting hit with this "mapping to a prefix" issue. Jan 7 at 21:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.