Curses
- Created at
- 8 August 2025
- Last modified
- 26 October 2025
- Status
- 🌿 sapling
- Tagged
-
Curses is "a terminal control library for Unix-like systems, enabling the construction of text user interface (TUI) applications". In other words: it's a programming library (written in C) that lets you do fancy terminal stuff, and particularly, that lets you take control of your terminal's whole screen to build applications that mimic graphical interfaces.
Curses has "wrapper" libraries in any number of languages - python's is well-documented, but ruby also has a library. And because I'm a sucker for ruby, if I can do it in ruby, I'll do it in ruby (even if the documentation is sparse). The good thing is that there's only so many ways to build a wrapper, so a lot of the documentation that was written for python or C curses, will work perfectly well in ruby.
The "hello world" example
Here's the basic example that every documentation site and tutorial will show you - putting "Hello world" on the screen, waiting for you to hit a key, and dumping you out to the terminal.
require 'curses'
include Curses
begin
init_screen
noecho
crmode
curs_set(0)
string = "Hello world!"
string_y = lines / 2
string_x = (cols - string.length) / 2
stdscr.setpos(string_y, string_x)
stdscr << string
stdscr.refresh
stdscr.getch
ensure
close_screen
end
Let's go through this a line at a time:
require 'curses'
include Curses
Curses is a gem these days - it used to be part of ruby's standard libraries, but it isn't really used that often, so it makes sense to be a gem. We want to access a lot of the basic curses methods right off the bat, so we'll just include Curses straight into the main file.
begin
init_screen
...
ensure
close_screen
end
We set up the curses environment in our terminal with init_screen. The one thing you want to ensure with a curses application, is that it'll dump you back out into the normal terminal once you've finished with it. So we wrap the whole thing in a begin/ensure/end structure to make sure close_screen always gets called.
noecho
crmode
curs_set(0)
These three cryptic commands appear at the top of most curses example apps, and they do three distinct things:
noechoensures characters you type don't get echoed back into the screen.crmodeensures all characters are immediately captured by the program and acted on (rather than waiting until you hit enter to process stuff).curs_set(0)means that you don't see the "cursor" character on the screen. This makes it look more like a GUI application.
With that, we're into the thick of it. No more prepping, let's get doing.
string = "Hello world!"
string_y = lines / 2
string_x = (cols - string.length) / 2
We're going to put this on the screen. We can use Curses.lines to see how many lines (ie rows) are in our window, and Curses.cols to see how many columns we have to play with. Here we're getting the middle of the screen with lines / 2, and working out how much padding to put on either side of our string to keep it centered with (cols - string.length) / 2.
stdscr.setpos(string_y, string_x)
stdscr << string
stdscr.refresh
Now we're outputting things to the screen! When we output, we output to a
External links
Curses (programming library) - Wikipedia
Curses - Rubydoc
Forms library - the linux documentation project
A very good description - with examples - of how to use forms in curses.
Writing programs with NCURSES - Invisible Island
A very thorough guide to using curses (in C).