scrollbar in xterm vim

279 views
Skip to first unread message

Michael Goerz

unread,
May 18, 2008, 1:34:36 PM5/18/08
to vim...@googlegroups.com
Hi,

after using vim in an xterm to edit some bigger files, I often get the
feeling of being "lost" in the file after a while, i.e. I don't feel in
touch with my current position in the file. Of course, line numbers and
the percentage of where I am are displayed, but still. I then recently,
while using gvim again, realized that the reason for my weird feeling is
that there's no scroll bar in the xterm mode. It seems that it makes a
big difference for me psychologically to have a visual representation of
where I am in the file, as opposed to just seeing the line
number/percentage, which gives me the information, but in an abstract
way. So, I was wondering if there's a way to get a scroll bar in the
non-gui version of vim as well. Maybe it's a capability that I haven't
found yet? It also seems feasible that this is something that an
extension script could do. Maybe something like that exists (didn't find
anything on the website). I'm not necessarily looking for something that
I can drag to change position, just really a visual representation of
where I am in the file proportionally. Does anyone know of anything like
that?

Thanks,
Michael

Tony Mechelynck

unread,
May 18, 2008, 5:52:33 PM5/18/08
to vim...@googlegroups.com

AFAIK, scrollbars are set by flags of the 'guioptions' setting, which is
only available in GUI mode (the help says "if compiled with GUI enabled"
but I just ran a short test which showed that it doesn't work in Console
mode, even if compiled with GUI enabled).

So, the short answer would be: No, you can't do it.

