Панель прокрутки для vim (на основі прокльонів, а не gvim)?


10

Як користувач Linux, мені було досить зручно з інструментами CLI та TUI, але я сумую за невеликою смугою прокрутки, яка присутня майже в кожній програмі GUI. Мені завжди було простіше дізнатись, як триває файл і де я перебуваю зі смуги прокрутки замість "9752 рядків, 24%".

Що я очікую - це смуга прокрутки ASCII

|
|
|
|
#
#
#
|
|
|

і я можу налаштувати показ ліворуч або праворуч (а якщо ліворуч, відносне розташування до номерів рядків та позначок складки). Чи вже є плагін Vim для цього чи як я можу написати свій власний? Платформа Vim, схоже, не підтримує такі зміни інтерфейсу безпосередньо.

Відповіді:


3

Якщо ви розглядаєте маршрут "написати свій власний плагін", можливо, найкраще почати функцію "Знак" Vim . Ця функція полягає в тому, як, наприклад, плагіни для перевірки синтаксису виділяють помилки.

приклад знака vim

Простим підходом до розміщення знаку було б:

  1. Визначте, де ви знаходитесь у файлі у відсотках p
  2. Визначте, скільки ліній видно у вікнах vim L
  3. Розмістіть знак за номером рядка, найближчим до int(p*L)
  4. Перерахунок на рух навколо файлу

Дякую! Це дуже близько до моєї заявленої вимоги, хоча з док. Виходить, що знаки можна намалювати лише зліва. Хоча гарна відповідь, прийнято!
xiaq

10

Можна використовувати статус стану як смугу прокрутки. У моєму .vimrc у мене було таке, що емулює смугу прокрутки (також вона є лише горизонтально, але працює на диво добре). Про це спочатку йшлося про розсилку vim_use Mailinglist кілька років тому.

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

Переконайтеся, що у вас laststatusопція встановлена ​​на 2.


Мені дуже подобається це рішення, оскільки він розміщує смугу прокрутки в тому місці, де воно не займає місця у вікні кодування. Спасибі, Крістіан!
dotancohen

Мені подобається ідея, і навіть можливо можливо жити з горизонтальною псевдо-прокруткою. Але @redacted представив рішення, наближене до моєї заявленої вимоги. хоча у вашій відповіді є +1. Дякую!
xiaq

Як встановити колір маркера позиції прокрутки? Це майже не відрізняється від решти бар, використовуючи соляризовану тему на kde.
Майк

З останніх рядків здогадайтесь, що використовуються групи виділення User1 та User2. Ви можете їх переосмислити.
Крістіан Брабандт

6

Моя спроба викупу моїх раніше штучних па ...

Ідея мені сподобалась, тому сьогодні я написав плагін для VIM, щоб показати панель прокрутки "великий палець" за допомогою функції знаків vim.

Це все ще ДУЖЕ бета-версія, але вона зараз корисна, мені ще належить попрацювати над нею, включаючи введення всіх документів, коментарів та інших матеріалів.

Я опублікую джерело тут, але ви можете витягнути його з мого Hg Repo . (Не смійся надто сильно над іншими речами)

Пам’ятайте ... ДУЖЕ бета, враховуючи, що я ніколи раніше не писав плагін, лише дивувався у VimL протягом багатьох років. (менше 12 годин від концепції до робочого прототипу! так!)

Я буду продовжувати працювати над цим, якось акуратно. Кольори - принадні, просто зрозуміти, що змінюється. Зараз у нього велика помилка, ви не можете змусити всі знаки, вимкнувши її. Я знаю, як це реалізувати, просто хотів поділитися.


Фотографії корисні:

Vim-Прокрутка в дії


Прокрутка 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:

Ви маєте на увазі, guioptionsі як чітко зазначено у довідці, це працює лише для версії gui vim.
Крістіан Брабандт

Приємно. Я реалізував щось подібне у плагіні DynamicSigns. BTW: зауважте, що знаки не намальовані на складених лініях.
Крістіан Брабандт

Дякую! Я подумав, що мені слід компенсувати свій фобар раніше, тоді я зацікавився цим більше ... тому написав це. Як завжди, початкова робота легка ... все це стає пестливим і прикольним виглядом - це неприємно. (ніяких ознак на складках ... відмічено)
lornix

Дякую! Але судячи з даних @redacted, ознака ознаки виховувалася раніше, ніж ви, тому, можливо, більш ввічливо прийняти його відповідь. Поставте +1 у своїй відповіді.
xiaq

1
Ваше репо видалено. Було б чудово, якби ви могли поставити це десь, як github, і дозволити іншим сприяти цьому. Я дійсно думаю, що це виглядає чудово.
Майк

0

Не ідеальне рішення, але ви можете дізнатися, де у файлі ви перебуваєте у рядку статусу з чимось подібним

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

або використовуючи set numberномер рядка перед кожним рядком.

Якщо ви не змінили джерело vim (ncurses), я не думаю, що це можливо, але я можу помилитися.


Дякую, але я це вже знав ... Я просто шукав щось легше на оці.
xiaq


0

Ось версія, яку можна перетягувати мишкою. Він також оновлюється лише тоді, коли використовується колесо прокрутки - якщо вам потрібна смуга прокрутки, ваша рука в будь-якому випадку повинна знаходитися на миші.

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

Це працює для миші, але не оновлюється під час прокрутки, наприклад, Ctrl + F. Здається, маркер залишається в початковому номері рядка. Робота :call UpdateScrollbox()працює, але не є зручною для користувачів. Можливо, потрібні гачки на всіх клавішах руху, або, ще краще, один гачок для події прокрутки, якщо це можливо.
Руслан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.