How to read a single character in D language?

Adam Ruppe destructionator at gmail.com
Fri Nov 19 22:21:42 UTC 2021


On Friday, 19 November 2021 at 20:51:09 UTC, BoQsc wrote:
> But the source file overwhelmed me by its size.

Yeah, the getch function in there builds on the rest of the 
events the library offers, so it won't be that useful outside.


The OS functions for getch alone though are actually pretty 
simple:

1) change the terminal to "raw" mode. the default is to buffer 
lines, which means your application doesn't get anything until a 
line is complete. You need to turn that off.

The RealTimeConsoleInput constructor does this in the lib:
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L2487

On Windows, you basically just call `SetConsoleMode`, but since 
the console is a shared resource, you also need to save the old 
mode to set it back later (that's what I do in the destructor of 
the struct).

On Linux, you call `tcsetattr`. The function for mine is here:
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L2620

Again, the terminal is a shared resource (this is actually even 
more true on linux systems!) so it is important to save the old 
one and set it back when you're done. There's a lot of ways this 
can happen so you should handle them all - that's why there's a 
bunch of signal handler blocks there.

Other things the library initialize is if you want echo, mouse 
input, paste events, resize notifications, etc. But if you only 
care about getch you can ignore most that stuff.

2) Read the terminal's event stream. On Windows, you call 
`ReadConsoleInput` and process the struct it sends you for a 
keyevent. See: 
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L3122

On Linux, you call the system `read` function on the stdin stream 
(file number 0). Basic keys will come as a single byte read on 
there. Others get.... extremely complicated.
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L3369

And it goes on for about 400 lines! And it depends on some of 
that other initialization we skipped over before and uses a 
database of terminal quirks found elsewhere in the file.

Windows' API is far, far easier to use.


But the Linux one isn't bad if you only want basic alphanumeric 
and enter keys. You can read those as a single ascii byte off the 
read function, so for that you can do it in just a few lines.

3) Again, remember to set it back how you found it before you 
exit by callling the SetConsoleMode/tcsetattr again before you 
exit.


More information about the Digitalmars-d-learn mailing list