Barra de desplazamiento para vim (basado en maldiciones, no gvim)?


10

Como usuario de Linux, me he sentido bastante cómodo con las herramientas CLI y TUI, pero extraño la pequeña barra de desplazamiento presente en casi todos los programas GUI. Siempre me ha sido más fácil saber cuánto dura el archivo y dónde estoy desde la barra de desplazamiento en lugar de "9752 líneas, 24%".

Lo que espero es una barra de desplazamiento ASCII que se parece

El |
El |
El |
El |
# #
# #
# #
El |
El |
El |

y puedo configurar para que aparezca a la izquierda o derecha (y si está a la izquierda, la posición relativa a los números de línea y las marcas de plegado). ¿Ya existe un complemento Vim para hacer esto, o cómo puedo escribir el mío? El marco de complementos de Vim no parece admitir tales modificaciones de la interfaz de usuario directamente.

Respuestas:


3

Si está considerando la ruta "escriba su propio complemento", la función 'señal' de Vim podría ser un buen lugar para comenzar. Esta característica es cómo, por ejemplo, los plugins de verificación de sintaxis resaltan los errores.

ejemplo de signo vim

Un enfoque simple para colocar el signo sería:

  1. Determine en qué parte del archivo se encuentra como porcentaje p
  2. Determine cuántas líneas son visibles en las ventanas vim L
  3. Coloque un letrero en el número de línea más cercano a int(p*L)
  4. Vuelva a calcular el movimiento alrededor del archivo

¡Gracias! Esto está muy cerca de mi requisito establecido, aunque desde el documento parece que los signos solo se pueden dibujar en el lado izquierdo. Buena respuesta, sin embargo, aceptado!
xiaq

10

Es posible usar la línea de estado como barra de desplazamiento. Solía ​​tener lo siguiente en mi .vimrc, que emula una barra de desplazamiento (también es solo horizontalmente, pero funciona sorprendentemente bien). Esto se discutió originalmente en la lista de correo vim_use hace algunos años.

func! STL()
  let stl = '%f [%{(&fenc==""?&enc:&fenc).((exists("+bomb") && &bomb)?",B":"")}%M%R%H%W] %y [%l/%L,%v] [%p%%]'
  let barWidth = &columns - 65 " <-- wild guess
  let barWidth = barWidth < 3 ? 3 : barWidth

  if line('$') > 1
    let progress = (line('.')-1) * (barWidth-1) / (line('$')-1)
  else
    let progress = barWidth/2
  endif

  " line + vcol + %
  let pad = strlen(line('$'))-strlen(line('.')) + 3 - strlen(virtcol('.')) + 3 - strlen(line('.')*100/line('$'))
  let bar = repeat(' ',pad).' [%1*%'.barWidth.'.'.barWidth.'('
        \.repeat('-',progress )
        \.'%2*0%1*'
        \.repeat('-',barWidth - progress - 1).'%0*%)%<]'

  return stl.bar
endfun

hi def link User1 DiffAdd
hi def link User2 DiffDelete
set stl=%!STL()

Asegúrese de tener la laststatusopción establecida en 2.


Realmente me gusta esta solución, ya que coloca la barra de desplazamiento en un lugar donde no ocupa espacio de la ventana de codificación. Gracias cristiano!
dotancohen

Me gusta la idea e incluso puedo vivir con una barra de pseudo desplazamiento horizontal. Pero @redacted presentó una solución más cercana a mi requisito establecido. sin embargo, tiene +1 en su respuesta. ¡Gracias!
xiaq

¿Cómo se configura el color de la BG del marcador de posición de desplazamiento? Es casi indistinguible del resto del bar usando el tema solarizado en kde.
Mike

Supongo, desde las últimas líneas, que se utilizan los grupos de resaltado Usuario1 y Usuario2. Puedes redefinirlos.
Christian Brabandt

6

Mi intento de redención de mi anterior paso en falso ...

Me gustó la idea, así que hoy escribí un complemento para VIM para mostrar un 'pulgar' de la barra de desplazamiento utilizando la función de signos de vim.

Todavía es MUY beta, pero es utilizable en este momento, todavía tengo trabajo que hacer, incluyendo escribir todos los documentos, comentarios y demás.

Publicaré la fuente aquí, pero puedes sacarlo de mi Hg Repo . (No te rías demasiado por las otras cosas)

Recuerde ... MUY beta, considerando que nunca antes había escrito un complemento, solo incursionando en VimL a lo largo de los años. (¡menos de 12 horas desde el concepto hasta el prototipo de trabajo! ¡yay!)

