Add color, style, advanced cursor movements, fancy menus, and more to your C++ terminal app! This fully cross-platform library includes a variety of functions and classes to make common challenges easier.
You can download this library into your project with git by using git submodule add https://github.com/wheelercj/ynot
and then adding #include "../ynot/ynot/ynot.h"
(and optionally using namespace ynot;
) to the files you want to use this library in. Get future updates with git submodule update --remote
. The library's version number is saved in ynot.h so that you can check whether you have the latest version in the future.
Alternatively, you can manually download a zip file or a tar.gz file and go through a similar setup process.
If you're using Visual Studio, each time you download or update the library you will also need to:
- add any of the library's files you haven't added yet to your project's solution explorer (here's a guide)
- rescan the solution by right-clicking on your project in the solution explorer and choosing "Rescan Solution"
See the header files for the lists of functions and their descriptions. There are many examples of how you can use this library below, in the test files, in terminal paint, and in the matrix. C++17 or newer is required; in Visual Studio, you can choose the version of C++ with project > Properties > C/C++ > Language > C++ Language Standard.
The ynot library's print
function (and other functions that print) allows you to print any emoji or other Unicode symbols to a terminal. On Windows, printing emoji with C++ is normally very complicated. With this print function, it couldn't be more simple.
ynot::print("🔥🐊");
ynot::print("\n I can print anything 😎🤖");
To print emoji, the file must be saved with the UTF-8 encoding (without signature/BOM) and your code must run in a modern terminal (such as Windows Terminal; see how to run your C++ app in Windows Terminal). On Windows, you must use the emoji or Unicode symbol itself in your code rather than a Unicode code point (Unicode code points only work in wstring
s).
Here is the get_key
function which can instantly detect key presses without an enter key press:
string key = "";
while (key != "escape")
{
key = ynot::get_key();
ynot::print("\r \r You pressed " + key);
}
This library also has many string manipulation functions including wrap
, split
, join
, strip
, center
, indent
, dedent
, and more. See their signatures in str.h.
Below is an example of ynot's Menu
class, which makes it easy to create centered menus controlled with the arrow and enter keys.
ynot::Menu menu("sample menu", { "create", "list", "edit", "delete", "help", "settings", "exit" });
string choice = menu.run();
ynot::print("\nYou chose " + choice);
Here's an example of getline_ac
which gets a line of input while giving autocomplete suggestions (not autocorrect) and has optional built-in input validation:
ynot::print(" Enter a month: ");
string month = ynot::getline_ac({ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" });
ynot::print("\n You chose " + month);
Below is another example. With ynot's Paginator
class, you can cleanly present long pieces of text in a terminal. The dedent
function removes indentation from a multiline string.
string article_title = "3.6 Git Branching - Rebasing";
string article_body = ynot::dedent(R"(
Article body here.
Indent with tabs or spaces, not both.)");
string line_prefix = "\n ";
ynot::Paginator paginator(article_title, article_body, line_prefix);
paginator.run();
The sample text is from git-scm.com.
If your app uses multiple threads that call functions in terminal.h, you can prevent race conditions by combining strings before printing.
Race condition example:
string message;
int x, y, green;
...
ynot::set_cursor_coords(x, y); // set_cursor_coords prints an ANSI code
ynot::print_rgb(0, green, 0, message);
Each character is supposed to get steadily darker after it appears on screen, but sometimes the print_rgb
function in one thread ends up being called between the set_cursor_coords
and print_rgb
calls in another thread.
Prevent this output scrambling by combining all strings into one before printing. The terminal.h functions that start with ret_
return strings instead of printing them so that you can wait to print until after combining strings.
string coord_str = ynot::ret_set_cursor_coords(x, y);
ynot::print_rgb(0, green, 0, coord_str + message);
You can see all of the code for what's shown in the gif here.