www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Color your terminal's output

reply Jens Mueller <jens.k.mueller gmx.de> writes:
Hi,

I started writing a simple module to color terminal output some time ago.
In a recent thread people seemed interested in having such
functionality. I cleaned up this code and kindly ask whether such a
module is considered a useful addition.

On Posix systems it uses 4 Curses functions and on Windows systems the
Windows API is used. I tested it on Linux (using different terminal
emulators) and on Windows XP.
It allows setting foreground and background colors and setting bold,
underline, reverse and blink font faces.

Get the code from
https://raw.github.com/jkm/phobos/terminal/std/terminal.d

To test (hopefully filling your terminal with colored output) run
on Posix
32 bit
$ dmd -unittest -m32 /usr/lib/libncurses.a -run terminal.d
64 bit
$ dmd -unittest -m64 /usr/lib/libncurses.a -run terminal.d

(The library path may need to be adjusted.)

and on Windows
$ dmd -unittest -run terminal.d

At this point there are some issues that I need to figure out, namely:
* Is there a portable way to unset font face attributes on Posix?
* How to portably obtain the default foreground/background color on
  Posix?
* How to properly test such a module?
* Possible license problems: I have no idea whether it's allowed to link
  against whatever license (the curses implementation uses). In doubt I
  need to use the license that I link against, I suppose.

Any help is very appreciated.

Though this module is functionality-wise inferior to something like
ncurses it conveniently allows coloring output for most use cases.

Jens
Oct 06 2011
next sibling parent reply Johannes Pfau <spam example.com> writes:
Jens Mueller wrote:
Hi,

I started writing a simple module to color terminal output some time
ago. In a recent thread people seemed interested in having such
functionality. I cleaned up this code and kindly ask whether such a
module is considered a useful addition.

On Posix systems it uses 4 Curses functions and on Windows systems the
Windows API is used. I tested it on Linux (using different terminal
emulators) and on Windows XP.
It allows setting foreground and background colors and setting bold,
underline, reverse and blink font faces.
Get the code from
https://raw.github.com/jkm/phobos/terminal/std/terminal.d

To test (hopefully filling your terminal with colored output) run
on Posix
32 bit
$ dmd -unittest -m32 /usr/lib/libncurses.a -run terminal.d
64 bit
$ dmd -unittest -m64 /usr/lib/libncurses.a -run terminal.d

(The library path may need to be adjusted.)

and on Windows
$ dmd -unittest -run terminal.d

At this point there are some issues that I need to figure out, namely:
* Is there a portable way to unset font face attributes on Posix?
* How to portably obtain the default foreground/background color on
  Posix?
* How to properly test such a module?
* Possible license problems: I have no idea whether it's allowed to
link
  against whatever license (the curses implementation uses). In doubt I
  need to use the license that I link against, I suppose.

You could use ANSI codes on posix to avoid a dependency on curses: http://en.wikipedia.org/wiki/ANSI_escape_code#Colors But I think using curses is ok. ncurses is MIT licensed and can be used as a dynamic library, so I don't think there are license problems. However, I'd recommend to load ncurses dynamically with dlopen/dlsym and fallback to simple text output if the ncurses library cannot be loaded.
Any help is very appreciated.

Though this module is functionality-wise inferior to something like
ncurses it conveniently allows coloring output for most use cases.

as you already use these functions: http://linux.die.net/man/3/setupterm it'd be nice to have wget-like progressbars and 'updateable' text labels. Shouldn't be as fancy as full ncurses, for most use cases it's good enough to modify the current line. +Points if it properly handles terminal width and resizing.
Jens

-- Johannes Pfau
Oct 07 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Trass3r" <un known.com> wrote in message news:op.v2zhq60v3ncmek enigma...
 I see. You mean using curses if available and falling back to ISO/IEC
 6429. So you think that supporting ISO/IEC 6429 terminals is too
 limited, aren't you?

Well I personally only care about bash and Windoze console. I guess these support ISO 6429?!

Windows console windows don't, oddly enough. Even though MS-DOS did if you had ANSI.SYS loaded. And, maybe I'm wrong, but I would think that shell interpreter wouldn't have anything to do with whether or not ANSI escape codes are avilable. Isn't that more a matter of terminal program (ie, xterm, vs...umm, all those others...)
Oct 07 2011
prev sibling next sibling parent Iain S <staffell gmail.com> writes:
Just to add my 2 cents...

