Skip to main content
Remove unnecessary feedkeys. Just use ex commands.
Source Link
Rich
  • 32.6k
  • 4
  • 74
  • 141

Like Ben and statox, I wouldn't necessarily recommend this, but it is possible:

function FirstPress(c1) abort
  let now = reltime()
  while reltimefloat(reltime(now)) < &timeoutlen / 1000.0
    " See if the user has typed another character
    let c2 = getchar(0)

    if c2 != 0
      " The user typed something. Was it another h?
      if c2 == char2nr(a:c1)
        " The user typed a double h, switch buffers
        callif feedkeys(a:c1 == 'h' 
 ? ":bp\<CR>" : ":bn\<CR>", 't')     bprevious
        else
          bnext
        endif
      else
        " The user typed something else. Switch tabs and replay what they typed
        call feedkeys((a:c1 == 'h' ? 'gT' : 'gt') . nr2char(c2), 't')
      endif
      return
    endif
  endwhile

  " The user didn't press anything. Switch Tabs
  callif feedkeys((a:c1 == 'h' 
 ? 'gT' : 'gt'),tabprevious
 't') else
    tabnext
  endif
endfunction

nnoremap <expr> h (getpos('.')[1] == 1 && getpos('.')[2] == 1) ? ':call FirstPress("h")<CR>' : 'h'
nnoremap <expr> l (getpos('.')[1] == line('$') && (getpos('.')[2] == col('$') - 1 \|\| col('$') == 1)) ? ':call FirstPress("l")<CR>' : 'l'

It works by mapping the single h and l keypresses only, and then in that mapping, checking if the user presses the given key a second time, and acting accordingly.

See also my answer to this recent similar, but slightly different question where the OP wanted to do the first mapping immediately and then perform the second as well if performed within timeoutlen.

Like Ben and statox, I wouldn't necessarily recommend this, but it is possible:

function FirstPress(c1) abort
  let now = reltime()
  while reltimefloat(reltime(now)) < &timeoutlen / 1000.0
    " See if the user has typed another character
    let c2 = getchar(0)

    if c2 != 0
      " The user typed something. Was it another h?
      if c2 == char2nr(a:c1)
        " The user typed a double h, switch buffers
        call feedkeys(a:c1 == 'h' ? ":bp\<CR>" : ":bn\<CR>", 't')
      else
        " The user typed something else. Switch tabs and replay what they typed
        call feedkeys((a:c1 == 'h' ? 'gT' : 'gt') . nr2char(c2), 't')
      endif
      return
    endif
  endwhile

  " The user didn't press anything. Switch Tabs
  call feedkeys((a:c1 == 'h' ? 'gT' : 'gt'), 't')
endfunction

nnoremap <expr> h (getpos('.')[1] == 1 && getpos('.')[2] == 1) ? ':call FirstPress("h")<CR>' : 'h'
nnoremap <expr> l (getpos('.')[1] == line('$') && (getpos('.')[2] == col('$') - 1 \|\| col('$') == 1)) ? ':call FirstPress("l")<CR>' : 'l'

It works by mapping the single h and l keypresses only, and then in that mapping, checking if the user presses the given key a second time, and acting accordingly.

See also my answer to this recent similar, but slightly different question where the OP wanted to do the first mapping immediately and then perform the second as well if performed within timeoutlen.

Like Ben and statox, I wouldn't necessarily recommend this, but it is possible:

function FirstPress(c1) abort
  let now = reltime()
  while reltimefloat(reltime(now)) < &timeoutlen / 1000.0
    " See if the user has typed another character
    let c2 = getchar(0)

    if c2 != 0
      " The user typed something. Was it another h?
      if c2 == char2nr(a:c1)
        " The user typed a double h, switch buffers
        if a:c1 == 'h' 
          bprevious
        else
          bnext
        endif
      else
        " The user typed something else. Switch tabs and replay what they typed
        call feedkeys((a:c1 == 'h' ? 'gT' : 'gt') . nr2char(c2), 't')
      endif
      return
    endif
  endwhile

  " The user didn't press anything. Switch Tabs
  if a:c1 == 'h' 
    tabprevious
  else
    tabnext
  endif
endfunction

nnoremap <expr> h (getpos('.')[1] == 1 && getpos('.')[2] == 1) ? ':call FirstPress("h")<CR>' : 'h'
nnoremap <expr> l (getpos('.')[1] == line('$') && (getpos('.')[2] == col('$') - 1 \|\| col('$') == 1)) ? ':call FirstPress("l")<CR>' : 'l'

It works by mapping the single h and l keypresses only, and then in that mapping, checking if the user presses the given key a second time, and acting accordingly.

See also my answer to this recent similar, but slightly different question where the OP wanted to do the first mapping immediately and then perform the second as well if performed within timeoutlen.

Source Link
Rich
  • 32.6k
  • 4
  • 74
  • 141

Like Ben and statox, I wouldn't necessarily recommend this, but it is possible:

function FirstPress(c1) abort
  let now = reltime()
  while reltimefloat(reltime(now)) < &timeoutlen / 1000.0
    " See if the user has typed another character
    let c2 = getchar(0)

    if c2 != 0
      " The user typed something. Was it another h?
      if c2 == char2nr(a:c1)
        " The user typed a double h, switch buffers
        call feedkeys(a:c1 == 'h' ? ":bp\<CR>" : ":bn\<CR>", 't')
      else
        " The user typed something else. Switch tabs and replay what they typed
        call feedkeys((a:c1 == 'h' ? 'gT' : 'gt') . nr2char(c2), 't')
      endif
      return
    endif
  endwhile

  " The user didn't press anything. Switch Tabs
  call feedkeys((a:c1 == 'h' ? 'gT' : 'gt'), 't')
endfunction

nnoremap <expr> h (getpos('.')[1] == 1 && getpos('.')[2] == 1) ? ':call FirstPress("h")<CR>' : 'h'
nnoremap <expr> l (getpos('.')[1] == line('$') && (getpos('.')[2] == col('$') - 1 \|\| col('$') == 1)) ? ':call FirstPress("l")<CR>' : 'l'

It works by mapping the single h and l keypresses only, and then in that mapping, checking if the user presses the given key a second time, and acting accordingly.

See also my answer to this recent similar, but slightly different question where the OP wanted to do the first mapping immediately and then perform the second as well if performed within timeoutlen.