Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vim 如果光标不在范围内,则重新绘制_Vim - Fatal编程技术网

Vim 如果光标不在范围内,则重新绘制

Vim 如果光标不在范围内,则重新绘制,vim,Vim,我喜欢将n的nnoremap映射到nzz,但当下一个匹配正好位于我现在所在的匹配项下方,或者在下面两行时,我会在按下n时迷失方向。 我希望有一个命令来执行 ZZ,但是只有当光标当前不在中间10行时。 你能帮我吗 nmap n <Plug>VimrcSearch<Plug>VimrcZZifnotinmiddle nnoremap <Plug>VimrcSearch

我喜欢将
n
nnoremap
映射到
nzz
,但当下一个匹配正好位于我现在所在的匹配项下方,或者在下面两行时,我会在按下
n
时迷失方向。 我希望有一个命令来执行<代码> ZZ,但是只有当光标当前不在中间10行时。 你能帮我吗

nmap            n                          <Plug>VimrcSearch<Plug>VimrcZZifnotinmiddle
nnoremap        <Plug>VimrcSearch          n
nnoremap <expr> <Plug>VimrcZZifnotinmiddle (abs(winline()-winheight(0)/2)>5 ? 'zz' : '')."\<C-l>"
,但映射是我想到的第一件事,因此我将保留它


,但映射是我想到的第一件事,因此我将保留它。

对于一个简单的解决方案,您可能希望将
'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

对于一个简单的解决方案,您可能需要将
'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
函数!中心(当不在中间时)()
让currentLine=winline()
让从中线偏移=5
让lineBeforeTenMiddleLines=winheight(0)/2-从中线偏移
让lineAfterTenMiddleLines=winheight(0)/2+offsetFromMiddleLine
如果currentLinelinesAfterTenMiddleLines
正常zz
恩迪夫
恩迪夫
端功能
nnoremap n:callcenterwhennotatthemiddle()
nnoremap N:callcenterwhennotatthemiddle()
功能!中心(当不在中间时)()
让currentLine=winline()
让从中线偏移=5
让lineBeforeTenMiddleLines=winheight(0)/2-从中线偏移
让lineAfterTenMiddleLines=winheight(0)/2+offsetFromMiddleLine
如果currentLinelinesAfterTenMiddleLines
正常zz
恩迪夫
恩迪夫
端功能
nnoremap n:callcenterwhennotatthemiddle()
nnoremap N:callcenterwhennotatthemiddle()

:h abs()
用于替换
(当前偏移量<(距离/2-公差)|当前偏移量>(距离/2+公差))
,只需一个条件。我所做的是这个
nnoremap n n n:call Recenter(15)nnoremap n:call Recenter(15)函数!如果(abs(winline()-winheight(0)/2)>a:tolerance)exe'norm,则重新居中(公差)!zz'endif endfunction
多亏了@PeterRincker@ZyX。我检查了你的答案,因为我发现插头的东西让人困惑,所以我只是把
abs()
行放在函数中。再次感谢!和
:h abs()
用一个条件替换
(当前偏移量<(距离/2-公差)|当前偏移量>(距离/2+公差))
。我做的是这个
nnoremap n:call Recenter(15)nnoremap n:call Recenter(15)函数!如果(abs(winline()-winheight(0)/2)>a:tolerance)exe'norm,则重新居中(公差)!zz'endif endfunction
多亏了@PeterRincker@ZyX。我检查了你的答案,因为我发现插头的东西让人困惑,所以我只是把
abs()
行放在函数中。再次感谢!这正是我的第二个解决方案,但比它大13行。这里不需要一个以上的变量。你不需要两个条件:记住
abs()
是“绝对值”的缩写真的有那么难吗?为什么要使用
middleLinesAmount
,如果你把这个幻数放在两个变量名中,它看起来像是用来避免使用幻数的。这些变量的存在是为了让代码更容易理解,我在发布答案时更喜欢这样。可能有阅读答案的人在理解更简洁的代码时有困难。它不会使代码更可读,一点也不会。Vim已经有了描述性函数名,在本例中就足够了。您的变体只是提出了一个问题:“WTF是‘点’?为什么要将点与线进行比较?”。此外,看看如何使用两个point*变量,很明显,这两个“point”都包含在十条中间线中,但声明它们在含义排除之前和之后。如果您认为“what is winline()”函数的含义不明显,那么在注释中对其进行一次描述就足够了。“middleLinesAmount”实际上是“从屏幕中间偏移”,因为中间行的数量是十行,而不是五行。@ZyX,谢谢您的建议。我相应地修改了答案,但我保留了两个条件,因为这更容易理解,而且你的答案显示了abs的方法。这正是我的第二个解决方案,但比这大13行。这里不需要一个以上的变量。你不需要两个条件:记住
abs()
是“绝对值”的缩写真的有那么难吗?为什么要使用
middleLinesAmount
,如果你把这个幻数放在两个变量名中,它看起来像是用来避免使用幻数的。这些变量的存在是为了让代码更容易理解,我在发布答案时更喜欢这样。可能有阅读答案的人在理解更简洁的代码时有困难。它不会使代码更可读,一点也不会。Vim已经有了描述性函数名,在本例中就足够了。您的变体只是提出了一个问题:“WTF是‘点’?为什么要将点与线进行比较?”。此外,看看如何使用两个point*变量,很明显,这两个“point”都包含在十条中间线中,但声明它们在含义排除之前和之后。一种描述
:h 'scrolloff'
:h line()
:h zz
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>