I have been looking for a simple way of altering the Windows terminal
colour, so I would personally say this is worth including - or at the
very least converting into a usable header/module/???.

I am very new to D, so I can't figure out how to make use of the code
posted on github.  Perhaps it's simpler than I think :)
Dec 13 2011
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Axl wrote:
 On Sunday, 10 March 2013 at 14:38:15 UTC, Jens Mueller wrote:
Axl wrote:
When I run:

$ dmd -unittest -m64 /usr/lib/x86_64-linux-gnu/libncurses.a -run
terminal.d

I get the follwoing output:

terminal.o: In function `_D8terminal12_staticCtor2FZv':
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x27): undefined
reference to `setupterm'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x81): undefined
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x12b): undefined
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x1cc): undefined
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x26d): undefined
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x30e): undefined
reference to `tigetstr'
terminal.o:terminal.d:(.text._D8terminal12_staticCtor2FZv+0x3af):
more undefined references to `tigetstr' follow
terminal.o: In function
`_D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv':
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0xb2):
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0xc2):
undefined reference to `tputs'
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0x147):
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0x157):
undefined reference to `tputs'
terminal.o: In function
`_D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv':
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0xac):
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0xbc):
undefined reference to `tputs'
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0x13e):
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0x14e):
undefined reference to `tputs'
collect2: ld returned 1 exit status
--- errorlevel 1

I know it is a linker error, but I cannot fix it. Any ideas?

Have you tried linking against libtermcap/libtinfo? Jens

It works against both those libs.

You only need one of those. libtermcap just points to libtinfo, at least on my system. You don't need ncurses. Glad it works. BTW you can report problems at https://github.com/jkm/terminal/issues. Jens
Mar 10 2013
prev sibling next sibling parent Trass3r <un known.com> writes:
 You could use ANSI codes on posix to avoid a dependency on curses:
 http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
 But I think using curses is ok. ncurses is MIT licensed and can be
 used as a dynamic library, so I don't think there are license problems.

 However, I'd recommend to load ncurses dynamically with dlopen/dlsym
 and fallback to simple text output if the ncurses library cannot be
 loaded.

+1 There shouldn't be a hard dependency on curses.
Oct 07 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Trass3r wrote:
You could use ANSI codes on posix to avoid a dependency on curses:
http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
But I think using curses is ok. ncurses is MIT licensed and can be
used as a dynamic library, so I don't think there are license problems.

However, I'd recommend to load ncurses dynamically with dlopen/dlsym
and fallback to simple text output if the ncurses library cannot be
loaded.

+1 There shouldn't be a hard dependency on curses.

I had the impression that even though there is this standard how do I know that I have a standard-compliant terminal. Can I just assume this? I started using curses because I had the impression there may be non-standard terminals. But this seems to be minor issue. I will change this if people are happy with Windows and ISO/IEC 6429 compliant terminals only. Thanks. Jens
Oct 07 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Johannes Pfau wrote:
 Jens Mueller wrote:
Hi,

I started writing a simple module to color terminal output some time
ago. In a recent thread people seemed interested in having such
functionality. I cleaned up this code and kindly ask whether such a
module is considered a useful addition.

On Posix systems it uses 4 Curses functions and on Windows systems the
Windows API is used. I tested it on Linux (using different terminal
emulators) and on Windows XP.
It allows setting foreground and background colors and setting bold,
underline, reverse and blink font faces.
Get the code from
https://raw.github.com/jkm/phobos/terminal/std/terminal.d

To test (hopefully filling your terminal with colored output) run
on Posix
32 bit
$ dmd -unittest -m32 /usr/lib/libncurses.a -run terminal.d
64 bit
$ dmd -unittest -m64 /usr/lib/libncurses.a -run terminal.d

(The library path may need to be adjusted.)

and on Windows
$ dmd -unittest -run terminal.d

At this point there are some issues that I need to figure out, namely:
* Is there a portable way to unset font face attributes on Posix?
* How to portably obtain the default foreground/background color on
  Posix?
