Barre de défilement pour vim (basée sur les malédictions, pas gvim)?


10

En tant qu'utilisateur Linux, je suis assez à l'aise avec les outils CLI et TUI, mais la petite barre de défilement présente dans presque tous les programmes GUI me manque. Il m'a toujours été plus facile de savoir quelle est la longueur du fichier et où je me trouve dans la barre de défilement au lieu de "9752 lignes, 24%".

Ce que j'attends, c'est une barre de défilement ASCII qui ressemble

|
|
|
|
#
#
#
|
|
|

et je peux configurer pour apparaître à gauche ou à droite (et si à gauche, la position relative aux numéros de ligne et aux marques de pliage). Existe-t-il déjà un plugin Vim pour ce faire, ou comment puis-je écrire le mien? Le framework de plug-in de Vim ne semble pas prendre en charge directement ces modifications d'interface utilisateur.

Réponses:


3

Si vous envisagez la route «écrivez votre propre plugin», la fonction «signer» de Vim pourrait être un bon point de départ. Cette fonctionnalité permet, par exemple, aux plugins de vérification de la syntaxe de mettre en évidence les erreurs.

exemple de signe vim

Une approche simple pour placer le signe serait alors:

  1. Déterminez où vous vous trouvez dans le fichier en pourcentage p
  2. Déterminer le nombre de lignes visibles dans les fenêtres vim L
  3. Placez un panneau au numéro de ligne le plus proche de int(p*L)
  4. Recalculer en se déplaçant autour du fichier

Merci! Ceci est très proche de mon exigence déclarée, bien que d'après le document, il semble que les signes ne peuvent être dessinés que sur le côté gauche. Bonne réponse cependant, acceptée!
2012 à 9h18

10

Il est possible d'utiliser la ligne d'état comme une barre de défilement. J'avais l'habitude d'avoir ce qui suit dans mon .vimrc, qui émule une barre de défilement (aussi c'est seulement horizontalement, mais cela fonctionne étonnamment bien). Cela a été initialement discuté sur la liste de diffusion vim_use il y a quelques années.

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()

Assurez-vous que l' laststatusoption est définie sur 2.


J'aime vraiment cette solution car elle place la barre de défilement dans un endroit où elle ne prend pas de place dans la fenêtre de codage. Merci, Christian!
dotancohen

J'aime l'idée, et peut même peut-être vivre avec une pseudo-barre de défilement horizontale. Mais @redacted a présenté une solution plus proche de mon exigence déclarée. avoir +1 sur votre réponse. Merci!
2012 à 9h16

Comment définissez-vous la couleur du BG du marqueur de position de défilement? Il est presque impossible de le distinguer du reste de la barre en utilisant le thème solarisé sur kde.
Mike

Devinez à partir des dernières lignes, que les groupes de surbrillance User1 et User2 sont utilisés. Vous pouvez les redéfinir.
Christian Brabandt

6

Ma tentative de rachat de mes faux pas précédents ....

J'ai aimé l'idée, donc aujourd'hui j'ai écrit un plugin pour VIM pour montrer un pouce de la barre de défilement en utilisant la fonction de signes de vim.

C'est encore TRÈS bêta, mais il est utilisable en ce moment, j'ai encore du travail à faire, y compris la dactylographie de tous les documents, commentaires et autres.

Je posterai la source ici, mais vous pouvez la retirer de mon Hg Repo . (Ne riez pas trop fort des autres trucs)

Rappelez-vous ... TRÈS bêta, étant donné que je n'ai jamais écrit de plug-in auparavant, je n'ai essayé que VimL au fil des ans. (moins de 12 heures du concept au prototype fonctionnel! yay!)

Je vais continuer à y travailler, un peu soigné. Les couleurs sont criardes pour une raison, faciles à voir ce qui change. Il a un gros bug en ce moment, vous ne pouvez pas faire disparaître tous les signes en le désactivant. Je sais comment mettre en œuvre cela, je voulais juste partager.


Les photos sont utiles:

Vim-Scrollbar en action


Barre de défilement VIM Curses - 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:

Vous voulez dire guioptionset comme l'aide l'indique clairement, cela ne fonctionne que pour la version gui de vim.
Christian Brabandt

Agréable. J'ai implémenté quelque chose de similaire dans le plugin DynamicSigns. BTW: notez que les signes ne sont pas dessinés, sur des lignes pliées.
Christian Brabandt

Je vous remercie! J'ai pensé que je devrais rattraper mon foobar plus tôt, puis je me suis intéressé de plus en plus ... alors je l'ai écrit. Comme toujours, le travail initial est facile ... tout cela est frustrant. (aucun signe sur les plis ... noté)
lornix

Merci! Mais à en juger par les données @redacted a fait apparaître la fonctionnalité de signe plus tôt que vous, il est donc peut-être plus poli d'accepter sa réponse. Ont +1 sur votre réponse.
2012 à 9h17

1
Votre dépôt a été supprimé. Ce serait formidable si vous pouviez mettre cela en place quelque part comme github et laisser les autres y contribuer. Je pense vraiment que ça a l'air génial.
Mike

0

Ce n'est pas une solution idéale, mais vous pouvez savoir où vous vous trouvez dans le fichier soit dans la ligne d'état avec quelque chose comme

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

ou en utilisant set numberpour avoir un numéro de ligne avant chaque ligne.

À moins que vous n'ayez modifié la source vim (ncurses), je ne pense pas que cela soit possible mais je peux me tromper.


Merci mais je le savais déjà ... Je cherchais juste quelque chose de plus agréable pour les yeux.
xiaq

Ce fut un long coup.
Sardathrion - contre les abus SE

0

Voici une version qui peut être déplacée avec la souris. Il ne se met également à jour que lorsque la molette de défilement est utilisée - si vous avez besoin d'une barre de défilement, votre main doit de toute façon être sur la souris.

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

Cela fonctionne pour la souris, mais n'est pas mis à jour lorsque vous faites défiler avec par exemple Ctrl + F. Le marqueur semble rester dans son numéro de ligne d'origine. Faire des :call UpdateScrollbox()travaux, mais n'est pas convivial. Pourrait avoir besoin de crochets sur toutes les touches de mouvement, ou, mieux, d'un crochet sur un événement de défilement, si c'est possible.
Ruslan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.