Thread overview
Reading Standard Input
Jan 23, 2013
Kenneth Sills
Jan 23, 2013
Adam D. Ruppe
Jan 23, 2013
nazriel
Jan 23, 2013
Ali Çehreli
Jan 23, 2013
H. S. Teoh
Jan 23, 2013
Kenneth Sills
Jan 23, 2013
Jesse Phillips
Jan 28, 2013
Kenneth Sills
Jan 28, 2013
Adam D. Ruppe
Jan 28, 2013
H. S. Teoh
January 23, 2013
Hello everyone! I'm pretty new to the D world, and just started
playing around with it. To start off with the language, I was
going to write a little game (as I usually do). I wanted to use
pure D (no ncurses) and not have to import any libraries (no
anything else) for the project. So I set out to make it a CLI
game.

I've written myself a nice little library for formatting the
output and doing all that lovely stuff with the terminal -
however I'm having trouble with input. You see, I need
nonblocking (which I've set up) input that can read character by
character (so when the user presses r, it immediately takes it
in, not waiting for an enter) and I need to be able to see things
like arrow keys, shift keys, and control keys.

I've looked around extensively, but I have yet to find anything
on how to set up character by character input NOR have I found
anything on receiving those special characters in D. I know it's
quite possible in C, but again, half the point of this project is
being pure D.So how would I go about implementing this?

Thank you in advance!
January 23, 2013
The two files in here are both independent, and either one should help out:

https://github.com/robik/ConsoleD/
January 23, 2013
On Wednesday, 23 January 2013 at 17:59:04 UTC, Kenneth Sills wrote:
> Hello everyone! I'm pretty new to the D world, and just started
> playing around with it. To start off with the language, I was
> going to write a little game (as I usually do). I wanted to use
> pure D (no ncurses) and not have to import any libraries (no
> anything else) for the project. So I set out to make it a CLI
> game.
>
> I've written myself a nice little library for formatting the
> output and doing all that lovely stuff with the terminal -
> however I'm having trouble with input. You see, I need
> nonblocking (which I've set up) input that can read character by
> character (so when the user presses r, it immediately takes it
> in, not waiting for an enter) and I need to be able to see things
> like arrow keys, shift keys, and control keys.
>
> I've looked around extensively, but I have yet to find anything
> on how to set up character by character input NOR have I found
> anything on receiving those special characters in D. I know it's
> quite possible in C, but again, half the point of this project is
> being pure D.So how would I go about implementing this?
>
> Thank you in advance!

Adam Ruppe is working on very nice terminal handler. Maybe you can look into this: https://github.com/robik/ConsoleD/blob/master/terminal.d

It's rather complete solution.

Myself I was using this simple function, not sure if it will be usable for you:
    char ReadKey()
    {
        version(Posix)
        {
            int getch()
            {
                int ch;
                termios oldt;
                termios newt;

                tcgetattr(0, &oldt);
                newt = oldt;
                newt.c_lflag &= ~(ICANON | ECHO);
                tcsetattr(0, TCSANOW, &newt);
                ch = getchar();
                tcsetattr(0, TCSANOW, &oldt);
                return ch;
            }
        }
        else version(Windows)
        {
            alias _getch getch;
        }

        return cast(char) getch();
    }
January 23, 2013
On 01/23/2013 09:59 AM, Kenneth Sills wrote:

> I'm having trouble with input. You see, I need
> nonblocking (which I've set up) input that can read character by
> character (so when the user presses r, it immediately takes it
> in, not waiting for an enter) and I need to be able to see things
> like arrow keys, shift keys, and control keys.

Not possible with standard input.

Standard input is a character stream that is bound to the program by the environment that has started the program. The program has been written in the D language (or C, etc.) but it has no control on how that character stream is filled in by the environment.

There isn't even the concept of a keyboard nor a monitor.

> I know it's quite possible in C

It is exactly the same story in C. :) You must have been relying on special libraries.

> but again, half the point of this project is
> being pure D.So how would I go about implementing this?

You must use a library like ncurses, which is aware of the keyboard (or write one yourself. (I don't know how. :))).

I had captured some of these ideas here:

  http://ddili.org/ders/d.en/io.html

  http://ddili.org/ders/d.en/stream_redirect.html

Ali

January 23, 2013
On Wed, Jan 23, 2013 at 06:59:03PM +0100, Kenneth Sills wrote:
> Hello everyone! I'm pretty new to the D world, and just started playing around with it. To start off with the language, I was going to write a little game (as I usually do). I wanted to use pure D (no ncurses) and not have to import any libraries (no anything else) for the project. So I set out to make it a CLI game.
> 
> I've written myself a nice little library for formatting the output and doing all that lovely stuff with the terminal - however I'm having trouble with input. You see, I need nonblocking (which I've set up) input that can read character by character (so when the user presses r, it immediately takes it in, not waiting for an enter) and I need to be able to see things like arrow keys, shift keys, and control keys.
> 
> I've looked around extensively, but I have yet to find anything on how to set up character by character input NOR have I found anything on receiving those special characters in D. I know it's quite possible in C, but again, half the point of this project is being pure D.So how would I go about implementing this?
[...]

Short answer:

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

Currently it's still in a rough development state, but it's already quite usable, and has a nice API to boot. Take a look at the demo main() function at the end of the file for an example of how to use it.

Eventually we hope to get this added to the standard library.

(As you can tell if you look at the code, writing a cross-platform console manipulation module is not as easy as it may sound at first!)


Long answer:

So you wanna get your hands dirty and do things directly? Well, then you should know that every OS has a different interface for manipulating the console, so first you have to decide which OS you're going to be working with.

If you're using Windows, take a look at core.sys.windows.windows, which provide D wrappers around Windows API functions, which should let you access the various console functions that you need.

If you're using Linux/Unix/*nix/Posix, then you need to understand that terminal functions are sprinkled throughout different places. First, there are the ANSI escape sequences:

	http://www.termsys.demon.co.uk/vtansi.htm

Which should work with *most* modern terminals.  Then each terminal type also has their own escape sequences, which are usually a superset of these (but there are terminals that require their own peculiar escape sequences). How do deal with this depends on how far you wanna go. If you want to code to just a single terminal, then you can just look up the documentation for it. If you want it to be generic, then you'll have to learn about termcap and terminfo:

	man 5 termcap
	man 5 terminfo

But these only deal with the output part of the terminal. What of terminal input (which is where per-character input is configured)? For this, you'll have to use the OS's termios functions. See:

	man 3 termios

Which, I'll admit, is a labyrinth of mostly-obscure settings, the effect of which isn't at all obvious to someone who isn't acquianted with how Unix terminals work. So, for a quick primer on how to get started, you might want to read this:

	http://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw

and then look up the termios manpage to figure out how to actually get these settings in place in code.

(Yes, now you can sit back in awe about how complicated something
apparently so simple can be.)

Note that most of this stuff is not directly related to D, because they are OS-specific functions (and thus export C interfaces -- but have no fear, D can call C functions directly, and also core.sys.posix and core.sys.windows already provide convenient D wrappers for most of these functions).

Ideally, Phobos should already have a module for doing all of this complicated stuff for you, but we're not quite there yet. For now, terminal.d is the best candidate for such a module, so you're probably best off using it instead of rolling your own. ;-)


T

-- 
Heuristics are bug-ridden by definition. If they didn't have bugs, they'd be algorithms.
January 23, 2013
Thank you very much everyone! I think I'm all set! It was an academic project to begin with, so learning about termios and getting all that in my brain for later use is probably the best idea! Although I'll keep in mind the consoleD project, as I was looking for something just like that before I started my own endeavor (which now that I've begun, refuse to waste), but couldn't find anything! It's a bit hard looking for D stuff, even searches such as "Dlang" or "D Language" don't yield terribly useful results.
January 23, 2013
On Wednesday, 23 January 2013 at 18:31:31 UTC, Kenneth Sills wrote:
> It's a bit hard looking for D stuff, even searches such as "Dlang" or "D Language" don't yield terribly useful results.

Mostly because the material isn't there. As more content about D exist the easier it is. Just most of the time people expect it to exist somewhere (and they are using the same language as the one writing about it).
January 28, 2013
So if anyone cared to know, I've been working on a D library for terminal use. Linux only, xterm based (fits my needs). I've got the hard part (non-blocking and non ASCII input) done. I found that consoleD is more about text, and less about treating the console like an I/O. So if you want a closer example of what my lib will be like - check out termbox-go by NSF. And it'll have an option library with helpful things for text or graphics. Anyways, I'll throw it up on Bitbucket or Github sooner or later, thanks for the help guys.
January 28, 2013
On Monday, 28 January 2013 at 13:39:22 UTC, Kenneth Sills wrote:
> I found that consoleD is more about text, and less about treating the console like an I/O.

I think that's a failure of documentation... taking a quick look at termbox-go, the terminal.d we have in there seems to fill the same bill.

(Documentation is something I don't bother too much with. I write libs for myself, so "works for me" and "I know how to do it" is good enough for me. Oh well.)

> Anyways, I'll throw it up on Bitbucket or Github sooner or later, thanks for the help guys.

Cool, post it to the announce group when you do, it will be cool to take a look at it.
January 28, 2013
On Mon, Jan 28, 2013 at 02:49:59PM +0100, Adam D. Ruppe wrote:
> On Monday, 28 January 2013 at 13:39:22 UTC, Kenneth Sills wrote:
> >I found that consoleD is more about text, and less about treating the console like an I/O.
> 
> I think that's a failure of documentation... taking a quick look at termbox-go, the terminal.d we have in there seems to fill the same bill.
[...]

Being a user of terminal.d, I have to say that it's very much about treating the console as I/O. The documentation could do with a face-lift, though. I did add some stuff to it, but probably not quite enough yet.

But in any case, having competing libraries isn't necessarily a bad thing. Competition forces you to improve the code in more ways than you would have. :-P


T

-- 
Amateurs built the Ark; professionals built the Titanic.