* How to properly test such a module?
* Possible license problems: I have no idea whether it's allowed to
link
  against whatever license (the curses implementation uses). In doubt I
  need to use the license that I link against, I suppose.

You could use ANSI codes on posix to avoid a dependency on curses: http://en.wikipedia.org/wiki/ANSI_escape_code#Colors But I think using curses is ok. ncurses is MIT licensed and can be used as a dynamic library, so I don't think there are license problems. However, I'd recommend to load ncurses dynamically with dlopen/dlsym and fallback to simple text output if the ncurses library cannot be loaded.

Using the ANSI codes is fine with me. I assumed they aren't that portable but it seems fine.
Any help is very appreciated.

Though this module is functionality-wise inferior to something like
ncurses it conveniently allows coloring output for most use cases.

as you already use these functions: http://linux.die.net/man/3/setupterm it'd be nice to have wget-like progressbars and 'updateable' text labels. Shouldn't be as fancy as full ncurses, for most use cases it's good enough to modify the current line. +Points if it properly handles terminal width and resizing.

I believe progress bars are easy to add. Boost's progress_bar should be fairly easy to port. It'll be nice if you could provide a pull request for this. Is this feasible for you? Regarding update able text labels I'm not sure how they are typically used. So I would also prefer some pull request from somebody with a common use case. I'm just pushing this color support because I'm using it in some tool. And it may be useful to others. I believe it's a good thing to add the features you need for your project via a pull request. Jens
Oct 07 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
Am 07.10.2011, 14:51 Uhr, schrieb Jens Mueller <jens.k.mueller gmx.de>:

 Trass3r wrote:
You could use ANSI codes on posix to avoid a dependency on curses:
http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
But I think using curses is ok. ncurses is MIT licensed and can be
used as a dynamic library, so I don't think there are license problems.

However, I'd recommend to load ncurses dynamically with dlopen/dlsym
and fallback to simple text output if the ncurses library cannot be
loaded.

+1 There shouldn't be a hard dependency on curses.

I had the impression that even though there is this standard how do I know that I have a standard-compliant terminal. Can I just assume this? I started using curses because I had the impression there may be non-standard terminals. But this seems to be minor issue. I will change this if people are happy with Windows and ISO/IEC 6429 compliant terminals only. Thanks.

As Johannes already said, it's perfectly possible to implement both approaches and choose at runtime.
Oct 07 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Trass3r wrote:
 Am 07.10.2011, 14:51 Uhr, schrieb Jens Mueller <jens.k.mueller gmx.de>:
 
Trass3r wrote:
You could use ANSI codes on posix to avoid a dependency on curses:
http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
But I think using curses is ok. ncurses is MIT licensed and can be
used as a dynamic library, so I don't think there are license problems.

However, I'd recommend to load ncurses dynamically with dlopen/dlsym
and fallback to simple text output if the ncurses library cannot be
loaded.

+1 There shouldn't be a hard dependency on curses.

I had the impression that even though there is this standard how do I know that I have a standard-compliant terminal. Can I just assume this? I started using curses because I had the impression there may be non-standard terminals. But this seems to be minor issue. I will change this if people are happy with Windows and ISO/IEC 6429 compliant terminals only. Thanks.

As Johannes already said, it's perfectly possible to implement both approaches and choose at runtime.

I see. You mean using curses if available and falling back to ISO/IEC 6429. So you think that supporting ISO/IEC 6429 terminals is too limited, aren't you? Jens
Oct 07 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
 I see. You mean using curses if available and falling back to ISO/IEC
 6429. So you think that supporting ISO/IEC 6429 terminals is too
 limited, aren't you?

Well I personally only care about bash and Windoze console. I guess these support ISO 6429?!
Oct 07 2011
prev sibling next sibling parent Johannes Pfau <spam example.com> writes:
Jens Mueller wrote:
Trass3r wrote:
You could use ANSI codes on posix to avoid a dependency on curses:
http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
But I think using curses is ok. ncurses is MIT licensed and can be
used as a dynamic library, so I don't think there are license
problems.

However, I'd recommend to load ncurses dynamically with dlopen/dlsym
and fallback to simple text output if the ncurses library cannot be
loaded.

