views:

81

answers:

3

When you run git clone, it updates progress in place. For example, the percentage of the objects received changes in place.

user@athena:~/cloj/src$ git clone git://git.boinkor.net/slime.git
Initialized empty Git repository in /home/user/cloj/src/slime/.git/
remote: Counting objects: 15936, done.
remote: Compressing objects: 100% (5500/5500), done.
Receiving objects:  28% (4547/15936), 3.16 MiB | 165 KiB/s

How is this acccomplished? Does it use ncurses or something even simpler, like some combination of backspace characters and regular character output?

I'm especially interested in how this kind of console output could be accomplished from Ruby.

EDIT

My original question is answered. But here's an addendum. When you use MPlayer, for example, it not only updates a line to show current progress, but also the previous line (e.g. when you press pause).

 =====  PAUSE  =====
A:  79.9 (01:19.9) of 4718.0 ( 1:18:38.0)  0.3% 

How would you update two lines of output in-place?

+3  A: 

Use carriage return. '\r' should usually work.

Moron
Here's an example: `10.times{|i| STDOUT.write "\r#{i}"; sleep 1}`
Mladen Jablanović
Thanks. But why does \r have that effect in Unix?
dan
@dan: Perhaps this has the answer: http://en.wikipedia.org/wiki/Carriage_return
Moron
A: 

There are a number of curses librbaries for Ruby. I believe rbbcurse is the most maintained.

Farrel
+1  A: 

git/progress.c

...
        eol = done ? done : "   \r";
...
                fprintf(stderr, "...%s", ..., eol);
                fflush(stderr);

Git simply emits a carriage return and no line feed, which the terminal interprets as "move to first column".

ephemient