Domanda Scorrimento di Vim senza cambiare la posizione sullo schermo dei cursori


Quando il cursore si trova a metà schermo e si scorre verso il basso, il cursore si sposta verso l'alto sullo schermo. Non voglio farlo.

Come posso scorrere senza cambiare i cursori sullo schermo?

Soluzione, aggiunta dopo la risposta:

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

35
2017-08-17 14:31


origine


risposte:


Se vuoi spostare il cursore e il riquadro della vista con il cursore in qualsiasi punto dello schermo, forse dovresti impostare alcuni collegamenti personalizzati dei tasti per eseguire entrambe le operazioni contemporaneamente.

Ad esempio:

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

Questo sposta il cursore verso il basso (j) e spostare il viewport (Ctrl-e) ogni volta che si preme Ctrl-Alt-u (solo in modalità normale).


6
2017-08-17 14:59



Ci sono due modi in cui posso pensare: ctrl-E e ctrl-Y scorrere il buffer senza spostare la posizione del cursore rispetto alla finestra. Penso che sia quello che vuoi. Inoltre, se si imposta scrolloff ad un numero elevato, otterrai lo stesso effetto di ctrl-E e ctrl-Y con i tasti di movimento. scrolloff l'impostazione renderà difficile far spostare il cursore verticalmente rispetto alla finestra. (Usa qualcosa come :set so=999, so è un'abbreviazione per scrolloff.)

:help 'scrolloff'
:help scrolling

43
2017-08-17 15:05



ctrl-D e ctrl-U è quello che vuoi

ctrl-D ha lo stesso effetto di 14j14<C-e> (solo che il numero 14 non è codificato in modo rigido e la quantità di movimento dipende dalle dimensioni effettive del tuo schermo): Sposta il cursore di diverse righe verso il basso nel testo, ma il cursore rimane al centro dello schermo.

allo stesso modo ctrl-U funziona come 14k14<C-y>.

Addendum: se il tuo schermo ha 30 righe, le due sono esattamente le stesse.


11
2017-11-22 18:55



Prova questa mappatura in .vimrc

map <ScrollWheelUp>   5<C-Y>
map <ScrollWheelDown> 5<C-E>

0
2018-03-30 17:54



Questo cambia la posizione sullo schermo del cursore, ma non cambia la posizione sullo schermo della linea del cursore:

noremap <C-k> @="1\<lt>C-D>"<CR>:set scroll=0<CR>
noremap <C-l> @="1\<lt>C-U>"<CR>:set scroll=0<CR>

Ciò tuttavia ripristina il scroll opzione, quindi successiva <C-D> e <C-U> scorrerà per mezzo schermo. Senza set scroll=0, il scroll l'opzione sarebbe stata impostata su 1 e successiva <C-D> e <C-U> starebbe scorrendo di una riga (Vim è strano).

Probabilmente una funzione di Vimscript basata su 1<C-D> e 1<C-U> sarebbe il massimo.


0
2018-03-12 15:54



Ci sono due metodi che conosco. Aggiungi queste righe al tuo file .vimrc (selezionando solo uno dei due metodi):

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

Questo usa il normale H, L per andare a schermo in alto, bot e i comandi gk, gj per spostarsi verso l'alto, in basso per riga dello schermo invece della linea attuale. È più complicato di quanto sembrerebbe necessario per funzionare correttamente quando le linee sono più lunghe della larghezza dello schermo e il wordwrap è attivo.

O questo metodo (che è stato precedentemente pubblicato su wiki di vim tips e su Stack Exchange):

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

L'unico problema che ho con il secondo metodo è quando le linee sono più lunghe della larghezza dello schermo e il wordwrap è attivo, quindi il cursore può spostarsi verso l'alto o verso il basso per tenere conto delle linee extra dell'involucro. Inoltre, nella parte superiore e inferiore del file, il cursore può spostarsi. Il primo metodo tenta davvero di non spostare mai il cursore in tutti i casi.


0
2017-12-13 18:46