Barra de rolagem para vim (baseado em curses, não gvim)?

9

Como usuário do Linux, tenho me sentido bastante confortável com as ferramentas CLI e TUI, mas sinto falta da pequena barra de rolagem presente em quase todos os programas GUI. Sempre foi mais fácil para mim saber quanto tempo o arquivo está e onde estou na barra de rolagem, em vez de "9752 linhas, 24%".

O que eu espero é uma barra de rolagem ASCII que pareça

|
|
|
|
#
#
#
|
|
|

e posso configurar para aparecer à esquerda ou à direita (e, se à esquerda, a posição relativa a números de linhas e marcas de dobra). Já existe um plugin Vim para fazer isso, ou como eu posso escrever o meu próprio? A estrutura de plugins do Vim parece não suportar diretamente essas modificações da interface do usuário.

    
por xiaq 28.04.2011 / 09:33

5 respostas

3

Se você estiver considerando a rota "escrever seu próprio plug-in", o recurso 'sinal' do Vim pode ser um bom lugar para começar. Esse recurso é como, por exemplo, os plugins de verificação de sintaxe destacam os erros.

Uma abordagem simples para colocar o sinal seria:

  1. Determine onde você está no arquivo como porcentagem p
  2. Determine quantas linhas estão visíveis nas janelas do vim L
  3. Coloque um sinal no número da linha mais próximo de int(p*L)
  4. Recalcule o movimento ao redor do arquivo
por 03.07.2012 / 18:49
10

É possível usar a linha de status como uma barra de rolagem. Eu costumava ter o seguinte no meu .vimrc, que emula uma barra de rolagem (também é apenas horizontalmente, mas funciona surpreendentemente bem). Isso foi discutido originalmente na lista de discussão vim_use há alguns anos.

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

Verifique se você tem a opção laststatus definida como 2.

    
por 05.07.2012 / 13:29
6

Minha tentativa de redenção do meu falso passo anterior ...

Eu gostei da ideia, então hoje eu escrevi um plugin para o VIM para mostrar um 'polegar' da barra de rolagem usando o recurso de sinais do vim.

Ainda é MUITO beta, mas é utilizável agora, ainda tenho trabalho a fazer nele, incluindo a digitação de todos os documentos e comentários e outras coisas.

Vou postar a fonte aqui, mas você pode retirá-la do meu Hg Repo . (Não ria muito das outras coisas)

Lembre-se ... MUITO beta, considerando que eu nunca escrevi um plugin antes, apenas mexendo com o VimL ao longo dos anos. (menos de 12 horas do conceito ao protótipo funcional! yay!)

Vou continuar trabalhando nisso, meio que legal. As cores são berrantes por um motivo, fácil de ver o que muda. Tem um grande problema agora, você não pode fazer todos os sinais desaparecerem, desligando-o. Eu sei como implementar isso, só queria compartilhar.

As fotos são úteis:

[email protected] Hg Repo

" Vim global plugin to display a curses scrollbar
" Version:      0.1.1
" Last Change:  2012 Jul 06
" Author:       Loni Nix <[email protected]>
"
" 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:
    
por 06.07.2012 / 09:58
0

Não é uma solução ideal, mas você pode descobrir onde no arquivo você está ou na linha de status com algo como

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

ou usando set number para ter um número de linha antes de cada linha.

A menos que você modifique a fonte vim (ncurses), então eu não acho que isso seja possível, mas posso estar errado.

    
por 22.08.2011 / 13:27
0

Aqui está uma versão que pode ser arrastada com o mouse. Ele também é atualizado somente quando a roda de rolagem está sendo usada - se precisar de uma barra de rolagem, sua mão deve estar no mouse mesmo assim.

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
    
por 24.06.2013 / 21:47

Tags