Прокрутка Vim без изменения положения курсоров на экране

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

Как я могу прокручивать, не меняя положение курсоров на экране?

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

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

person john-jones    schedule 17.08.2010    source источник
comment
Вы можете прокручивать с помощью курсора или прокручивать экран, не перемещая курсор с его текущей строки (хотя он будет перемещаться в позиции на экране, так как строки перемещаются). Я не думаю, что вы сможете сделать именно то, что ищете ... как насчет того, чтобы просто перейти на страницу вниз? ..   -  person Fosco    schedule 17.08.2010
comment
страница вниз - это просто прокрутка с большим движением.   -  person john-jones    schedule 17.08.2010
comment
Это повторение: stackoverflow.com/questions/3458689/   -  person GWW    schedule 17.08.2010
comment
@GWW, это не повторение этого вопроса. Он хотел, чтобы экран двигался так, чтобы его курсор стал первой строкой.   -  person joedevon    schedule 26.10.2011


Ответы (6)


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

Такие как:

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

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

person wds    schedule 17.08.2010

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

:help 'scrolloff'
:help scrolling
person Alok Singhal    schedule 17.08.2010
comment
ctrl-E перемещает положение курсора относительно окна, курсор следует за текстом; если курсор находится в середине окна / экрана и вы нажимаете ctrl-E несколько раз, курсор перемещается в первую строку; именно этого не хочет спрашивающий; он хочет сделать 14j14<C-e> просто с заменой 14 числом в зависимости от размера его экрана - person Matthias 009; 22.11.2012
comment
второе предложение, установка прокрутки, выполняет то, что требует оператор, но не дает того же эффекта, что и ctrl-E; единственная проблема с прокруткой в ​​том, что она постоянна в том смысле, что теперь невозможно перемещаться без прокрутки; было бы хорошо, если бы одна клавиша двигалась с помощью, а другая двигалась без прокрутки - person Matthias 009; 22.11.2012
comment
Проголосуйте за вариант so, но @ Matthias009 прав. - person Big McLargeHuge; 02.01.2015

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

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

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

Дополнение: если на вашем экране 30 строк, то эти две абсолютно одинаковые.

person Matthias 009    schedule 22.11.2012
comment
Точнее: [count] ‹C-d› и [count] ‹C-u› - это то, что он хочет. - person ciastek; 19.03.2013
comment
@ciastek Вы должны дать ответ. - person Zenexer; 11.06.2013

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

map <ScrollWheelUp>   5<C-Y>
map <ScrollWheelDown> 5<C-E>
person IvanM    schedule 30.03.2013

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

Или этот метод (который ранее был опубликован в вики-странице подсказок 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>

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

person M Kelly    schedule 13.12.2016
comment
Не могли бы вы дать более подробные пояснения к своим ответам? В противном случае это бессмысленно для тех, кто придет позже. - person Joe C; 14.12.2016
comment
Хорошо, вы добавляете эти строки в свой файл .vimrc. Довольно просто прокручивать, не перемещая курсор, когда перенос слов отключен или когда он включен, но все строки короче ширины окна. Но когда включен перенос слов и строки длиннее ширины окна, прокрутка может перемещать курсор вверх или вниз по мере того, как он идет вниз или вверх на строку. Метод top сохраняет позицию курсора, несмотря ни на что, но я использую его только в обычном режиме. - person M Kelly; 14.12.2016
comment
нормальный H перемещается в верхнюю строку, а нормальный L перемещается в нижнюю строку, и оттуда вы можете выяснить, сколько строк экрана нужно переместить с помощью gj или gk, чтобы прокрутить строку экрана, а затем вернуться к исходной строке экрана. - person M Kelly; 14.12.2016
comment
Хорошо. Вы не против отредактировать свой ответ, указав эту информацию, а не оставить его в комментарии? - person Joe C; 14.12.2016
comment
В советах vim wiki также есть следующее: vim.wikia.com/wiki/Page_up/down_and_keep_cursor_position - person M Kelly; 20.07.2017

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

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>.

person Alexey    schedule 12.03.2014