Seguiré trabajando en eso, un poco ordenado. Los colores son llamativos por una razón, fácil de ver qué cambios. Tiene un gran error en este momento, no puede hacer que todas las señales desaparezcan al desactivarlo. Sé cómo implementar esto, solo quería compartir.


Las fotos son útiles:

Vim-Scrollbar en acción


Barra de desplazamiento de maldiciones VIM - v0.1 - L Nix - lornix@lornix.com Hg Repo

" Vim global plugin to display a curses scrollbar
" Version:      0.1.1
" Last Change:  2012 Jul 06
" Author:       Loni Nix <lornix@lornix.com>
"
" License:      TODO: Have to put something here
"
"
if exists('g:loaded_scrollbar')
    finish
endif
let g:loaded_scrollbar=1
"
" save cpoptions
let s:save_cpoptions=&cpoptions
set cpoptions&vim
"
" some global constants
if !exists('g:scrollbar_thumb')
    let g:scrollbar_thumb='#'
endif
if !exists('g:scrollbar_clear')
    let g:scrollbar_clear='|'
endif
"
"our highlighting scheme
highlight Scrollbar_Clear ctermfg=green ctermbg=black guifg=green guibg=black cterm=none
highlight Scrollbar_Thumb ctermfg=red   ctermbg=black guifg=red   guibg=black cterm=reverse
"
"the signs we're goint to use
exec "sign define sbclear text=".g:scrollbar_clear." texthl=Scrollbar_Clear"
exec "sign define sbthumb text=".g:scrollbar_thumb." texthl=Scrollbar_Thumb"
"
" set up a default mapping to toggle the scrollbar
" but only if user hasn't already done it
if !hasmapto('ToggleScrollbar')
    map <silent> <unique> <leader>sb :call <sid>ToggleScrollbar()<cr>
endif
"
" start out activated or not?
if !exists('s:scrollbar_active')
    let s:scrollbar_active=1
endif
"
function! <sid>ToggleScrollbar()
    if s:scrollbar_active
        let s:scrollbar_active=0
        " clear out the autocmds
        augroup Scrollbar_augroup
            autocmd!
        augroup END
        "call <sid>ZeroSignList()
    else
        let s:scrollbar_active=1
        call <sid>SetupScrollbar()
    endif
endfunction

function! <sid>SetupScrollbar()
    augroup Scrollbar_augroup
        autocmd BufEnter     * :call <sid>showScrollbar()
        autocmd BufWinEnter  * :call <sid>showScrollbar()
        autocmd CursorHold   * :call <sid>showScrollbar()
        autocmd CursorHoldI  * :call <sid>showScrollbar()
        autocmd CursorMoved  * :call <sid>showScrollbar()
        autocmd CursorMovedI * :call <sid>showScrollbar()
        autocmd FocusGained  * :call <sid>showScrollbar()
        autocmd VimResized   * :call <sid>showScrollbar()
    augroup END
    call <sid>showScrollbar()
endfunction
"
function! <sid>showScrollbar()
    " not active, go away
    if s:scrollbar_active==0
        return
    endif
    "
    let bnum=bufnr("%")
    let total_lines=line('$')
    let current_line=line('.')
    let win_height=winheight(0)
    let win_start=line('w0')+0 "curious, this was only one had to be forced
    let clear_top=float2nr((current_line * win_height) / total_lines) - 1
    if clear_top < 0
        let clear_top=0
    elseif clear_top > (win_height - 1)
        let clear_top=win_height - 1
    endif
    let thumb_height=float2nr((win_height * win_height) / total_lines)
    if thumb_height < 1
        let thumb_height=1
    elseif thumb_height > win_height
        let thumb_height=win_height
    endif
    let thumb_height=thumb_height + clear_top
    let linectr=1
    while linectr <= clear_top
        let dest_line=win_start+linectr-1
        exec ":sign place ".dest_line." line=".dest_line." name=sbclear buffer=".bnum
        let linectr=linectr+1
    endwhile
    while linectr <= thumb_height
        let dest_line=win_start+linectr-1
        exec ":sign place ".dest_line." line=".dest_line." name=sbthumb buffer=".bnum
        let linectr=linectr+1
    endwhile
    while linectr <= win_height
        let dest_line=win_start+linectr-1
        exec ":sign place ".dest_line." line=".dest_line." name=sbclear buffer=".bnum
        let linectr=linectr+1
    endwhile
endfunction
"
" fire it all up if we're 'active'
if s:scrollbar_active != 0
    call <sid>SetupScrollbar()
