防止在vim中重复使用hjkl移动键

由于我经常不使用vim提供的优秀动作和文本对象,(因为“压低'j'是vim反模式”),我希望vim帮助我进行培训以使用它们,而不是连续使用hjkl几次以上。

当我开始使用vim时,我很恼火,我没有使用hjkl移动,而是使用箭头键。 为了避免这样做,我重新映射了箭头键以防止使用它们 - 我知道使用家里行来浏览会是一个更好的长期计划,所以我削减了通过工作箭头获得的正面强化键。

map <left> <nop>   
map <right> <nop>  
# I quickly removed nop's for up and down because using 
#  the mouse wheel to scroll is sometimes useful

我不再需要这些映射在我的.vimrc中,因为它工作得很好,而且我很快就切换了,而无需做出有意识的努力。 以类似的方式,我现在想切断我对基本运动键hjkl重复使用。 我在想像这样的事情:

let g:last_mov_key = 'none'
let g:times_mov_key_repeated = 0
function! MovementKey(key)
    if (g:last_mov_key == a:key)
        let g:times_mov_key_repeated = g:times_mov_key_repeated + 1
    else
        let g:last_mov_key = a:key
        let g:times_mov_key_repeated = 0
    endif
    if g:times_mov_key_repeated > 3
        echo "Negative Reinforcement!"                             
    endif
endfunction

noremap j :call MovementKey('j')<CR>gj
noremap k :call MovementKey('k')<CR>gk
noremap h :call MovementKey('h')<CR>h
noremap l :call MovementKey('l')<CR>l

但是,这在视觉模式下打破了,我想象在很多其他情况下,在某些情况下使用vim命令行会改变状态,而不应该改变状态。 我如何限制自己必须使用更复杂的动作?

编辑:为了清晰起见,第一个两个答案后编辑的问题,段落重新排序。 我希望vim的一些帮助超越romainl的“0级”。 到目前为止,答案建议我不要浪费时间,但如果我们认为自己是学习技术的粉丝,通过改变我的环境改变激励机制,改变我的习惯? 在这个模型中,我想完成一项任务,比如说,向下滚动页面,我会或多或少地随机尝试组合键,直到完成该任务。 多巴胺信号等在我脑中会加强最终达到这个结果的行动。 我可以专注于记住不使用hjkl ,或者我可以专注于我最初试图做的任务,编辑文本,而没有真正考虑它,发现自己使用更高效的编辑技术。


我想提出一个更符合OP思路的解决方案。

正如我们在这里讨论的那样,我也决定阻止某些议案,如果没有先前计数是一个好主意。 正如OP所描述的,我也尝试过直接重新映射,但这在许多情况下都不起作用。

但是我最终想出了一种使用返回表达式的关键映射的方法:

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", "gj", "gk"])
    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

请注意,这里包含的代码是为了方便起见,但我也会检查一下是否有更新/修复。

您可以放松对水平运动的约束,或通过在~/.vimrc设置影响的键/命令列表g:keys_to_disable_if_not_preceded_by_count添加/删除其他运动。 例如,以下仅对“j”和“k”执行计数前缀运动:

let g:keys_to_disable_if_not_preceded_by_count = ["j", "k"]

另外,正如在要点中指出的那样,您可能会发现在~/.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

或者安装一个插件行vim-numbers。

尽管这个问题已经(很长时间)回答了OP对另一种方法的满意度,但我在这里添加了我的解决方案,以防有人寻找不同的东西。


你太多地听别人的话了。 只需使用任何您最喜欢的按键进行移动,并单独留下其他按键。 重新映射hjkl键有点麻烦,最好不要完成,因为它们在vim中由于历史原因而被硬编码


编辑

阅读你的编辑和你的评论这里是我提出的激进解决方案:重映射hjkl做超级讨厌的事情:

nnoremap h $
nnoremap l 0
nnoremap j gg
nnoremap k G
" and so on for other modes

hjkl被映射到他们原来的行为的极端,基本上使他们完全无法使用。 为了完整性,你也应该对他们的同义词( :hh:hj:hk:hl )也做同样的事情,但是有些情况下逐个字符/逐行移动是有用的。 在这种情况下,您会很高兴拥有+-<Space>

虽然我不喜欢那种巴洛克式的方法。 我觉得这太残酷了,你真正习惯了这些奇怪的映射的风险似乎相当高。

结束编辑

简洁版本:

箭头键和hjkl都不值得使用,所以你的重映射最终是无用的。 过了一段时间,你会习惯Vim的动作和文本对象。 与此同时,使用对你来说更自然的事物。 不要急于。 它会来。 自然。

长版本:

你是一个触摸打字员吗? 或者你打算学习触摸打字吗?

我不是一个触摸打字员,我不打算永远成为一个:我用hjkl只有实际输入hjkl在插入模式。

当我需要移动1或2行以上或以下而没有特定的“目标”时,我使用箭头键,当我需要将几个字母向左或向右移动时,我使用箭头键。 这样做并不可耻。

然而,当你键入jjjjjjjjjj或者按下10次向下箭头键向下移动10 jjjjjjjjjjj有一个问题: jjjjjjjjjjj显然和↓↓↓↓↓↓↓↓↓↓一样糟糕

“不使用箭头键”这个愚蠢的口头禅就是隐藏森林的树:它经常重复,它使你专注于无用的模式/反模式,而不是实际学习更强大的方法。

我不想复述美丽你对Vim的问题是你不喜欢vi。 但你可以把它看作“启蒙水平”:

  • 等级0将是

    jjjjjjjjjjj或↓↓↓↓↓↓↓↓↓↓然后进行所有必要的水平移动以达到目标。

    读上面的行,是不是很明显, hjkl Vs←↓↑→辩论是绝对愚蠢的?

    无论您使用一种方法还是其他方法,您最终都会将键盘横向移动和水平移动以达到您想要编辑的值。 真是浪费。 多么浪费时间和精力来强迫自己使用一种方法而不是另一种方法,因为两者同样不好。

  • 1级

    10j22l下降10行,到达目标22个字符的权利。 虽然输入少了很多,但现在您必须对线条和字符进行计数,这并不是特别好。

  • 等级2将是

    10jwww向下走10条线,向右移动3个单词或10jf# 10行并跳转到目标的第一个字母(十六进制颜色值)。

    嗯,那好多了。

  • 等级3将是

    /#<CR>直接跳转到目标(十六进制颜色值,和以前一样)。 如果它高于你目前的位置,你会这样做?#<CR>

  • 如果你是一个触摸式打字员,或者正在接受训练,那么辩论就可以解决: hjkl (或jkl;有些人喜欢重新映射它们)是快速和自然的,你根本不需要箭头键,如果你不是,在←↓↑→上使用hjkl的好处最少。

    重点放在eEbBwWfFtT/?}和Co.上。 一次一点。 不要“强迫”你自己。

    链接地址: http://www.djcxy.com/p/49507.html

    上一篇: Preventing repeated use of hjkl movement keys in vim

    下一篇: copy and paste in vi