防止在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.上。 一次一点。 不要“强迫”你自己。
上一篇: Preventing repeated use of hjkl movement keys in vim
下一篇: copy and paste in vi