A slightly longer answer is: Since you already use xterm, which uses the
X server, why not go one step furter and use gvim? You would then have
all the scrollbars you would want (even vertical scrollbars on both
sides of the only window, if that's what you want).


Best regards,
Tony.
--
I cannot conceive that anybody will require multiplications at the rate
of 40,000 or even 4,000 per hour ...
-- F. H. Wales (1936)

Michael Goerz

unread,
May 18, 2008, 7:47:36 PM5/18/08
to vim...@googlegroups.com
gvim is not bad in that respect, but it has some shortcomings that make
it difficult for me to use. The mail problem is that it's builtin shell
is very limited. When I do :shell, colors and many other things don't
work. It also can't use perl or python scripts, which I have set as
keywordprg for some filetypes. In short, the shell-interaction isn't
too good for gvim, and that's something that's quite important for me.

I thought a little bit about the possibility of a "scrollbar", or a
visual representation of a position in the file. Maybe there's a way to
put it in the statusline. Right now, I have this as my statusline:

set statusline=%f\ [%{(&fenc==\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\
&bomb)?\",B\":\"\")}%M%R%H%W]\ %y\ [%l/%L,%v]\ [%p%%]

That evaluates to something like this:

.vimrc [utf-8] [vim] [41/382,23] [10%]

Now, maybe there's a way to have something more visual instead of the
last block, which shows the percentage. What would be great if the whole
status bar could extend over the entire available width, and show
something like a progressbar, so that it looks like this:

.vimrc [utf-8] [vim] [41/382,23] [----o--------------------------------]

The 'o' would move proportionally with the position in the file. Just an
idea.

Right now, I'm not sure if/how this could be implemented. The element
would have to know it's own width, and the width of the current terminal
window. Maybe someone has some ideas about this?

Thanks,
Michael

sc

unread,
May 18, 2008, 8:02:55 PM5/18/08
to vim...@googlegroups.com

i use 'rul' (following) to find out how wide my window is:


#!/usr/bin/python
from sys import argv
from subprocess import Popen, PIPE
if len(argv) < 2:
ds = int(Popen(["tput", "cols"], stdout=PIPE).communicate()[0])
else:
ds = int(argv[1])

str = "."
lstr = len(str)
while lstr < ds:
if (lstr + 1) % 10 == 0:
str += (("%d") % ((lstr + 1) / 10))[-1]
elif (lstr + 1) % 5 == 0:
str += "+"
else:
str += "."
lstr = len(str)

print "%s" % str

Andreas Politz

unread,
May 19, 2008, 5:09:22 AM5/19/08
to vim...@googlegroups.com
Michael Goerz wrote:
>
> I thought a little bit about the possibility of a "scrollbar", or a
> visual representation of a position in the file. Maybe there's a way to
> put it in the statusline. Right now, I have this as my statusline:
>
> set statusline=%f\ [%{(&fenc==\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\
> &bomb)?\",B\":\"\")}%M%R%H%W]\ %y\ [%l/%L,%v]\ [%p%%]
>
> That evaluates to something like this:
>
> .vimrc [utf-8] [vim] [41/382,23] [10%]
>
> Now, maybe there's a way to have something more visual instead of the
> last block, which shows the percentage. What would be great if the whole
> status bar could extend over the entire available width, and show
> something like a progressbar, so that it looks like this:
>
> .vimrc [utf-8] [vim] [41/382,23] [----o--------------------------------]
>
> The 'o' would move proportionally with the position in the file. Just an
> idea.
>
> Right now, I'm not sure if/how this could be implemented. The element
> would have to know it's own width, and the width of the current terminal
> window. Maybe someone has some ideas about this?
>
> Thanks,
> Michael
>
> >
>

It's easier to take a wild guess at how much place will be there for the
scrollbar.
Otherwise the length of the other fields have to be computed.


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

-ap

Michael Goerz

unread,
May 19, 2008, 10:27:55 AM5/19/08
to vim...@googlegroups.com
Andreas Politz wrote, on 05/19/2008 11:09 AM:
> Michael Goerz wrote:
>> I thought a little bit about the possibility of a "scrollbar", or a
>> visual representation of a position in the file. Maybe there's a way to
>> put it in the statusline. Right now, I have this as my statusline:
>>
>> set statusline=%f\ [%{(&fenc==\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\
>> &bomb)?\",B\":\"\")}%M%R%H%W]\ %y\ [%l/%L,%v]\ [%p%%]
>>
>> That evaluates to something like this:
>>
>> .vimrc [utf-8] [vim] [41/382,23] [10%]
>>
>> Now, maybe there's a way to have something more visual instead of the
>> last block, which shows the percentage. What would be great if the whole
>> status bar could extend over the entire available width, and show
>> something like a progressbar, so that it looks like this:
>>
>> .vimrc [utf-8] [vim] [41/382,23] [----o--------------------------------]
>>
>> The 'o' would move proportionally with the position in the file. Just an
>> idea.
>>
>> Right now, I'm not sure if/how this could be implemented. The element
>> would have to know it's own width, and the width of the current terminal
>> window. Maybe someone has some ideas about this?
>
> It's easier to take a wild guess at how much place will be there for the
> scrollbar.
> Otherwise the length of the other fields have to be computed.

Wow, this is quite amazing! Thanks so much! I have some further thoughts
about the details...

>
> "-----------%<-----------------
> 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

Maybe the guess could be less wild. The most variable thing is the
filename, so what I did was to use the following two lines instead of
the last one above:
let takenwidth = len(bufname(winbufnr(winnr()))) + 40
let barWidth = &columns - takenwidth
This already give a rather accurate result. Maybe there are even more
parts that can be calculated? Especially the '%M%R%H%W' would be
interesting.

> 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

This last part confuses me. Obviously, these two highlight definitions
define the highlighting of the bar. But where do the names User1 and
User2 come from? How does the bar know that it's using that format?

> set stl=%!STL()
> "-----------%<-----------------

Thanks,
Michael

Tony Mechelynck

unread,
May 19, 2008, 10:49:45 AM5/19/08
to vim...@googlegroups.com
>> let barWidth =&columns - 65 "<-- wild guess

>
> Maybe the guess could be less wild. The most variable thing is the
> filename, so what I did was to use the following two lines instead of
> the last one above:
> let takenwidth = len(bufname(winbufnr(winnr()))) + 40
> let barWidth =&columns - takenwidth

> This already give a rather accurate result. Maybe there are even more
> parts that can be calculated? Especially the '%M%R%H%W' would be
> interesting.
>
>> 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
>
> This last part confuses me. Obviously, these two highlight definitions
> define the highlighting of the bar. But where do the names User1 and
> User2 come from? How does the bar know that it's using that format?

From special codes in the 'statusline' option value, which it gets from
the complex "let bar = bla bla bla" above:

%1* use User1 from now on
%2* use User2 from now on
%0* go back to StatusLine (or StatusLineNC)

see ":help 'statusline'".

>
>> set stl=%!STL()
>> "-----------%<-----------------
>
> Thanks,
> Michael


Best regards,
Tony.
--
(letter from Mark to Mike, about the film's probale certificate)
For an 'A' we would have to: Lose as may shits as possible Take Jesus
Christ out, if possible Loose "I fart in your general direction" Lose
"the oral sex" Lose "oh, fuck off" Lose "We make castanets out of
your
testicles"
"Monty Python and the Holy Grail" PYTHON (MONTY)
PICTURES LTD

Michael Goerz

unread,
May 19, 2008, 12:52:01 PM5/19/08
to vim...@googlegroups.com

I got something pretty stable now. The "final results" are at
http://www.physik.fu-berlin.de/~goerz/linux.html#vim

The only thing that's still missing is the total number of lines in the
file. Is there any way to get that number in a script?

Cheers,
Michael

Benjamin Fritz

unread,
May 19, 2008, 2:49:02 PM5/19/08
to vim...@googlegroups.com

:help line()

Reply all
Reply to author
Forward
0 new messages