+1 There shouldn't be a hard dependency on curses.

I had the impression that even though there is this standard how do I know that I have a standard-compliant terminal. Can I just assume this? I started using curses because I had the impression there may be non-standard terminals. But this seems to be minor issue. I will change this if people are happy with Windows and ISO/IEC 6429 compliant terminals only. Thanks. Jens

AFAIK the capabilities of a terminal are found using the terminfo database: http://en.wikipedia.org/wiki/Terminal_capabilities But it seems there's no standard stand-alone library to access this database. Curses seems the only simple way to access this database, so I'd say: Try to load curses at runtime, if that fails, fall back to simple non-colored text output. -- Johannes Pfau
Oct 08 2011
prev sibling next sibling parent Johannes Pfau <spam example.com> writes:
Jens Mueller wrote:
Trass3r wrote:
You could use ANSI codes on posix to avoid a dependency on curses:
http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
But I think using curses is ok. ncurses is MIT licensed and can be
used as a dynamic library, so I don't think there are license
problems.

However, I'd recommend to load ncurses dynamically with dlopen/dlsym
and fallback to simple text output if the ncurses library cannot be
loaded.

+1 There shouldn't be a hard dependency on curses.

I had the impression that even though there is this standard how do I know that I have a standard-compliant terminal. Can I just assume this? I started using curses because I had the impression there may be non-standard terminals. But this seems to be minor issue. I will change this if people are happy with Windows and ISO/IEC 6429 compliant terminals only. Thanks. Jens

AFAIK the capabilities of a terminal are found using the terminfo database: http://en.wikipedia.org/wiki/Terminal_capabilities But it seems there's no standard stand-alone library to access this database. Curses seems the only simple way to access this database, so I'd say: Try to load curses at runtime, if that fails, fall back to simple non-colored text output. BTW: you could also use isatty (http://linux.die.net/man/3/isatty) to detect if stdout has been redirected and disable color output in that case. For windows: https://forums.embarcadero.com/thread.jspa?threadID=21194 or http://msdn.microsoft.com/de-de/library/f4s0ddew(v=vs.80).aspx -- Johannes Pfau
Oct 08 2011
prev sibling next sibling parent Johannes Pfau <spam example.com> writes:
Jens Mueller wrote:
Johannes Pfau wrote:
 Jens Mueller wrote:
Hi,

I started writing a simple module to color terminal output some time
ago. In a recent thread people seemed interested in having such
functionality. I cleaned up this code and kindly ask whether such a
module is considered a useful addition.

On Posix systems it uses 4 Curses functions and on Windows systems
the Windows API is used. I tested it on Linux (using different
terminal emulators) and on Windows XP.
It allows setting foreground and background colors and setting bold,
underline, reverse and blink font faces.
Get the code from
https://raw.github.com/jkm/phobos/terminal/std/terminal.d

To test (hopefully filling your terminal with colored output) run
on Posix
32 bit
$ dmd -unittest -m32 /usr/lib/libncurses.a -run terminal.d
64 bit
$ dmd -unittest -m64 /usr/lib/libncurses.a -run terminal.d

(The library path may need to be adjusted.)

and on Windows
$ dmd -unittest -run terminal.d

At this point there are some issues that I need to figure out,
namely:
* Is there a portable way to unset font face attributes on Posix?
* How to portably obtain the default foreground/background color on
  Posix?
* How to properly test such a module?
* Possible license problems: I have no idea whether it's allowed to
link
  against whatever license (the curses implementation uses). In
 doubt I need to use the license that I link against, I suppose.

You could use ANSI codes on posix to avoid a dependency on curses: http://en.wikipedia.org/wiki/ANSI_escape_code#Colors But I think using curses is ok. ncurses is MIT licensed and can be used as a dynamic library, so I don't think there are license problems. However, I'd recommend to load ncurses dynamically with dlopen/dlsym and fallback to simple text output if the ncurses library cannot be loaded.

Using the ANSI codes is fine with me. I assumed they aren't that portable but it seems fine.

I'd still use curses though, as it abstracts some things away. Finding terminal capabilities and similar stuff.
Any help is very appreciated.

Though this module is functionality-wise inferior to something like
ncurses it conveniently allows coloring output for most use cases.

