我喜欢使用nnoremap
for n
to nzz
,但是当下一场比赛正好在我现在所在的比赛之下,或者两行之下时,当我按下 时,我会迷失方向n
。我想要一个命令来做什么zz
,但前提是光标当前不在中间 10 行中。你能帮助我吗?
问问题
87 次
4 回答
3
nmap n <Plug>VimrcSearch<Plug>VimrcZZifnotinmiddle
nnoremap <Plug>VimrcSearch n
nnoremap <expr> <Plug>VimrcZZifnotinmiddle (abs(winline()-winheight(0)/2)>5 ? 'zz' : '')."\<C-l>"
以上三行是以下解决方法的结果:
- 第一
<Plug>
行和第二行是 a) 避免重映射(实际上是为了避免记住部分可重映射映射未重映射的情况) b) 遵循规则“当使用可重映射映射时,{rhs} 中的每个符号必须以已知方式重映射”。 - 第二
<Plug>
和第三行在那里,因为<expr>
必须在切换到新位置后启动映射。我无法放入n
映射<expr>
,因为zz
在切换到新位置之前将评估带有条件的第二部分。
有一个替代方案:
nnoremap <silent> n n:if abs(winline()-winheight(0)/2)>5<bar>execute 'normal! zz'<bar>endif<CR>
,但<expr>
映射是我想到的第一件事,因此我会保留它。
于 2012-10-15T17:19:38.440 回答
2
对于一个简单的解决方案,您可能需要考虑设置'scrolloff'
为较大的东西。这实际上并不能完全解决您的问题,但它非常简单,因此您可能想先尝试一下。
如果这不令人满意,那么我们可以尝试更重的方法并在你的~/.vimrc
.
nnoremap <silent> n :call Recenter('n', 10)<cr>
nnoremap <silent> N :call Recenter('N', 10)<cr>
function! Recenter(cmd, tolerance)
let ws = line('w0')
let distance = line('w$') - ws
exe 'norm! ' . a:cmd
let tolerance = a:tolerance / 2
let current_offset = line('.') - line('w0')
if line('w0') != ws || (current_offset < (distance/2-tolerance) || current_offset > (distance/2+tolerance))
norm! zz
endif
endfunction
有关更多信息,请参阅:
:h 'scrolloff'
:h line()
:h zz
于 2012-10-15T17:20:56.613 回答
1
于 2012-10-15T17:50:22.307 回答
-1
function! CenterWhenNotAtTheMiddle()
let currentLine = winline()
let offsetFromMiddleLine = 5
let lineBeforeTenMiddleLines = winheight(0) / 2 - offsetFromMiddleLine
let lineAfterTenMiddleLines = winheight(0) / 2 + offsetFromMiddleLine
if currentLine < lineBeforeTenMiddleLines
normal zz
else
if currentLine > linesAfterTenMiddleLines
normal zz
endif
endif
endfunction
nnoremap n n:call CenterWhenNotAtTheMiddle()<Cr>
nnoremap N N:call CenterWhenNotAtTheMiddle()<Cr>
于 2012-10-15T17:49:07.827 回答