Module for interacting with the user's terminal, including color output, cursor manipulation, and full-featured real-time mouse and keyboard input. Also includes high-level convenience methods, like Terminal.getline, which gives the user a line editor with history, completion, etc. See the examples.



class FileLineGetter

This is a line getter that customizes the tab completion to fill in file names separated by spaces, like a command line thing.

class LineGetter

FIXME: support lines that wrap FIXME: better controls maybe


enum Color

Defines the list of standard colors understood by Terminal.

enum ConsoleInputFlags

When capturing input, what events are you interested in?

enum ConsoleOutputType

Defines how terminal output should be handled.

enum ForceOption

Some methods will try not to send unnecessary commands to the screen. You can override their judgement using a ForceOption parameter, if present

enum ModifierState


void main()

View the source of this!

Mixin templates

mixin template LineGetterConstructors()

Adds default constructors that just forward to the superclass

Static variables

bool hangedUp

similar to interrupted.

bool interrupted

you might periodically check this in a long operation and abort if it is set. Remember it is volatile. It is also sent through the input event loop via RealTimeConsoleInput


struct CharacterEvent
struct EndOfFileEvent

Sent upon receiving end-of-file from stdin.

struct HangupEvent

If the user hangs up (for example, closes the terminal emulator without exiting the app), this is sent. If you receive it, you should generally cleanly exit.

struct InputEvent

RealTimeConsoleInput.nextEvent returns one of these. Check the type, then use the get method to get the more detailed information about the event.

struct KeyboardEvent

The new style of keyboard event

struct MouseEvent


struct NonCharacterKeyEvent
struct PasteEvent


struct RGB

Represents a 24-bit color.

struct RealTimeConsoleInput

Encapsulates the stream of input events received from the terminal input.

struct SizeChangedEvent

When you get this, check terminal.width and terminal.height to see the new size and react accordingly.

struct Terminal

Encapsulates the I/O capabilities of a terminal.

struct UserInterruptionEvent

the user hitting ctrl+c will send this You should drop what you're doing and perhaps exit when this happens.

Detailed Description

The main interface for this module is the Terminal struct, which encapsulates the output functions and line-buffered input of the terminal, and RealTimeConsoleInput, which gives real time input.

Creating an instance of these structs will perform console initialization. When the struct goes out of scope, any changes in console settings will be automatically reverted.

Note: on Posix, it traps SIGINT and translates it into an input event. You should keep your event loop moving and keep an eye open for this to exit cleanly; simply break your event loop upon receiving a UserInterruptionEvent. (Without the signal handler, ctrl+c can leave your terminal in a bizarre state.)

As a user, if you have to forcibly kill your program and the event doesn't work, there's still ctrl+\

On Mac Terminal btw, a lot of hacks are needed and mouse support doesn't work. Most functions basically work now though.

Future Roadmap

  • The CharacterEvent and NonCharacterKeyEvent types will be removed. Instead, use KeyboardEvent on new programs.
  • The ScrollbackBuffer will be expanded to be easier to use to partition your screen. It might even handle input events of some sort. Its API may change.
  • getline I want to be really easy to use both for code and end users. It will need multi-line support eventually.
  • I might add an expandable event loop and base level widget classes. This may be Linux-specific in places and may overlap with similar functionality in simpledisplay.d. If I can pull it off without a third module, I want them to be compatible with each other too so the two modules can be combined easily. (Currently, they are both compatible with my eventloop.d and can be easily combined through it, but that is a third module.)
  • More advanced terminal features as functions, where available, like cursor changing and full-color functions.
  • The module will eventually be renamed to arsd.terminal.
  • More documentation.


  • support everything under the sun. If it isn't default-installed on an OS I or significant number of other people might actually use, and isn't written by me, I don't really care about it. This means the only supported terminals are:
    • xterm (and decently xterm compatible emulators like Konsole)
    • Windows console
    • rxvt (to a lesser extent)
    • Linux console
    • My terminal emulator family of applications

    Anything else is cool if it does work, but I don't want to go out of my way for it.

  • Use other libraries, unless strictly optional. terminal.d is a stand-alone module by default and always will be.
  • Do a full TUI widget set. I might do some basics and lay a little groundwork, but a full TUI is outside the scope of this module (unless I can do it really small.)


Get Line

This example will demonstrate the high-level getline interface.

The user will be able to type a line and navigate around it with cursor keys and even the mouse on some systems, as well as perform editing as they expect (e.g. the backspace and delete keys work normally) until they press enter. Then, the final line will be returned to your program, which the example will simply print back to the user.

1 import arsd.terminal;
3 void main() {
4 	auto terminal = Terminal(ConsoleOutputType.linear);
5 	string line = terminal.getline();
6 	terminal.writeln("You wrote: ", line);
7 }


This example demonstrates color output, using Terminal.color and the output functions like Terminal.writeln.

1 import arsd.terminal;
2 void main() {
3 	auto terminal = Terminal(ConsoleOutputType.linear);
4 	terminal.color(,;
5 	terminal.writeln("Hello world, in green on black!");
6 	terminal.color(Color.DEFAULT, Color.DEFAULT);
7 	terminal.writeln("And back to normal.");
8 }

Single Key

This shows how to get one single character press using the RealTimeConsoleInput structure.

1 import arsd.terminal;
2 void main() {
3 	auto terminal = Terminal(ConsoleOutputType.linear);
4 	auto input = RealTimeConsoleInput(&terminal, ConsoleInputFlags.raw);
6 	terminal.writeln("Press any key to continue...");
7 	auto ch = input.getch();
8 	terminal.writeln("You pressed ", ch);
9 }
Suggestion Box / Bug Report