as you already use these functions: http://linux.die.net/man/3/setupterm it'd be nice to have wget-like progressbars and 'updateable' text labels. Shouldn't be as fancy as full ncurses, for most use cases it's good enough to modify the current line. +Points if it properly handles terminal width and resizing.

I believe progress bars are easy to add. Boost's progress_bar should be fairly easy to port. It'll be nice if you could provide a pull request for this. Is this feasible for you?

Sure, I'll have a look at it soon. You're talking about this progress_display class, right? http://www.boost.org/doc/libs/1_47_0/boost/progress.hpp
Regarding update able text labels I'm not sure how they are typically
used. So I would also prefer some pull request from somebody with a
common use case.

Well, think of wget's output: 0% [ ] 1.154.567 123K/s ETA 57m 6s | | | | | updateable label progressbar u-label u-label u-label
I'm just pushing this color support because I'm using it in some tool.
And it may be useful to others. I believe it's a good thing to add the
features you need for your project via a pull request.

Jens

-- Johannes Pfau
Oct 08 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Nick Sabalausky wrote:
 "Trass3r" <un known.com> wrote in message news:op.v2zhq60v3ncmek enigma...
 I see. You mean using curses if available and falling back to ISO/IEC
 6429. So you think that supporting ISO/IEC 6429 terminals is too
 limited, aren't you?

Well I personally only care about bash and Windoze console. I guess these support ISO 6429?!

Windows console windows don't, oddly enough. Even though MS-DOS did if you had ANSI.SYS loaded. And, maybe I'm wrong, but I would think that shell interpreter wouldn't have anything to do with whether or not ANSI escape codes are avilable. Isn't that more a matter of terminal program (ie, xterm, vs...umm, all those others...)

Yes. The shell has nothing to do with it. As far as I understand it even ncurses uses terminfo to send the appropriate escape sequences. I just will load the library at runtime. But I wonder what's the general interest and whether it makes sense as a module. Jens
Oct 08 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Johannes Pfau wrote:
 Jens Mueller wrote:
Johannes Pfau wrote:
 You could use ANSI codes on posix to avoid a dependency on curses:
 http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
 But I think using curses is ok. ncurses is MIT licensed and can be
 used as a dynamic library, so I don't think there are license
 problems.
 
 However, I'd recommend to load ncurses dynamically with dlopen/dlsym
 and fallback to simple text output if the ncurses library cannot be
 loaded.

Using the ANSI codes is fine with me. I assumed they aren't that portable but it seems fine.

I'd still use curses though, as it abstracts some things away. Finding terminal capabilities and similar stuff.
Any help is very appreciated.

Though this module is functionality-wise inferior to something like
ncurses it conveniently allows coloring output for most use cases.

as you already use these functions: http://linux.die.net/man/3/setupterm it'd be nice to have wget-like progressbars and 'updateable' text labels. Shouldn't be as fancy as full ncurses, for most use cases it's good enough to modify the current line. +Points if it properly handles terminal width and resizing.

I believe progress bars are easy to add. Boost's progress_bar should be fairly easy to port. It'll be nice if you could provide a pull request for this. Is this feasible for you?

Sure, I'll have a look at it soon. You're talking about this progress_display class, right? http://www.boost.org/doc/libs/1_47_0/boost/progress.hpp

Yes. Maybe it's too simple compared to wget's.
Regarding update able text labels I'm not sure how they are typically
used. So I would also prefer some pull request from somebody with a
common use case.

Well, think of wget's output: 0% [ ] 1.154.567 123K/s ETA 57m 6s | | | | | updateable label progressbar u-label u-label u-label

That looks very useful. Is this difficult to add? Can't one just delete the entire line and replace it with an appropriately updated one? Is this too naive? This would be easy to implement on Windows as well, I suppose. Jens
Oct 09 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Johannes Pfau wrote:
 Jens Mueller wrote:
Trass3r wrote:
You could use ANSI codes on posix to avoid a dependency on curses:
http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
But I think using curses is ok. ncurses is MIT licensed and can be
used as a dynamic library, so I don't think there are license
problems.

However, I'd recommend to load ncurses dynamically with dlopen/dlsym
and fallback to simple text output if the ncurses library cannot be
loaded.

