Reading Standard Input

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Jan 23 10:16:52 PST 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.


More information about the Digitalmars-d-learn mailing list