Bilah gulir untuk vim (berbasis kutukan, bukan gvim)?

10

Sebagai pengguna Linux, saya merasa cukup nyaman dengan alat CLI dan TUI, tapi saya kehilangan scrollbar kecil yang ada di hampir setiap program GUI. Selalu lebih mudah bagi saya untuk mengetahui berapa lama file tersebut dan di mana saya berada dari scrollbar alih-alih "9752 baris, 24%".

Apa yang saya harapkan adalah scrollbar ASCII yang terlihat seperti

|
|
|
|
#
#
#
|
|
|

dan saya dapat mengkonfigurasi untuk muncul di sebelah kiri atau kanan (dan jika di sebelah kiri, posisi relatif ke nomor garis dan tanda lipat). Apakah sudah ada plugin Vim untuk melakukan ini, atau bagaimana saya bisa menulis saya sendiri? Kerangka kerja plugin Vim tampaknya tidak mendukung modifikasi UI secara langsung.

xiaq
sumber

Jawaban:

3

Jika Anda mempertimbangkan rute "tulis plugin Anda", fitur 'tanda' Vim mungkin tempat yang baik untuk memulai. Fitur ini adalah bagaimana misalnya, memeriksa sintaks plugin menyoroti kesalahan.

contoh tanda vim

Pendekatan sederhana untuk menempatkan tanda itu adalah:

  1. Tentukan di mana Anda berada dalam file sebagai persentase p
  2. Tentukan berapa banyak garis yang terlihat di jendela vim L
  3. Tempatkan tanda pada nomor baris terdekat int(p*L)
  4. Hitung ulang saat bergerak di sekitar file
dihapus
sumber
Terima kasih! Ini sangat dekat dengan persyaratan yang saya nyatakan, meskipun dari dokter tampaknya tanda-tanda hanya dapat ditarik di sisi kiri. Jawaban yang bagus, diterima!
xiaq
10

Dimungkinkan untuk menggunakan baris status sebagai bilah gulir. Saya dulu memiliki yang berikut ini di .vimrc saya, yang mengemulasi sebuah scrollbar (juga hanya secara horizontal, tetapi ternyata bekerja dengan sangat baik). Ini awalnya dibahas di milis vim_use beberapa tahun yang lalu.

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

Pastikan Anda memiliki laststatusopsi yang diatur ke 2.

Christian Brabandt
sumber
Saya sangat suka solusi ini karena menempatkan scrollbar di tempat di mana tidak memakan ruang dari jendela pengkodean. Terima kasih, Christian!
dotancohen
Saya suka ide itu, dan bahkan mungkin bisa hidup dengan pseudo-scrollbar horizontal. Tapi @redacted menghadirkan solusi yang lebih dekat dengan kebutuhan saya. miliki +1 pada jawaban Anda. Terima kasih!
xiaq
Bagaimana Anda mengatur warna BG penanda posisi gulir? Itu hampir tidak bisa dibedakan dari sisa bar menggunakan tema soliter di KDE.
Mike
Tebak dari baris terakhir, bahwa grup yang disorot adalah User1 dan User2 yang digunakan. Anda dapat mendefinisikannya kembali.
Christian Brabandt
6

Upaya saya untuk menebus kesalahan saya sebelumnya ....

Saya menyukai ide itu, jadi hari ini saya menulis sebuah plugin untuk VIM untuk memperlihatkan scrollbar 'jempol' menggunakan fitur tanda-tanda vim.

Ini masih SANGAT beta, tetapi masih dapat digunakan sekarang, saya masih memiliki pekerjaan untuk dilakukan, termasuk mengetik semua dokumen dan komentar dan hal-hal lainnya.

Saya akan memposting sumber di sini, tetapi Anda dapat menariknya dari Hg Repo saya . (Jangan tertawa terlalu keras atas hal-hal lain)

Ingat ... SANGAT beta, mengingat saya belum pernah menulis plugin sebelumnya, hanya mencoba-coba VIML selama bertahun-tahun. (kurang dari 12 jam dari konsep ke prototipe kerja! yay!)

Saya akan terus mengerjakannya, agak rapi. Warna-warna mencolok karena suatu alasan, mudah untuk melihat perubahan apa. Ini memiliki bug besar saat ini, Anda tidak dapat membuat semua tanda hilang dengan mematikannya. Saya tahu cara mengimplementasikan ini, hanya ingin berbagi.


Gambar bermanfaat:

Vim-Scrollbar sedang beraksi


VIM Curses Scrollbar - 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
sumber
Maksud Anda guioptionsdan sebagai bantuan dengan jelas menyatakan, ini hanya berfungsi untuk versi gui vim.
Christian Brabandt
Bagus. Saya telah menerapkan sesuatu yang serupa di plugin DynamicSigns. BTW: perhatikan, tanda-tanda itu tidak digambar, pada garis yang dilipat.
Christian Brabandt
Terima kasih! Saya pikir saya harus menebus foobar saya sebelumnya, maka saya menjadi lebih tertarik di dalamnya ... jadi saya menulisnya. Seperti biasa, pekerjaan awalnya mudah ... mendapatkan semuanya keren dan tampak keren adalah bagian yang membuat frustrasi. (tidak ada tanda-tanda pada lipatan ... dicatat)
lornix
Terima kasih! Tetapi menilai dari data @redacted memunculkan fitur tanda lebih awal dari Anda, jadi mungkin lebih sopan untuk menerima jawabannya. Telah memberi +1 pada jawaban Anda.
xiaq
1
Repo Anda telah dihapus. Alangkah baiknya jika Anda bisa memasang ini di suatu tempat seperti github dan membiarkan orang lain berkontribusi padanya. Saya benar-benar berpikir itu terlihat hebat.
Mike
0

Bukan solusi yang ideal tetapi Anda bisa mencari tahu di mana dalam file Anda berada di baris status dengan sesuatu seperti

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

atau gunakan set numberuntuk memiliki nomor baris sebelum setiap baris.

Kecuali Anda memodifikasi sumber vim (ncurses) maka saya tidak berpikir ini mungkin tapi saya bisa salah.

Sardathrion - menentang penyalahgunaan SE
sumber
Terima kasih tetapi saya sudah tahu ini ... Saya hanya mencari sesuatu yang lebih mudah di mata.
xiaq
Itu tembakan panjang.
Sardathrion - terhadap penyalahgunaan SE
0

Berikut ini adalah versi yang dapat diseret dengan mouse. Ini juga memperbarui hanya ketika roda gulir sedang digunakan - jika perlu scrollbar, tangan Anda harus di atas 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
q335r49
sumber
Ini berfungsi untuk mouse, tetapi tidak diperbarui ketika Anda menggulir dengan misalnya Ctrl + F. Marker tampaknya tetap dalam nomor baris aslinya. Melakukan :call UpdateScrollbox()pekerjaan, tetapi tidak ramah pengguna. Mungkin perlu kait pada semua tombol gerakan, atau, lebih baik, satu kait pada acara gulir, jika memungkinkan.
Ruslan