+1 There shouldn't be a hard dependency on curses.

I had the impression that even though there is this standard how do I know that I have a standard-compliant terminal. Can I just assume this? I started using curses because I had the impression there may be non-standard terminals. But this seems to be minor issue. I will change this if people are happy with Windows and ISO/IEC 6429 compliant terminals only. Thanks. Jens

AFAIK the capabilities of a terminal are found using the terminfo database: http://en.wikipedia.org/wiki/Terminal_capabilities But it seems there's no standard stand-alone library to access this database. Curses seems the only simple way to access this database, so

That's how it seems to be.
 I'd say:
 Try to load curses at runtime, if that fails, fall back to simple
 non-colored text output.

I'd better throw an exception.
 BTW: you could also use isatty (http://linux.die.net/man/3/isatty) to
 detect if stdout has been redirected and disable color output in that
 case.
 For windows:
 https://forums.embarcadero.com/thread.jspa?threadID=21194
 or
 http://msdn.microsoft.com/de-de/library/f4s0ddew(v=vs.80).aspx

Nice idea. Thanks. Jens
Oct 09 2011
prev sibling next sibling parent Johannes Pfau <spam example.com> writes:
Jens Mueller wrote:
Johannes Pfau wrote:
 Jens Mueller wrote:
Johannes Pfau wrote:
 You could use ANSI codes on posix to avoid a dependency on curses:
 http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
 But I think using curses is ok. ncurses is MIT licensed and can be
 used as a dynamic library, so I don't think there are license
 problems.
 
 However, I'd recommend to load ncurses dynamically with
 dlopen/dlsym and fallback to simple text output if the ncurses
 library cannot be loaded.

Using the ANSI codes is fine with me. I assumed they aren't that portable but it seems fine.

I'd still use curses though, as it abstracts some things away. Finding terminal capabilities and similar stuff.
Any help is very appreciated.

Though this module is functionality-wise inferior to something
like ncurses it conveniently allows coloring output for most use
cases.

as you already use these functions: http://linux.die.net/man/3/setupterm it'd be nice to have wget-like progressbars and 'updateable' text labels. Shouldn't be as fancy as full ncurses, for most use cases it's good enough to modify the current line. +Points if it properly handles terminal width and resizing.

I believe progress bars are easy to add. Boost's progress_bar should be fairly easy to port. It'll be nice if you could provide a pull request for this. Is this feasible for you?

Sure, I'll have a look at it soon. You're talking about this progress_display class, right? http://www.boost.org/doc/libs/1_47_0/boost/progress.hpp

Yes. Maybe it's too simple compared to wget's.
Regarding update able text labels I'm not sure how they are
typically used. So I would also prefer some pull request from
somebody with a common use case.

Well, think of wget's output: 0% [ ] 1.154.567 123K/s ETA 57m 6s | | | | | updateable label progressbar u-label u-label u-label

That looks very useful. Is this difficult to add? Can't one just delete the entire line and replace it with an appropriately updated one? Is this too naive?

Yes it's implemented exactly that way. But I think having it in a library is useful nevertheless. Here's what I have so far: https://gist.github.com/1273678 Some improvements to be done: -Autodetect terminal width -test on windows -use isatty and produce useful output for non-ttys -refactoring, docs
This would be easy to implement on Windows as well, I suppose.

terminals. If not, the only needed function is to reset the cursor to the beginning of the current line.
Jens

-- Johannes Pfau
Oct 09 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 09.10.2011, 12:32 Uhr, schrieb Jens Mueller <jens.k.mueller gmx.de>:

 Johannes Pfau wrote:
 Jens Mueller wrote:
 BTW: you could also use isatty (http://linux.die.net/man/3/isatty) to
 detect if stdout has been redirected and disable color output in that
 case.
 For windows:
 https://forums.embarcadero.com/thread.jspa?threadID=21194
 or
 http://msdn.microsoft.com/de-de/library/f4s0ddew(v=vs.80).aspx

Nice idea. Thanks. Jens

But allow the programmer to force color output anyway. In some cases you redirect to a program that itself supports or passes through escape sequences. "grep --color=always <regex> <file> | less" would be an example of that.
Oct 09 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Marco Leise wrote:
 Am 09.10.2011, 12:32 Uhr, schrieb Jens Mueller <jens.k.mueller gmx.de>:
 
Johannes Pfau wrote:
Jens Mueller wrote:
BTW: you could also use isatty (http://linux.die.net/man/3/isatty) to
detect if stdout has been redirected and disable color output in that
case.
For windows:
https://forums.embarcadero.com/thread.jspa?threadID=21194
or
http://msdn.microsoft.com/de-de/library/f4s0ddew(v=vs.80).aspx

Nice idea. Thanks. Jens

But allow the programmer to force color output anyway. In some cases you redirect to a program that itself supports or passes through escape sequences. "grep --color=always <regex> <file> | less" would be an example of that.

Make sense. Thanks. Jens
Oct 10 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Johannes Pfau wrote:
 Jens Mueller wrote:
Johannes Pfau wrote:
 Jens Mueller wrote:
Johannes Pfau wrote:
 You could use ANSI codes on posix to avoid a dependency on curses:
 http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
 But I think using curses is ok. ncurses is MIT licensed and can be
 used as a dynamic library, so I don't think there are license
 problems.
 
 However, I'd recommend to load ncurses dynamically with
 dlopen/dlsym and fallback to simple text output if the ncurses
 library cannot be loaded.

Using the ANSI codes is fine with me. I assumed they aren't that portable but it seems fine.

I'd still use curses though, as it abstracts some things away. Finding terminal capabilities and similar stuff.
Any help is very appreciated.

Though this module is functionality-wise inferior to something
like ncurses it conveniently allows coloring output for most use
cases.

as you already use these functions: http://linux.die.net/man/3/setupterm it'd be nice to have wget-like progressbars and 'updateable' text labels. Shouldn't be as fancy as full ncurses, for most use cases it's good enough to modify the current line. +Points if it properly handles terminal width and resizing.

I believe progress bars are easy to add. Boost's progress_bar should be fairly easy to port. It'll be nice if you could provide a pull request for this. Is this feasible for you?

Sure, I'll have a look at it soon. You're talking about this progress_display class, right? http://www.boost.org/doc/libs/1_47_0/boost/progress.hpp

Yes. Maybe it's too simple compared to wget's.
Regarding update able text labels I'm not sure how they are
typically used. So I would also prefer some pull request from
somebody with a common use case.

Well, think of wget's output: 0% [ ] 1.154.567 123K/s ETA 57m 6s | | | | | updateable label progressbar u-label u-label u-label

That looks very useful. Is this difficult to add? Can't one just delete the entire line and replace it with an appropriately updated one? Is this too naive?

Yes it's implemented exactly that way. But I think having it in a library is useful nevertheless. Here's what I have so far: https://gist.github.com/1273678

Looks good on first view.
 Some improvements to be done:
 -Autodetect terminal width
 -test on windows
 -use isatty and produce useful output for non-ttys
 -refactoring, docs

Can you create a pull request then? Anyway it would be nice to know if there is enough value to add it to phobos? Is there any chance? Otherwise I will put it in its own library and host it on github. Jens
Oct 10 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Iain S wrote:
 Just to add my 2 cents...
 
 I have been looking for a simple way of altering the Windows terminal
 colour, so I would personally say this is worth including - or at the
 very least converting into a usable header/module/???.
 
 I am very new to D, so I can't figure out how to make use of the code
 posted on github.  Perhaps it's simpler than I think :)

Hopefully it's simpler than you expect it: Execute on the Windows command line: dmd.exe -unittest -run terminal.d Does it work for you? You should get colored output. To see how to use it check the unittests. Jens
Dec 14 2011
prev sibling next sibling parent "Axl" <axl_dot_mattheus_ _gmail_dot_com.com> writes:
When I run:

$ dmd -unittest -m64 /usr/lib/x86_64-linux-gnu/libncurses.a -run 
terminal.d

I get the follwoing output:

terminal.o: In function `_D8terminal12_staticCtor2FZv':
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x27): undefined 
reference to `setupterm'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x81): undefined 
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x12b): undefined 
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x1cc): undefined 
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x26d): undefined 
reference to `tigetstr'
terminal.d:(.text._D8terminal12_staticCtor2FZv+0x30e): undefined 
reference to `tigetstr'
terminal.o:terminal.d:(.text._D8terminal12_staticCtor2FZv+0x3af): 
more undefined references to `tigetstr' follow
terminal.o: In function 
`_D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv':
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8ter
inal5ColorZv+0xb2): 
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8ter
inal5ColorZv+0xc2): 
undefined reference to `tputs'
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8term
nal5ColorZv+0x147): 
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8term
nal5ColorZv+0x157): 
undefined reference to `tputs'
terminal.o: In function 
`_D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv':
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal1
CapabilityZv+0xac): 
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal1
CapabilityZv+0xbc): 
undefined reference to `tputs'
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10
apabilityZv+0x13e): 
undefined reference to `tparm'
terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10
apabilityZv+0x14e): 
undefined reference to `tputs'
collect2: ld returned 1 exit status
--- errorlevel 1

