Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Disable Basic Motions if not Preceded By a Count
" Notes:
" (1) To enhance the ergonomics of this sufficiently to make it practical, at
" least, until your brain grows a new lobe dedicated to counting line offsets
" in the background while you work, you should either make sure you have
" something like the following in your `~/.vimrc`:
"
" set number
" if has('autocmd')
" augroup vimrc_linenumbering
" autocmd!
" autocmd WinLeave *
" \ if &number |
" \ set norelativenumber |
" \ endif
" autocmd BufWinEnter *
" \ if &number |
" \ set relativenumber |
" \ endif
" autocmd VimEnter *
" \ if &number |
" \ set relativenumber |
" \ endif
" augroup END
" endif
"
" or you have installed a plugin like
" (vim-numbers)[https://github.com/myusuf3/numbers.vim].
"
" (2) You might want to relax the constraint for horizontal motions, or
" add other motions. You can customize the list of motions by
" specifying the keys in the
" `g:keys_to_disable_if_not_preceded_by_count` variable. For example,
" the following only enforces count-prefixed motions for "j" and "k":
"
" let g:keys_to_disable_if_not_preceded_by_count = ["j", "k"]
function! DisableIfNonCounted(move) range
if v:count
return a:move
else
" You can make this do something annoying like:
" echoerr "Count required!"
" sleep 2
return ""
endif
endfunction
function! SetDisablingOfBasicMotionsIfNonCounted(on)
let keys_to_disable = get(g:, "keys_to_disable_if_not_preceded_by_count", ["j", "k", "l", "h"])
if a:on
for key in keys_to_disable
execute "noremap <expr> <silent> " . key . " DisableIfNonCounted('" . key . "')"
endfor
let g:keys_to_disable_if_not_preceded_by_count = keys_to_disable
let g:is_non_counted_basic_motions_disabled = 1
else
for key in keys_to_disable
try
execute "unmap " . key
catch /E31:/
endtry
endfor
let g:is_non_counted_basic_motions_disabled = 0
endif
endfunction
function! ToggleDisablingOfBasicMotionsIfNonCounted()
let is_disabled = get(g:, "is_non_counted_basic_motions_disabled", 0)
if is_disabled
call SetDisablingOfBasicMotionsIfNonCounted(0)
else
call SetDisablingOfBasicMotionsIfNonCounted(1)
endif
endfunction
command! ToggleDisablingOfNonCountedBasicMotions :call ToggleDisablingOfBasicMotionsIfNonCounted()
command! DisableNonCountedBasicMotions :call SetDisablingOfBasicMotionsIfNonCounted(1)
command! EnableNonCountedBasicMotions :call SetDisablingOfBasicMotionsIfNonCounted(0)
DisableNonCountedBasicMotions

@jeetsukumaran would be great if we could set some usage tolerance to use the "avoided keys without counting".

portalgun commented Jul 7, 2017

This is great!
Here is your same come with a few lines to allow you to press just your keys just once, as to prevent bad habits (eg d1j instead of just dj).

let g:lastmove = 1
function! DisableIfNonCounted(move) range
    if g:lastmove != a:move
        let g:lastmove = a:move
        return a:move
    else
        if v:count
            let g:lastmove = a:move
            return a:move
        else
            " You can make this do something annoying like:
               " echoerr "Count required!"
               " sleep 2
            return ""
        endif
    endif
    let g:lastmove = a:move
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment