由于我经常不使用vim提供的优秀动作和文本对象,(以及"Holding down 'j' is a vim anti-pattern,")我希望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
,或者我可以专注于我最初尝试做的任务,编辑文本,而没有真正考虑它发现自己使用更有效的编辑技术。
答案 0 :(得分:9)
你太聆听别人的意见了。只需使用您最喜欢的任何键移动,并留下其他键。重新映射hjkl
密钥有点麻烦,最好不要这样做,因为由于历史原因它们在vim中hardcoded。
答案 1 :(得分:6)
修改的
在阅读完你的编辑后,你的评论是我提出的根本解决方案:重新映射hjkl
来做超级讨厌的事情:
nnoremap h $
nnoremap l 0
nnoremap j gg
nnoremap k G
" and so on for other modes
hjkl
被映射到与其原始行为极端相反的情况,基本上使它们完全无法使用。您也应该对其同义词(:h h
,:h j
,:h k
,:h l
)执行相同的操作,以确保完整性,但有时会逐个字符/逐行线运动很有用。在这种情况下,您会很高兴+
或-
或<Space>
。
结束编辑
简短版:
箭头键和hjkl
都不值得使用,因此您的重映射最终无用。过了一会儿,你会习惯Vim的动作和文本对象。在此期间使用对您来说更自然的感觉。不要急于求成。它会来。自然。
长版:
你是一名打字员吗?或者你打算学习触摸打字?
我不是一个触摸打字员而且我不打算成为一个:我只使用hjkl
来实际在INSERT模式下输入hjkl
。
当我需要在没有特定“目标”的情况下在上方或下方移动1或2行时,我使用箭头键,当我需要向左或向右移动几个字母时,我使用箭头键。这样做并不可耻。
但是,当您键入jjjjjjjjjj
或按下向下箭头键10次向下移动10行时会出现问题:jjjjjjjjjjj
显然与↓ ↓ ↓ ↓ ↓ ↓ ↓ < KBD>↓ ↓ ↓
这个愚蠢的“不使用箭头键”的口号只是隐藏森林的树:它经常重复,它会让你专注于无用的模式/反模式而不是实际学习更强大的方式。
我不想解释美丽的Your problem with Vim is that you don't grok vi.,但你可以将其视为“启蒙水平”:
等级0 将是
jjjjjjjjjjj
或↓ ↓ ↓ ↓ ↓ < kbd>↓ ↓ ↓ ↓ ↓然后所有必要的水平移动到达目标。
阅读上面的一行,hjkl
Vs ← ↓ ↑ →显而易见辩论绝对是愚蠢的?
无论是使用一种方法还是另一种方法,最终都会使键盘垂直和水平移动以达到要编辑的值。多么浪费。浪费时间和精力迫使自己使用一种方法而不是另一种方法,因为两者都同样糟糕。
等级1 将
10j22l
向下移动10行并向右移动目标22个字符。虽然输入的次数要少得多,但你现在必须计算线条和字符并不是特别好。
等级2 将
10jwww
向下移动10行并向右移动目标3个单词
或10jf#
向下移动10行并跳转到目标的第一个字母(十六进制颜色值)。
等级3 将是
/#<CR>
直接跳到目标(十六进制颜色值,如前所述)。如果它高于您当前的位置,您可以?#<CR>
。
如果你是一个触摸打字员,或者正在接受培训,那么辩论就会得到解决:hjkl
(或jkl;
,因为有些人喜欢重新映射它们)是快速而自然的,你不会需要箭头键,如果不是,使用hjkl
优于← ↓ ↑ →< / kbd>至多是最小的。
专注于eEbBwWfFtT/?}
和公司。一次一点。不要“强迫”自己。
答案 2 :(得分:4)
我发现有一件事是:noremap jj <nop>
。 Vim会推迟j
动作,因为它认为你可能会延长它,这会让你慢下来尝试别的东西。您也无法再按下j
键,因为它只会触发nop。您仍然可以在紧急情况下使用该按钮,但令人沮丧的是让您在日常编辑中避免使用该按钮。
答案 3 :(得分:2)
我想提出一个更符合OP思维方式的解决方案。
我也决定阻止某些动作,如果没有计数之前是一个好主意,正如所讨论here。我也尝试过简单的直接重映射,但是在OP的描述中,这在许多情况下都不起作用。
但我确实最终提出了一种使用key maps that returned an expression的方法:
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
请注意,为方便起见,此处包含代码,但我也会检查gist以查看是否有更新/修复。
你可以放松水平运动的约束,或者
通过设置键/命令列表来添加/删除其他动作
受g:keys_to_disable_if_not_preceded_by_count
影响的~/.vimrc
。
例如,以下仅对&#34; j&#34;强制执行以前计数为前缀的动作。和&#34; k&#34;:
let g:keys_to_disable_if_not_preceded_by_count = ["j", "k"]
此外,正如gist中所述,您可能会发现在~/.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)已经回答OP对替代方法的满意度,但我在这里添加我的解决方案,以防任何人搜索不同的东西。
答案 4 :(得分:0)
我刚刚发现的一个非常特定于平台的解决方案,仅适用于Mac:使用类似vim的东西(我只能在vim模式下将其与PyCharm配合使用),打开MacOS密钥持有*,这使得按住 e 弹出èéêëēėę
以供选择。这使得按住键永远无效!除非您想学会停止按住键,否则这真的很烦人!
如果我能弄清楚如何在我的终端仿真器(iTerm,Terminal.app等)中实现此功能,那么可以使它在正常vim中运行吗?
*如果您被禁用,它将打开此功能:
defaults write -g ApplePressAndHoldEnabled -bool true