當光標位於屏幕中間時,向下滾動,光標在屏幕上向上移動。我不希望它那樣做。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