Прокрутка Vim без изменения курсора на экране - PullRequest
35 голосов
/ 17 августа 2010

Когда курсор находится в середине экрана и я прокручиваю вниз, курсор перемещается вверх по экрану.Я не хочу, чтобы это делалось.

Как прокрутить экран без изменения положения курсора на экране?

Решение, добавленное после ответа:

noremap <C-k> 14j14<C-e>
noremap <C-l> 14k14<C-y>

Ответы [ 6 ]

44 голосов
/ 17 августа 2010

Я могу думать о двух способах: ctrl - E и ctrl - Y прокручивать буфер без перемещения курсора положение относительно окна. Я думаю, это то, что вы хотите. Кроме того, если вы установите scrolloff на большое число, вы получите тот же эффект, что и ctrl - E и ctrl - Y с помощью клавиш движения. Установка scrolloff затруднит перемещение курсора по вертикали относительно окна. (Используйте что-то вроде :set so=999, so - сокращение от scrolloff.)

:help 'scrolloff'
:help scrolling
11 голосов
/ 22 ноября 2012

ctrl - D и ctrl - U - это то, что вы хотите.

ctrl - D имеет тот же эффект, что и 14j14<C-e> (только то, что число 14 не жестко запрограммировано, а величина перемещения зависит от фактического размера вашего экрана): вы перемещаете курсор на несколько строк внизв тексте, но курсор остается в центре экрана.

Аналогично ctrl - U работает как 14k14<C-y>.

Добавление:Если на вашем экране 30 строк, то они точно такие же.

6 голосов
/ 17 августа 2010

Если вы хотите одновременно переместить курсор и область просмотра с курсором в любое место на экране, возможно, вам следует настроить некоторые пользовательские привязки клавиш для одновременного выполнения обоих действий.

Например:

:nnoremap <C-M-u> j<C-e>

Это будет перемещать курсор вниз (j) и перемещать окно просмотра (Ctrl-e) всякий раз, когда вы нажимаете Ctrl-Alt-u (только в обычном режиме).

1 голос
/ 30 марта 2013

Попробуйте это сопоставление в .vimrc

map <ScrollWheelUp>   5<C-Y>
map <ScrollWheelDown> 5<C-E>
0 голосов
/ 13 декабря 2016

Есть два метода, которые я знаю. Добавьте эти строки в ваш файл .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 для перехода к верхней части экрана, бот и команды gk, gj для перемещения вверх, вниз по экранной строке вместо реальной строки. Это сложнее, чем кажется, просто для правильной работы, когда строки длиннее ширины экрана и включена перенос слов.

Или этот метод (который ранее был опубликован в вики подсказках vim и в Stack Exchange):

Метод 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>

Единственная проблема, с которой я столкнулся во втором методе, - это когда строки длиннее ширины экрана и включена перенос по словам, тогда курсор может перемещаться вверх или вниз, чтобы получить дополнительные строки из переноса. Также в самой верхней и нижней части файла курсор может двигаться. Первый метод действительно пытается никогда не перемещать курсор во всех случаях.

0 голосов
/ 12 марта 2014

Это изменяет позицию курсора на экране, но не меняет позицию курсора на экране:

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 странный).

Вероятно, наилучшей будет функция Vimscript, основанная на 1<C-D> и 1<C-U>.

...