I know it is a linker error, but I cannot fix it. Any ideas?

dmd version is:

DMD64 D Compiler v2.061

linker version is:

GNU ld (GNU Binutils for Ubuntu) 2.22

Distro is Ubuntu Linux 12.04.

Thanks,

Axl
Mar 09 2013
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Axl wrote:
 When I run:
 
 $ dmd -unittest -m64 /usr/lib/x86_64-linux-gnu/libncurses.a -run
 terminal.d
 
 I get the follwoing output:
 
 terminal.o: In function `_D8terminal12_staticCtor2FZv':
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x27): undefined
 reference to `setupterm'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x81): undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x12b): undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x1cc): undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x26d): undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x30e): undefined
 reference to `tigetstr'
 terminal.o:terminal.d:(.text._D8terminal12_staticCtor2FZv+0x3af):
 more undefined references to `tigetstr' follow
 terminal.o: In function
`_D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv':
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0xb2):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0xc2):
 undefined reference to `tputs'
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0x147):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0x157):
 undefined reference to `tputs'
 terminal.o: In function
`_D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv':
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0xac):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0xbc):
 undefined reference to `tputs'
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0x13e):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0x14e):
 undefined reference to `tputs'
 collect2: ld returned 1 exit status
 --- errorlevel 1
 
 I know it is a linker error, but I cannot fix it. Any ideas?

