Barra de rolagem para vim (um baseado em maldições, não gvim)?

10

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

O que eu espero é uma barra de rolagem ASCII que se parece

|
|
|
|
#
#
#
|
|
|

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

xiaq
fonte

Respostas:

3

Se você está considerando a rota "escreva seu próprio plugin", o recurso 'sign' do Vim pode ser um bom lugar para começar. Esse recurso é como, por exemplo, plugins de verificação de sintaxe destacam erros.

exemplo de sinal vim

Uma abordagem simples para colocar o sinal seria:

  1. Determine onde você está no arquivo como uma porcentagem p
  2. Determinar quantas linhas são visíveis nas janelas do vim L
  3. Coloque uma placa no número da linha mais próximo de int(p*L)
  4. Recalcular em movimento ao redor do arquivo
redigido
fonte
Obrigado! Isso está muito próximo do meu requisito declarado, embora, a partir do documento, pareça que os sinais só podem ser desenhados no lado esquerdo. Boa resposta, porém, aceito!
Xiaq
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 horizontal, mas funciona surpreendentemente bem). Isso foi discutido originalmente na lista de discussão vim_use alguns anos atrás.

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 laststatusopção definida como 2.

Christian Brabandt
fonte
Eu realmente gosto dessa solução, pois coloca a barra de rolagem em um local onde não ocupa espaço na janela de codificação. Obrigado Christian!
10136 dotarkhen
Gosto da ideia e posso até conviver com uma pseudo-barra de rolagem horizontal. Mas o @redacted apresentou uma solução mais próxima do meu requisito declarado. tenha +1 na sua resposta. Obrigado!
Xiaq
Como você define a cor da BG do marcador de posição de rolagem? É quase indistinguível do resto da barra usando o tema solarizado no kde.
6133 Mike
Acho que a partir das últimas linhas, que os grupos de destaque Usuário1 e Usuário2 são usados. Você pode redefini-los.
Christian Brabandt
6

Minha tentativa de redenção de minhas faltas anteriores ....

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 no momento, ainda tenho trabalho a fazer, inclusive digitando todos os documentos, comentários e outras coisas.

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

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

Vou continuar trabalhando nisso, meio arrumado. As cores são berrantes por um motivo, fácil de ver o que muda. Ele tem um grande erro no momento, você não pode fazer com que todos os sinais desapareçam desativando-o. Eu sei como implementar isso, só queria compartilhar.


As imagens são úteis:

Vim-Scrollbar em ação


Barra de rolagem do VIM Curses - v0.1 - L Nix - [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:
lornix
fonte
Você quer dizer guioptionse, como a ajuda afirma claramente, isso funciona apenas para a versão gui do vim.
Christian Brabandt
Agradável. Eu implementei algo semelhante no plug-in DynamicSigns. BTW: observe que os sinais não são desenhados, em linhas dobradas.
Christian Brabandt
Obrigado! Eu achei que deveria compensar meu foobar mais cedo, então fiquei mais interessado nele ... então eu escrevi. Como sempre, o trabalho inicial é fácil ... ficar com um aspeto elegante e bonito é a parte frustrante. (não há sinais nas dobras ... anotados) #
1155 lornix
Obrigado! Mas, a julgar pelos dados reduzidos, o recurso de sinalização foi publicado mais cedo do que você; portanto, talvez seja mais educado aceitar a resposta dele. Marcou com +1 sua resposta.
Xiaq 28/07/12
11
Seu repo foi removido. Seria ótimo se você pudesse colocar isso em algum lugar como o github e permitir que outros contribuíssem. Eu realmente acho que parece ótimo.
27515 Mike
0

Não é uma solução ideal, mas você pode descobrir em que parte do arquivo está na linha de status com algo como

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

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

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

Sardathrion - contra o abuso de SE
fonte
Obrigado, mas eu já sabia disso ... Eu estava apenas procurando algo mais fácil para os olhos.
xiaq 23/08/11
Foi um tiro no escuro.
Sardathrion - contra abuso do SE
0

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

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
q335r49
fonte
Isso funciona para o mouse, mas não é atualizado quando você rola com, por exemplo, Ctrl + F. O marcador parece permanecer em seu número de linha original. Fazer :call UpdateScrollbox()funciona, mas não é fácil de usar. Pode precisar de ganchos em todas as teclas de movimento ou, melhor ainda, de um gancho em um evento de rolagem, se possível.
Ruslan