endif
"
" restore cpoptions
let &cpoptions=s:save_cpoptions
unlet s:save_cpoptions
"
" vim: set filetype=vim fileformat=unix expandtab softtabstop=4 shiftwidth=4 tabstop=8:

Es decir, guioptionsy como dice claramente la ayuda, esto solo funciona para la versión gui de vim.
Christian Brabandt

Agradable. He implementado algo similar en el complemento DynamicSigns. Por cierto: tenga en cuenta que los signos no se dibujan, en líneas dobladas.
Christian Brabandt

¡Gracias! Pensé que debería compensar mi foobar antes, luego me interesé más en eso ... así que lo escribí. Como siempre, el trabajo inicial es fácil ... hacer que todo sea elegante y atractivo es la parte frustrante. (sin signos en los pliegues ... notado)
lornix

¡Gracias! Pero a juzgar por los datos @redacted, apareció la función de signo antes que usted, por lo que quizás sea más cortés aceptar su respuesta. Has hecho +1 en tu respuesta.
xiaq

1
Su repositorio ha sido eliminado. Sería genial si pudieras poner esto en algún lugar como Github y dejar que otros contribuyan a ello. Realmente creo que se ve genial.
Mike

0

No es una solución ideal, pero puede averiguar en qué parte del archivo se encuentra en la línea de estado con algo como

set statusline=%<%m\ %f\ %y\ %{&ff}\ \%=\ row:%l\ of\ %L\ col:%c%V\ %P

o usar set numberpara tener un número de línea antes de cada línea.

A menos que haya modificado la fuente vim (ncurses), no creo que esto sea posible, pero podría estar equivocado.


Gracias pero ya lo sabía ... Estaba buscando algo más fácil a la vista.
xiaq

Fue una posibilidad remota.
Sardathrion - contra el abuso SE

0

Aquí hay una versión que se puede arrastrar con el mouse. También se actualiza solo cuando se usa la rueda de desplazamiento; de todos modos, si necesita una barra de desplazamiento, su mano debe estar en el mouse.

sign define scrollbox texthl=Visual text=[]
fun! ScrollbarGrab()
    if getchar()=="\<leftrelease>" || v:mouse_col!=1
        return|en
    while getchar()!="\<leftrelease>"
        let pos=1+(v:mouse_lnum-line('w0'))*line('$')/winheight(0)
        call cursor(pos,1)
        sign unplace 789
        exe "sign place 789 line=".(pos*winheight(0)/line('$')+line('w0')).b:scrollexpr
    endwhile
endfun
fun! UpdateScrollbox()
    sign unplace 789
    exe "sign place 789 line=".(line('w0')*winheight(0)/line('$')+line('w0')).b:scrollexpr
endfun
fun! ToggleScrollbar()
    if exists('b:opt_scrollbar')
        unlet b:opt_scrollbar
        nun <buffer> <leftmouse>
        iun <buffer> <leftmouse>
        nun <buffer> <scrollwheelup>
        nun <buffer> <scrollwheeldown>
        iun <buffer> <scrollwheelup>
        iun <buffer> <scrollwheeldown>
        exe "sign unplace 789 file=" . expand("%:p")
        exe "sign unplace 788 file=" . expand("%:p")
    el
        let b:opt_scrollbar=1
        nno <silent> <buffer> <leftmouse> <leftmouse>:call ScrollbarGrab()<cr>
        ino <silent> <buffer> <leftmouse> <leftmouse><c-o>:call ScrollbarGrab()<cr>
        nno <buffer> <scrollwheelup> <scrollwheelup>:call UpdateScrollbox()<cr>
        nno <buffer> <scrollwheeldown> <scrollwheeldown>:call UpdateScrollbox()<cr>
        ino <buffer> <scrollwheelup> <scrollwheelup><c-o>:call UpdateScrollbox()<cr>
        ino <buffer> <scrollwheeldown> <scrollwheeldown><c-o>: call UpdateScrollbox()<cr>
        let b:scrollexpr=" name=scrollbox file=".expand("%:p")
        exe "sign place 789 line=".(line('w0')*winheight(0)/line('$')+line('w0')).b:scrollexpr
        exe "sign place 788 line=1".b:scrollexpr
    en
endfun

Esto funciona para el mouse, pero no se actualiza cuando se desplaza con, por ejemplo, Ctrl + F. El marcador parece permanecer en su número de línea original. Hacer :call UpdateScrollbox()funciona, pero no es fácil de usar. Es posible que necesite ganchos en todas las teclas de movimiento o, mejor, un gancho en un evento de desplazamiento, si es posible.
Ruslan
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.