Have you tried linking against libtermcap/libtinfo? Jens
Mar 10 2013
prev sibling parent "Axl" <axl_dot_mattheus_ _gmail_dot_com.com> writes:
On Sunday, 10 March 2013 at 14:38:15 UTC, Jens Mueller wrote:
 Axl wrote:
 When I run:
 
 $ dmd -unittest -m64 /usr/lib/x86_64-linux-gnu/libncurses.a 
 -run
 terminal.d
 
 I get the follwoing output:
 
 terminal.o: In function `_D8terminal12_staticCtor2FZv':
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x27): undefined
 reference to `setupterm'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x81): undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x12b): 
 undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x1cc): 
 undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x26d): 
 undefined
 reference to `tigetstr'
 terminal.d:(.text._D8terminal12_staticCtor2FZv+0x30e): 
 undefined
 reference to `tigetstr'
 terminal.o:terminal.d:(.text._D8terminal12_staticCtor2FZv+0x3af):
 more undefined references to `tigetstr' follow
 terminal.o: In function 
 `_D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv':
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0xb2):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0xc2):
 undefined reference to `tputs'
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0x147):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal36__T13setCapabilityTE8terminal5ColorZ13setCapabilityMFxE8terminal10CapabilityxE8terminal5ColorZv+0x157):
 undefined reference to `tputs'
 terminal.o: In function 
 `_D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv':
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0xac):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0xbc):
 undefined reference to `tputs'
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0x13e):
 undefined reference to `tparm'
 terminal.d:(.text._D8terminal8Terminal19__T13setCapabilityZ13setCapabilityMFxE8terminal10CapabilityZv+0x14e):
 undefined reference to `tputs'
 collect2: ld returned 1 exit status
 --- errorlevel 1
 
 I know it is a linker error, but I cannot fix it. Any ideas?

Have you tried linking against libtermcap/libtinfo? Jens

It works against both those libs. Thanks!
Mar 10 2013