当光标位于屏幕中间时,向下滚动,光标在屏幕上向上移动。我不希望它那样做。Vim滚动时不改变光标在屏幕上的位置
如何在不改变游标屏幕位置的情况下滚动?
解决方案,答案后说:
noremap <C-k> 14j14<C-e>
noremap <C-l> 14k14<C-y>
当光标位于屏幕中间时,向下滚动,光标在屏幕上向上移动。我不希望它那样做。Vim滚动时不改变光标在屏幕上的位置
如何在不改变游标屏幕位置的情况下滚动?
解决方案,答案后说:
noremap <C-k> 14j14<C-e>
noremap <C-l> 14k14<C-y>
如果要同时移动光标,光标在屏幕上任意位置的视窗,也许你应该设置一些自定义键绑定同时做两。
如:
:nnoremap <C-M-u> j<C-e>
这将向下移动光标(j
),只要你按Ctrl-Alt-u
(仅在正常模式下)移动视(Ctrl-e
)。
有两种方法我能想到的:CTRL - Ë和CTRL - Ÿ滚动没有位置相对光标移动到该窗口的缓冲区。我认为那就是你想要的。此外,如果您设置scrolloff
有大量,您将得到同样的效果CTRL - Ë和CTRL - Ÿ与移动键。 scrolloff
设置将使得光标很难相对于窗口垂直移动。 (使用类似:set so=999
,so
是scrolloff
的缩写。)
:help 'scrolloff'
:help scrolling
'ctrl-E' **确实**移动光标相对于窗口的位置,光标跟随文本;如果光标位于窗口/屏幕中间,并且反复按下“ctrl-E”,则光标移动到第一行;这正是提问者不想要的;他想要做'14j14
你的第二个建议,设置滚降,做什么操作要求,但它**没有提供相同的效果'CTRL-E';只有滚动的问题是它是永久性的,因为现在不可能在没有滚动的情况下移动;这将是一件好事,一键移动,一键移动而不滚动 – 2012-11-22 18:41:43
Upvote for'so'选项,但@ Matthias009是正确的。 – 2015-01-02 20:07:47
试试这个映射。的vimrc
map <ScrollWheelUp> 5<C-Y>
map <ScrollWheelDown> 5<C-E>
可以改变光标在屏幕上的位置,但不会改变光标线在屏幕上的位置:
noremap <C-k> @="1\<lt>C-D>"<CR>:set scroll=0<CR>
noremap <C-l> @="1\<lt>C-U>"<CR>:set scroll=0<CR>
但是这将重置scroll
选项,因此后续<C-D>
和<C-U>
会滚动一半屏幕。如果没有set scroll=0
,则scroll
选项将被设置为1,随后的<C-D>
和<C-U>
将滚动一行(Vim很奇怪)。
基于1<C-D>
和1<C-U>
的Vimscript函数可能是最好的。
我知道有两种方法。这些行添加到您的.vimrc文件(选择两种方法只有一个):
方法1:
function! s:GetNumScroll(num)
let num_rows = winheight(0)
let num_scroll = a:num
if (a:num == -1)
let num_scroll = (num_rows + 1)/2
elseif (a:num == -2)
let num_scroll = num_rows
endif
if (num_scroll < 1)
let num_scroll = 1
endif
return num_scroll
endfunction
function! s:RtrnToOrig(before_scr_line)
normal H
let delta = a:before_scr_line - winline()
while (delta != 0)
if (delta < 0)
let delta = winline() - a:before_scr_line
let iter = 1
while (iter <= delta)
execute "normal" "gk"
let iter +=1
endwhile
elseif (delta > 0)
let iter = 1
while (iter <= delta)
execute "normal" "gj"
let iter +=1
endwhile
endif
let delta = a:before_scr_line - winline()
endwhile
endfunction
function! s:scrollUP(num)
let num_scroll = <SID>GetNumScroll(a:num)
let num_rows = winheight(0)
" -------------
let before_scr_line = winline()
normal L
let after_scr_line = winline()
let extra = num_rows - after_scr_line
let extra += num_scroll
" move by 1 to prevent over scrolling
let iter = 1
while (iter <= extra)
execute "normal" "gj"
let iter +=1
endwhile
" -------------
call <SID>RtrnToOrig(before_scr_line)
endfunction
function! s:scrollDN(num)
let num_scroll = <SID>GetNumScroll(a:num)
" -------------
let before_scr_line = winline()
normal H
let after_scr_line = line(".")
execute "normal" "gk"
let after_scr2_line = line(".")
if ((after_scr_line == after_scr2_line) && (after_scr_line > 1))
execute "normal" "gk"
endif
let extra = (num_scroll - 1)
let extra += (winline() - 1)
" move by 1 to prevent over scrolling
let iter = 1
while (iter <= extra)
execute "normal" "gk"
let iter +=1
endwhile
" -------------
call <SID>RtrnToOrig(before_scr_line)
endfunction
nmap <silent> <C-J> :call <SID>scrollUP(1)<CR>
nmap <silent> <C-K> :call <SID>scrollDN(1)<CR>
nmap <silent> <C-F> :call <SID>scrollUP(-1)<CR>
nmap <silent> <C-B> :call <SID>scrollDN(-1)<CR>
nmap <silent> <PageDown>:call <SID>scrollUP(-2)<CR>
nmap <silent> <PageUp> :call <SID>scrollDN(-2)<CR>
这用正常的H,L去屏幕顶部,BOT和GK, gj命令可以通过屏幕线而不是实际线向上移动。当线条长度超过屏幕宽度并且打开wordwrap时,它会比看起来需要更加复杂的工作。
或者这种方法(先前已经在vim技巧wiki和对堆栈交易所发布):
方法2:
" N<C-D> and N<C-U> idiotically change the scroll setting
function! s:Saving_scrollV(cmd)
let save_scroll = &scroll
execute "normal" a:cmd
let &scroll = save_scroll
endfunction
" move and scroll
nmap <silent> <C-J> :call <SID>Saving_scrollV("1<C-V><C-D>")<CR>
vmap <silent> <C-J> <Esc> :call <SID>Saving_scrollV("gv1<C-V><C-D>")<CR>
nmap <silent> <C-K> :call <SID>Saving_scrollV("1<C-V><C-U>")<CR>
vmap <silent> <C-K> <Esc> :call <SID>Saving_scrollV("gv1<C-V><C-U>")<CR>
nmap <silent> <C-F> :call <SID>Saving_scrollV("<C-V><C-D>")<CR>
vmap <silent> <C-F> <Esc> :call <SID>Saving_scrollV("gv<C-V><C-D>")<CR>
nmap <silent> <PageDown> :call <SID>Saving_scrollV("<C-V><C-D>")<CR>
vmap <silent> <PageDown> <Esc>:call <SID>Saving_scrollV("gv<C-V><C-D>")<CR>
nmap <silent> <C-B> :call <SID>Saving_scrollV("<C-V><C-U>")<CR>
vmap <silent> <C-B> <Esc> :call <SID>Saving_scrollV("gv<C-V><C-U>")<CR>
nmap <silent> <PageUp> :call <SID>Saving_scrollV("<C-V><C-U>")<CR>
vmap <silent> <PageUp> <Esc> :call <SID>Saving_scrollV("gv<C-V><C-U>")<CR>
我有第二种方法唯一的问题是当行比屏幕宽度和wordwrap更长,则光标可以向上或向下移动一些以解释换行中的额外行。同样在文件的顶部和底部,光标可以移动。第一种方法确实试图在所有情况下不移动光标。
你能否提供你的答案更详细的解释?否则对任何后来出现的人来说都没有意义。 – 2016-12-13 21:31:45
好吧,您将这些行添加到.vimrc文件中。当wordwrap关闭时,或当它打开但线条都比窗口宽度短时,在不移动光标的情况下进行滚动非常简单。但是当wordwrap打开并且行比窗口宽度更长时,滚动可以将光标向上或向下移动一些,因为它会向下或向上移动一行。顶部方法无论如何保持光标位置,但我只在正常模式下使用它。 – 2016-12-14 01:05:36
正常的H移动到最上面的一行,正常的L移动到最后一行,从那里你可以计算出用“gj”或“gk”移动多少屏幕行来滚动屏幕行,然后返回到原始屏幕线。 – 2016-12-14 01:08:07
您可以使用光标进行滚动,也可以在不移动光标的当前行的情况下滚动屏幕(尽管它会在行移动时移动到屏幕上的位置)。我认为你不能完全实现你正在寻找的东西......如果只是打下页面呢? – Fosco 2010-08-17 14:34:51
页面向下是更大的移动滚动。 – 2010-08-17 14:39:43
这是一个重复: http://stackoverflow.com/questions/3458689/how-to-move-screen-without-moving-cursor-in-vim/ – GWW 2010-08-17 15:03:48