October 28, 2012
Adam D. Ruppe wrote:
> Here we go, some more basic functions:
> 
> http://arsdnet.net/dcode/terminal.d
> 
> The unix stuff is more implemented than the windows.
> 
> 
> Let's walk through main and I'll discuss why I'm doing things the way I am. I'm throwing this out just to show one possible way this can be done and to explain why I like this way. Feel free to take some or all of my code if you want.
> 
> 
> 	auto terminal = Terminal(ConsoleOutputType.cellular);
> 
> First, the terminal is a separate type, a struct, rather than just magic functions. This way it can use the struct destructor to reset things to normal.
> 
> The argument here is either linear or cellular - do you want line based output or do you want to control the whole screen as a grid of cells?
> 
> If you use cellular, it will use the alternative screen buffer on unix terminals. IIRC Windows works basically the same way. This is what we want for a TUI app.
> 
> The escape sequences to make this happen is based on the envrionment variable TERMCAP, which is set by gnu screen, xterm, and most other emulators.
> 
> It is *not* set by the linux console or rxvt on my box, so this isn't perfect yet, but it is a start. If it can't find a capability in there, it simply ignores those method calls, meaning it should be backward compatible (once fully implemented - I haven't done this on title yet.)

I like that you code won't need additional libraries. But how do you plan to handle the linux console or rxvt if setting TERMCAP is not portable?

> 	terminal.setTitle("Basic I/O");
> 
> All changes are done with methods. This is how Windows does it and is cleaner anyway.
> 
> 	auto input = terminal.captureInput(ConsoleInputFlags.raw);
> 
> To get real time input, you use a special method which returns an input struct. Which could probably be an input range actually but isn't now.
> 
> Anyway the reason is you have to change the terminal mode in linux to get real time input. Otherwise it will be line buffered. Again, a struct lets us reset the mode automatically in the destructor. The flags let you control automatic echo.
> 
> 	terminal.color(Color.green | Bright, Color.black);
> 
> I insist that you set foreground and background colors together. This ensure you get readable text.
> 
> The colors are defined with a platform independent color enum and you can flag in bright to get brighter colors.
> 
> 
> BTW I'm thinking about calling it LowContrast instead of bright... then your color definitions can always be the same regardless of bg, and it automatically flips the bright bit if needed. But since I'm forcing you to specify background here too it isn't a big deal with now.
> 
> 
> 	int centerX = terminal.width / 2;
> 	int centerY = terminal.height / 2;
> 
> I prefer width and height to rows and columns. I think more in terms of gui here.
> 
> 	while(true) {
> 		if(input.kbhit()) {
> 
> Since we have real time capture, can poll for new input instead of blocking.
> 
> 			auto c = input.getch();
> 
> Get our character... (BTW this function still needs a lot of work)
> 
> 			if(c == 'q' || c == 'Q')
> 				break;
> 			terminal.moveTo(centerX, centerY);
> 			terminal.writef("%c", c);
> 			terminal.flush();
> 
> And output the stuff, centering the text. All output methods are attached to the terminal to ensure the proper api stuff is handled.
> 
> 		usleep(10000);
> 
> This is just there so we don't eat too much cpu waiting on input.

This looks well thought-out. I'm unsure about TERMCAP. Currently I'm using tinfo instead. Probably I'm going will all your ideas but still using tinfo.

Jens
October 28, 2012
Tobias Pankrath wrote:
> On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
> >On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens Mueller wrote:
> >>> This is probably interesting for Phobos. But I'm not the one
> >to make a
> >>> decision. The core Phobos developers should decide. Hopefully somebody is reading this.
> >>
> >> Off the top of my head something that is specific for only
> >certain systems
> >> (Unixen in this case) is decidedly of less Phobos interest.
> >We could,
> >> nevertheless, put such functionality in system-specific
> >modules.
> >
> >A module that only sets the console color is a little too light to be a phobos entry.
> >
> >A more comprehensive module that included:
> >
> >1. getting mouse input
> >2. getting size of the console
> >3. moving the cursor around
> >4. drawing boxes in the console window
> >5. setting the contents of the title bar
> >6. supporting cut/paste
> >7. getting no-echo raw input
> >8. setting the size of the cursor
> >
> >would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).
> 
> This would look like a full blown TUI-Toolkit and we should model
> the API
> after successfull GUI-Frameworks like Qt, i.e. provide a event
> loop, use
> a Signal/Slot mechanism etc.
> 
> That would be a real improvement over nCurses. What do you think?

If you can add an event loop on top that would be great. What do I need to make sure that you can add the event handling on top?

Jens
October 28, 2012
Adam D. Ruppe wrote:
> It now can translate most PC keyboard input sequences into char or non-char key events, including requesting UTF-8 input for chars:
> 
> http://arsdnet.net/dcode/terminal.d
> 
> 
> We could just about start writing real apps with this now. Biggest problem left is it doesn't actually scan the termcap file - it only looks for a TERMCAP environment variable. This means many keys are ignored on some terminals.
> 
> Should be a fairly easy fix I just haven't gotten around to it yet.

How?

> Then finish the Windows support side of it and we have a fairly functional, totally standalone, little text library here.
> 
> 
> 
> BTW this is actually kinda off topic for ColorD since I'm going more fancy - if you just want to add color to stdout, my code has probably gone too far.

It is. But it is going in the right direction.

Jens
October 28, 2012
> If you can add an event loop on top that would be great. What do I need
> to make sure that you can add the event handling on top?
>
> Jens

I don't think that this needs any special consideration. If you look at Adams code samples in this thread, he's building his own event loop on input.getch.

That's fine. I just think, that you shouldn't have to write your own and having a standard one and common mechanism to dispatch events to some kind of widgets, will make sharing those widgets so much easier.


October 28, 2012
On Sunday, 28 October 2012 at 10:44:58 UTC, Jens Mueller wrote:
> How?

The file /etc/termcap has the data too so opening it and quickly parsing should give the same result as the environment variable.

It looks like this:

vg|vt-generic|Generic VT entries:\
        :bs:mi:ms:pt:xn:xo:it#8:\
<snip>
# Slackware 3.1 linux termcap entry (Sat Apr 27 23:03:58 CDT 1996):
lx|linux|console|con80x25|LINUX System Console:\
        :do=^J:co#80:li#25:cl=\E[H\E[J:sf=\ED:sb=\EM:\
<snip>

and so on. The $TERM variable is used as a key into one of those names, then the rest of the data is on the following lines.

The termcap entries can also inherit from other entries, but again it is just a key lookup into the list.



October 28, 2012
Adam D. Ruppe wrote:
> On Sunday, 28 October 2012 at 10:44:58 UTC, Jens Mueller wrote:
> >How?
> 
> The file /etc/termcap has the data too so opening it and quickly parsing should give the same result as the environment variable.

I'm running Debian. It doesn't have such a file.

> It looks like this:
> 
> vg|vt-generic|Generic VT entries:\
>         :bs:mi:ms:pt:xn:xo:it#8:\
> <snip>
> # Slackware 3.1 linux termcap entry (Sat Apr 27 23:03:58 CDT 1996):
> lx|linux|console|con80x25|LINUX System Console:\
>         :do=^J:co#80:li#25:cl=\E[H\E[J:sf=\ED:sb=\EM:\
> <snip>
> 
> and so on. The $TERM variable is used as a key into one of those names, then the rest of the data is on the following lines.
> 
> The termcap entries can also inherit from other entries, but again it is just a key lookup into the list.

Jens
October 28, 2012
On Sunday, 28 October 2012 at 14:09:09 UTC, Jens Mueller wrote:
> I'm running Debian. It doesn't have such a file.

They must just depend on terminfo. That's more complicated to read though - it isn't a plain text file anymore, so doing it without a library is going to be more of a pain.

I think I'll also copy/paste a few of the entries from my system into the code to use as generic fallback if nothing else is available (they aren't long).
October 28, 2012
On Sun, Oct 28, 2012 at 03:15:46PM +0100, Adam D. Ruppe wrote:
> On Sunday, 28 October 2012 at 14:09:09 UTC, Jens Mueller wrote:
> >I'm running Debian. It doesn't have such a file.
> 
> They must just depend on terminfo. That's more complicated to read though - it isn't a plain text file anymore, so doing it without a library is going to be more of a pain.

Why not use a library? Terminfo is designed precisely for this.


> I think I'll also copy/paste a few of the entries from my system into the code to use as generic fallback if nothing else is available (they aren't long).


T

-- 
If it's green, it's biology, If it stinks, it's chemistry, If it has numbers it's math, If it doesn't work, it's technology.
October 28, 2012
On Sunday, 28 October 2012 at 14:53:31 UTC, H. S. Teoh wrote:
> Why not use a library? Terminfo is designed precisely for this.

Sometimes linking in external libraries in Phobos can be a problem for licensing or Just Works portability.

idk about terminfo, I haven't really looked at it. (tbh I just don't like using libraries in general either :-p )
October 28, 2012
Robik let me add my code to his repository with the plan to merge the two files later, but for now I just pushed my file up there.

https://github.com/robik/ConsoleD/blob/master/terminal.d

It now has /etc/termcap support, a builtin termcap to work in a pinch if the system doesn't have one, and most of the stuff needed for Windows support (the events aren't translated perfectly, but basic programs already work).

I'm done with it for today, but the idea is to eventually merge our two files completely so we have both low level event, etc., and high level drawing in the one module.