Bildlaufleiste für vim (fluchbasiert, nicht gvim)?

10

Als Linux-Benutzer war ich mit CLI- und TUI-Tools ziemlich vertraut, aber ich vermisse die kleine Bildlaufleiste, die in fast jedem GUI-Programm vorhanden ist. Es war für mich immer einfacher zu erkennen, wie lang die Datei ist und wo ich mich in der Bildlaufleiste befinde, anstatt "9752 Zeilen, 24%".

Was ich erwarte, ist eine ASCII-Bildlaufleiste, die aussieht

|
|
|
|
#
#
#
|
|
|

und ich kann konfigurieren, dass links oder rechts angezeigt wird (und wenn links, die relative Position zu Zeilennummern und Falzmarkierungen). Gibt es dafür bereits ein Vim-Plugin oder wie kann ich mein eigenes schreiben? Das Plugin-Framework von Vim scheint solche Änderungen an der Benutzeroberfläche nicht direkt zu unterstützen.

xiaq
quelle

Antworten:

3

Wenn Sie die Route "Schreiben Sie Ihr eigenes Plugin" in Betracht ziehen, ist die " Zeichen" -Funktion von Vim möglicherweise ein guter Ausgangspunkt. Mit dieser Funktion können beispielsweise Plugins zur Syntaxprüfung Fehler hervorheben.

Beispiel für ein Vim-Zeichen

Ein einfacher Ansatz zum Platzieren des Zeichens wäre dann:

  1. Bestimmen Sie als Prozentsatz, wo Sie sich in der Datei befinden p
  2. Bestimmen Sie, wie viele Linien in den vim-Fenstern sichtbar sind L
  3. Platzieren Sie ein Schild an der Zeilennummer, die am nächsten liegt int(p*L)
  4. Berechnen Sie die Bewegung in der Datei neu
redigiert
quelle
Vielen Dank! Dies kommt meiner angegebenen Anforderung sehr nahe, obwohl aus dem Dokument hervorgeht, dass Zeichen nur auf der linken Seite gezeichnet werden können. Gute Antwort, akzeptiert!
Xiaq
10

Es ist möglich, die Statuszeile als Bildlaufleiste zu verwenden. Früher hatte ich Folgendes in meiner .vimrc, die eine Bildlaufleiste emuliert (auch nur horizontal, aber es funktioniert überraschend gut). Dies wurde ursprünglich vor einigen Jahren auf der Mailingliste vim_use diskutiert .

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

Stellen Sie sicher, dass Sie die laststatusOption auf 2 gesetzt haben.

Christian Brabandt
quelle
Diese Lösung gefällt mir sehr gut, da sie die Bildlaufleiste an einer Stelle platziert, an der sie keinen Platz im Codierungsfenster einnimmt. Danke, Christian!
Dotancohen
Ich mag die Idee und kann vielleicht sogar mit einer horizontalen Pseudo-Bildlaufleiste leben. Aber @redacted präsentierte eine Lösung, die meiner angegebenen Anforderung näher kommt. habe aber +1 auf deiner Antwort. Vielen Dank!
Xiaq
Wie stellen Sie die Farbe des Hintergrunds der Bildlaufpositionsmarkierung ein? Es ist fast nicht vom Rest der Bar zu unterscheiden, wenn man das solarisierte Thema auf kde verwendet.
Mike
Aus den letzten Zeilen geht hervor, dass die Hervorhebungsgruppen Benutzer1 und Benutzer2 verwendet werden. Sie können sie neu definieren.
Christian Brabandt
6

Mein Versuch zur Erlösung meiner früheren Fauxpas ....

Die Idee hat mir gefallen, deshalb habe ich heute ein Plugin für VIM geschrieben, um einen Bildlaufleisten-Daumen mit der Zeichenfunktion von vim anzuzeigen.

Es ist immer noch SEHR Beta, aber es ist momentan verwendbar. Ich muss noch daran arbeiten, einschließlich des Schreibens aller Dokumente, Kommentare und Sachen.

Ich werde die Quelle hier posten, aber Sie können sie gerne von meinem Hg Repo abrufen . (Lache nicht zu sehr über die anderen Sachen)

Denken Sie daran ... SEHR Beta, wenn man bedenkt, dass ich noch nie ein Plugin geschrieben habe und mich im Laufe der Jahre nur mit VimL beschäftigt habe. (weniger als 12 Stunden vom Konzept bis zum funktionierenden Prototyp! yay!)

Ich werde weiter daran arbeiten, irgendwie ordentlich. Die Farben sind aus einem bestimmten Grund grell und leicht zu erkennen, was sich ändert. Es hat gerade einen großen Fehler, Sie können nicht alle Zeichen verschwinden lassen, indem Sie es ausschalten. Ich weiß, wie man das umsetzt, wollte nur teilen.


Bilder sind nützlich:

Vim-Scrollbar in Aktion


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
quelle
Du meinst guioptionsund wie die Hilfe klar sagt, funktioniert dies nur für die GUI-Version von Vim.
Christian Brabandt
Nett. Ich habe etwas Ähnliches im DynamicSigns-Plugin implementiert. Übrigens: Beachten Sie, dass auf gefalteten Linien keine Zeichen gezeichnet werden.
Christian Brabandt
Vielen Dank! Ich dachte, ich sollte meine Foobar früher wieder gut machen, dann interessierte ich mich mehr dafür ... also schrieb ich es. Wie immer ist die anfängliche Arbeit einfach ... es ist frustrierend, alles schick und cool aussehen zu lassen. (keine Anzeichen auf Falten ... notiert)
Lornix
Vielen Dank! Aber nach den Daten zu urteilen, die @redacted früher als Sie hervorgebracht hat, ist es vielleicht höflicher, seine Antwort zu akzeptieren. Habe + 1 auf deine Antwort gegeben.
Xiaq
1
Ihr Repo wurde entfernt. Es wäre großartig, wenn Sie dies irgendwo wie Github aufstellen und andere dazu beitragen könnten. Ich finde es wirklich toll.
Mike
0

Keine ideale Lösung, aber Sie können herausfinden, wo in der Datei Sie sich entweder in der Statuszeile mit so etwas wie befinden

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

oder verwenden set number, um vor jeder Zeile eine Zeilennummer zu haben.

Wenn Sie die vim-Quelle (ncurses) nicht geändert haben, denke ich nicht, dass dies möglich ist, aber ich könnte mich irren.

Sardathrion - gegen SE-Missbrauch
quelle
Danke, aber das wusste ich schon ... Ich habe nur nach etwas gesucht, das das Auge leichter macht.
Xiaq
Es war ein langer Schuss.
Sardathrion - gegen SE Missbrauch
0

Hier ist eine Version, die mit der Maus gezogen werden kann. Es wird auch nur aktualisiert, wenn das Scrollrad verwendet wird. Wenn Sie eine Scrollbar benötigen, sollte Ihre Hand sowieso mit der Maus sein.

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
quelle
Dies funktioniert für die Maus, wird jedoch nicht aktualisiert, wenn Sie mit z. B. Strg + F scrollen. Der Marker scheint in seiner ursprünglichen Zeilennummer zu bleiben. Das :call UpdateScrollbox()funktioniert, ist aber nicht benutzerfreundlich. Benötigt möglicherweise Haken an allen Bewegungstasten oder besser einen Haken an einem Bildlaufereignis, wenn dies möglich ist.
Ruslan