## File: README.md
# Notcurses: blingful TUIs and character graphics
**What it is**: a library facilitating complex TUIs on modern terminal
emulators, supporting vivid colors, multimedia, threads, and Unicode to the
maximum degree possible. [Things](https://www.youtube.com/watch?v=dcjkezf1ARY) can be done with
Notcurses that simply can't be done with NCURSES. It is furthermore
fast as shit. **What it is not**: a source-compatible X/Open Curses implementation, nor a
replacement for NCURSES on existing systems.
for more information, see [dankwiki](https://nick-black.com/dankwiki/index.php/Notcurses)
and the [man pages](https://notcurses.com). in addition, there is
[Doxygen](https://notcurses.com/html/) output.
i wrote a coherent [guidebook](https://nick-black.com/htp-notcurses.pdf), which is available for
free download (or [paperback purchase](https://amazon.com/dp/B086PNVNC9)).
i've not yet added many documented examples, but [src/poc/](https://github.com/dankamongmen/notcurses/tree/master/src/poc)
and [src/pocpp/](https://github.com/dankamongmen/notcurses/tree/master/src/pocpp)
contain many small C and C++ programs respectively. `notcurses-demo` covers
most of the functionality of Notcurses.
**If you're running Notcurses applications in a Docker, please consult
"[Environment notes](#environment-notes)" below.**
[](https://github.com/dankamongmen/notcurses/actions/workflows/ubuntu_test.yml?query=branch%3Amaster)
[](https://github.com/dankamongmen/notcurses/actions/workflows/macos_test.yml?query=branch%3Amaster)
[](https://github.com/dankamongmen/notcurses/actions/workflows/windows_test.yml?query=branch%3Amaster)
[](https://pypi.org/project/notcurses)
[](https://crates.io/crates/libnotcurses-sys)
[](https://app.element.io/#/room/#notcursesdev:matrix.org)
[](https://github.com/sponsors/dankamongmen)
## Introduction
Notcurses abandons the X/Open Curses API bundled as part of the Single UNIX
Specification. For some necessary background, consult Thomas E. Dickey's
superb and authoritative [NCURSES FAQ](https://invisible-island.net/ncurses/ncurses.faq.html#xterm_16MegaColors).
As such, Notcurses is not a drop-in Curses replacement.
Wherever possible, Notcurses makes use of the Terminfo library shipped with
NCURSES, benefiting greatly from its portability and thoroughness.
Notcurses opens up advanced functionality for the interactive user on
workstations, phones, laptops, and tablets, possibly at the expense of e.g.
some industrial and retail terminals. Fundamentally, Curses assumes the minimum
and allows you (with effort) to step up, whereas Notcurses assumes the maximum
and steps down (by itself) when necessary. The latter approach probably breaks
on some older hardware, but the former approach results in new software looking
like old hardware.
Why use this non-standard library?
* Thread safety, and efficient use in parallel programs, has been a design
consideration from the beginning.
* A more orderly surface than that codified by X/Open: Exported identifiers are
prefixed to avoid common namespace collisions. Where reasonable,
`static inline` header-only code is used. This facilitates compiler
optimizations, and reduces loader time. Notcurses can be built without its
multimedia functionality, requiring a significantly lesser set of dependencies.
* All APIs natively support the Universal Character Set (Unicode). The `nccell`
API is based around Unicode's [Extended Grapheme Cluster](https://unicode.org/reports/tr29/) concept.
* Visual features including images, fonts, video, high-contrast text, sprites,
and transparent regions. All APIs natively support 24-bit color, quantized
down as necessary for the terminal.
* Portable support for bitmapped graphics, using Sixel, Kitty,
and even the Linux framebuffer console.
* Support for unambiguous [keyboard protocols](https://sw.kovidgoyal.net/kitty/keyboard-protocol/).
* "TUI mode" facilitates high-performance, non-scrolling, full-screen
applications. "CLI mode" supports scrolling output for shell utilities,
but with the full power of Notcurses.
* It's Apache2-licensed in its entirety, as opposed to the
[drama in several acts](https://invisible-island.net/ncurses/ncurses-license.html)
that is the NCURSES license (the latter is [summarized](https://invisible-island.net/ncurses/ncurses-license.html#issues_freer)
as "a restatement of MIT-X11").
Much of the above can be had with NCURSES, but they're not what NCURSES was
*designed* for. On the other hand, if you're targeting industrial or critical
applications, or wish to benefit from time-tested reliability and
portability, you should by all means use that fine library.
## Requirements
Minimum versions generally indicate the oldest version I've tested with; it
may well be possible to use still older versions. Let me know of any successes!
* (build) CMake 3.21.0+ and a C17 compiler
* (OPTIONAL) (OpenImageIO, testing, C++ bindings): A C++17 compiler
* (build+runtime) From [NCURSES](https://invisible-island.net/ncurses/announce.html): terminfo 6.1+
* (build+runtime) GNU [libunistring](https://www.gnu.org/software/libunistring/) 0.9.10+
* (OPTIONAL) (build+runtime) [libgpm](https://www.nico.schottelius.org/software/gpm/) 1.20+
* (OPTIONAL) (build+runtime) From QR-Code-generator: [libqrcodegen](https://github.com/nayuki/QR-Code-generator) 1.5.0+
* (OPTIONAL) (build+runtime) From [FFmpeg](https://www.ffmpeg.org/): libswscale 5.0+, libavformat 57.0+, libavutil 56.0+, libavdevice 57.0+
* (OPTIONAL) (build+runtime) [OpenImageIO](https://github.com/OpenImageIO/oiio) 2.15.0+, requires C++
* (OPTIONAL) (testing) [Doctest](https://github.com/onqtam/doctest) 2.3.5+
* (OPTIONAL) (documentation) [pandoc](https://pandoc.org/index.html) 1.19.2+
* (OPTIONAL) (python bindings): Python 3.7+, [CFFI](https://pypi.org/project/cffi/) 1.13.2+, [pypandoc](https://pypi.org/project/pypandoc/) 1.5+
* (runtime) Linux 2.6+, FreeBSD 11+, DragonFly BSD 5.9+, Windows 10 v1093+, or macOS 11.4+
More information on building and installation is available in [INSTALL.md](INSTALL.md).
### Wrappers
If you wish to use a language other than C to work with Notcurses, numerous
wrappers are available. Several are included in this repository, while
others are external.
| Language | Lead(s) | Repository |
| -------- | ----------------------------- | ---------- |
| Ada | Jeremy Grosser | [JeremyGrosser/notcursesada](https://github.com/JeremyGrosser/notcursesada) |
| C++ | Marek Habersack, nick black | internal |
| Dart | Nelson Fernandez | [kascote/dart_notcurses](https://github.com/kascote/dart_notcurses) |
| Julia | Dheepak Krishnamurthy | [kdheepak/Notcurses.jl](https://github.com/kdheepak/Notcurses.jl) |
| Nim | Michael S. Bradley, Jr. | [michaelsbradleyjr/nim-notcurses](https://github.com/michaelsbradleyjr/nim-notcurses) |
| Python | nick black | internal |
| Python | igo95862 | internal |
| Rust | José Luis Cruz | [dankamongmen/libnotcurses-sys](https://github.com/dankamongmen/libnotcurses-sys) |
| Zig | Jakub Dundalek | [dundalek/notcurses-zig-example](https://github.com/dundalek/notcurses-zig-example) |
| Raku | Matt Doughty | [m-doughty/Notcurses-Native](https://github.com/m-doughty/Notcurses-Native) |
## Included tools
Nine executables are installed as part of Notcurses:
* `ncls`: an `ls` that displays multimedia in the terminal
* `ncneofetch`: a [neofetch](https://github.com/dylanaraps/neofetch) ripoff
* `ncplayer`: renders visual media (images/videos)
* `nctetris`: a tetris clone
* `notcurses-demo`: some demonstration code
* `notcurses-info`: detect and print terminal capabilities/diagnostics
* `notcurses-input`: decode and print keypresses
* `notcurses-tester`: unit testing
* `tfman`: a swank manual browser
To run `notcurses-demo` from a checkout, provide the `data` directory via
the `-p` argument. Demos requiring data files will otherwise abort. The base
delay used in `notcurses-demo` can be changed with `-d`, accepting a
floating-point multiplier. Values less than 1 will speed up the demo, while
values greater than 1 will slow it down.
`notcurses-tester` likewise requires that `data`, populated with the necessary
data files, be specified with `-p`. It can be run by itself, or via `make test`.
## Documentation
With `-DUSE_PANDOC=on` (the default), a full set of man pages and XHTML
will be built from `doc/man`. The following Markdown documentation is included
directly:
* Per-release [News](NEWS.md) for packagers, developers, and users.
* The `TERM` environment variable and [various terminal emulators](TERMINALS.md).
* Notes on [contributing](CONTRIBUTING.md) and [hacking](doc/HACKING.md).
* There's a semi-complete [reference guide](USAGE.md).
* A list of [other TUI libraries](doc/OTHERS.md).
* Abbreviated [history](doc/HISTORY.md) and thanks.
* [Differences from](doc/CURSES.md) Curses and adapting Curses programs.
If you (understandably) want to avoid the large Pandoc stack, but still enjoy
manual pages, I publish a tarball with generated man/XHTML along with
each release. Download it, and install the contents as you deem fit.
## Environment notes
* If your `TERM` variable is wrong, or that terminfo definition is out-of-date,
you're going to have a very bad time. Use *only* `TERM` values appropriate
for your terminal. If this variable is undefined, or Notcurses can't load the
specified Terminfo entry, it will refuse to start, and you will
[not be going to space today](https://xkcd.com/1133/).
* Notcurses queries the terminal on startup, enabling some advanced features
based on the determined terminal (and even version). Basic capabilities,
however, are taken from Terminfo. So if you have, say, Kitty, but
`TERM=vt100`, you're going to be able to draw RGBA bitmap graphics (despite
such things being but a dream for a VT100), but *unable* to use the alternate
screen (despite it being supported by every Kitty version). So `TERM` and an
up-to-date Terminfo database remain important.
* Ensure your `LANG` environment variable is set to a UTF8-encoded locale, and
that this locale has been generated. This usually means
`"[language]_[Countrycode].UTF-8"`, i.e. `en_US.UTF-8`. The first part
(`en_US`) ought exist as a directory or symlink in `/usr/share/locales`.
This usually requires editing `/etc/locale.gen` and running `locale-gen`.
On Debian systems, this can be accomplished with `dpkg-reconfigure locales`,
and enabling the desired locale. The default locale is stored somewhere like
`/etc/default/locale`.
* If your terminal has an option about default interpretation of "ambiguous-width
characters" (this is actually a technical term from Unicode), ensure it is
set to **Wide**, not narrow (if that doesn't work, ensure it is set to
**Narrow**, heh).
* If your terminal supports 3x8bit RGB color via `setaf` and `setbf` (most
modern terminals), but exports neither the `RGB` nor `Tc` terminfo capability,
you can export the `COLORTERM` environment variable as `truecolor` or `24bit`.
Note that some terminals accept a 24-bit specification, but map it down to
fewer colors. RGB is unconditionally enabled whenever
[most modern terminals](TERMINALS.md) are identified.
### Fonts
Glyph width, and indeed whether a glyph can be displayed at all, is dependent
in part on the font configuration. Ideally, your font configuration has a
glyph for every Unicode EGC, and each glyph's width matches up with the POSIX
function's `wcswidth()` result for the EGC. If this is not the case, you'll
likely get blanks or � (U+FFFD, REPLACEMENT CHARACTER) for missing characters,
and subsequent characters on the line may be misplaced.
It is worth knowing that several terminals draw the block characters directly,
rather than loading them from a font. This is generally desirable. Quadrants,
sextants, and octants are not the place to demonstrate your design virtuosity.
To inspect your environment's rendering of drawing characters, run
`notcurses-info`. The desired output ought look something like this:
## FAQs
If things break or seem otherwise lackluster, **please** consult the
[Environment Notes](#environment-notes) section! You **need** correct
`TERM` and `LANG` definitions, and might want `COLORTERM`.
Can I use Notcurses in my closed-source program?
Notcurses is licensed under [Apache2](https://www.apache.org/licenses/LICENSE-2.0),
a demonstration that I have transcended your petty world of material goods,
fiat currencies, and closed sources. Implement Microsoft Bob in it. Charge
rubes for it. Put it in your ballistic missiles so that you have a nice LED
display of said missile's speed and projected yield; right before impact,
scroll "FUCK YOU" in all the world's languages, and close it out with a smart
palette fade. Carve the compiled objects onto bricks and mail them to Richard
Stallman, taunting him through a bullhorn as you do so.
Can I write a CLI program (scrolling, fits in with the shell, etc.)
with Notcurses?
Yes! Use the `NCOPTION_CLI_MODE` flag (an alias for several
real flags; see [`notcurses_init(1)`](https://notcurses.com/notcurses_init.3.html)
for more information). You still must explicitly render.
Can I have Notcurses without this huge multimedia stack?
Again yes! Build with `-DUSE_MULTIMEDIA=none`.
Can I build this individual Notcurses program without aforementioned
multimedia stack?
Almost unbelievably, yes! Use `notcurses_core_init()` or
`ncdirect_core_init()` in place of `notcurses_init()`/
`ncdirect_init()`, and link with `-lnotcurses-core`.
Your application will likely start a few milliseconds faster;
more importantly, it will link against minimal Notcurses installations.
We're paying by the electron, and have no C++ compiler. Can we still
enjoy Notcurses goodness?
Some of it! You won't be able to build several executables, nor the NCPP C++
wrappers, nor can you build with the OpenImageIO multimedia backend (OIIO
ships C++ headers). You'll be able to build the main library, though, as
well as `notcurses-demo` (and maybe a few other programs).
Use `-DUSE_CXX=off`.
Do I want ffmpeg or OpenImageIO?
While OpenImageIO is a superb library for dealing with single-frame images,
its video support is less than perfect (blame me; I've been promising Larry
I'd rewrite it for several months), and in any case implemented
atop...ffmpeg. ffmpeg is the preferred multimedia backend.
Does it work with hardware terminals?
With the correct `TERM` value, many hardware terminals are
supported. In general, if the terminfo database entry indicates mandatory
delays, Notcurses will not currently support that terminal properly. It's
known that Notcurses can drive the VT320 and VT340, including Sixel graphics
on the latter.
What happens if I try blitting bitmap graphics on a terminal which
doesn't support them?
Notcurses will not make use of bitmap protocols unless the terminal positively
indicates support for them, even if `NCBLIT_PIXEL` has been
requested. Likewise, sextants (`NCBLIT_3x2`) won't be used without
Unicode 13 support, octants (`NCBLIT_4x2`) won't be used without
Unicode 16 support, etc. `ncvisual_blit()` will use the best blitter
available, unless `NCVISUAL_OPTION_NODEGRADE` is provided (in
which case it will fail).
Notcurses looks like absolute crap in `screen`.
`screen` doesn't support RGB colors (at least as of 4.08.00);
if you have `COLORTERM` defined, you'll have a bad time.
If you have a `screen` that was compiled with
`--enable-colors256`, try exporting
`TERM=screen-256color` as opposed to `TERM=screen`.
Notcurses looks like absolute crap in `mosh`.
Yeah it sure does. I'm not yet sure what's up.
Notcurses looks like absolute crap in Windows Terminal.
Go to [Language Setting](ms-settings:regionlanguage), click
"Administrative language settings", click "Change system locale", and check
the "Beta: Use Unicode UTF-8 for worldwide language support" option. Restart
the computer. That ought help a little bit. Try playing with fonts—Cascadia
Code and Cascadia Mono both seem to work well (quadrants and Braille both
work), whereas Consolas and Courier New both have definite problems.
I'm getting strange and/or duplicate inputs in Kitty/foot.
Notcurses supports Kitty's powerful
[keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/),
which includes things like key release events and modifier keypresses by
themselves. This means, among other things, that a program in these terminals
will usually immediately get an `NC_ENTER` `NCTYPE_RELEASE`
event, and each keypress will typically result in at least two inputs.
Why didn't you just render everything to bitmaps?
That's not a TUI; it's a slow and inflexible GUI. Many terminal emulators
don't support bitmaps. They doesn't work well with mouse selection.
Sixels have a limited color palette. With that said, both Sixel and the
Kitty bitmap protocol are well-supported.
My multithreaded program doesn't see `NCKEY_RESIZE` until
I press some other key.
You've almost certainly failed to mask `SIGWINCH` in some thread,
and that thread is receiving the signal instead of the thread which called
`notcurses_getc_blocking()`. As a result, the `poll()`
is not interrupted. Call `pthread_sigmask()` before spawning any
threads.
Using the C++ wrapper, how can I ensure that the `NotCurses`
destructor is run when I return from `main()`?
As noted in the
C++ FAQ, wrap it in an artificial scope (this assumes your
`NotCurses` is scoped to `main()`).
How do I hide a plane I want to make visible later?
In order of least to most performant: move it offscreen using
`ncplane_move_yx()`, move it underneath an opaque plane with
`ncplane_move_below()`, or move it off-pile with
`ncplane_reparent()`.
Why isn't there an `ncplane_box_yx()`? Do you hate
orthogonality, you dullard? `ncplane_box()` and friends
already have far too many arguments, you monster.
Why doesn't Notcurses support 10- or 16-bit color?
Notcurses supports 24 bits of color, spread across three eight-bit channels.
You presumably mean 10-bit-per-channel color. I needed those six bits for
other things. When terminals support it, Notcurses might support it.
The name is dumb.
That's not a question?
I'm not finding qrcodegen on BSD, despite having installed
`graphics/qr-code-generator`.
Try `cmake -DCMAKE_REQUIRED_INCLUDES=/usr/local/include`.
This is passed by `bsd.port.mk`.
Do you support [musl](https://musl.libc.org/)?
I try to! You'll need at least 1.20.
I only seem to blit in ASCII, and/or can't emit Unicode beyond ASCII
in general.
Your `LANG` environment variable is underdefined or incorrectly
defined, or the necessary locale is not present on your machine (it is also
possible that you explicitly supplied `NCOPTION_INHIBIT_SETLOCALE`,
but never called `setlocale(3)`, in which case don't do that).
I pretty much always need an `ncplane` when using a
`nccell`. Why doesn't the latter hold a pointer to the former?
Besides the massive redundancy this would entail, `nccell` needs to
remain as small as possible, and you almost always have the `ncplane`
handy if you've got a reference to a valid `nccell` anyway.
I ran my Notcurses program under `valgrind`/ASAN, and
it shows memory leaks from `libtinfo.so`, what's up with that?
Yeah, the NCURSES Terminfo leaks memory unless compiled a special,
non-standard way (see the NCURSES FAQ). It shouldn't be a substantial amount;
you're advised not to worry overmuch about it.
I ran `notcurses-demo`, but my table numbers don't match
the Notcurses banner numbers, you charlatan.
`notcurses-demo` renders several frames beyond the actual demos.
When my program exits, I don't have a cursor, or text is invisible,
or colors are weird, *ad nauseam*.
Ensure you're calling `notcurses_stop()`/`ncdirect_stop()`
on all exit paths, including fatal signals (note that, by default, Notcurses
installs handlers for most fatal signals to do exactly this).
How can I use Direct Mode in conjunction with libreadline?
You can't anymore (you could up until 2.4.1, but the new input system is
fundamentally incompatible with it). `ncdirect_readline()` still exists,
though, and now actually works even without libreadline, though it is of
course not exactly libreadline. In any case, you'd probably be better off
using CLI mode with a `ncreader`.
So is Direct Mode deprecated or what?
It is not currently deprecated, and definitely receives bugfixes. You are
probably better served using CLI mode (see above), which came about
somewhat late in Notcurses development (the 2.3.x series), but is superior
to Direct Mode in pretty much every way. The only reason to use Direct
Mode is if you're going to have other programs junking up your display.
Direct Mode sounds fast! Since it's, like, direct.
Direct mode is *substantially slower* than rendered mode. Rendered
mode assumes it knows what's on the screen, and uses this information to
generate optimized sequences of escapes and glyphs. Direct mode writes
everything it's told to write. It is furthermore far less capable—all
widgets etc. are available only to rendered mode, and will definitely
not be extended to Direct Mode.
Will there ever be Java wrappers?
I should hope not. If you want a Java solution, try @klamonte's
[Jexer](https://jexer.sourceforge.io/). Autumn's a good
woman, and thorough. We seem to have neatly partitioned the language
space.
Given that the glyph channel is initialized as transparent for a
plane, shouldn't the foreground and background be initialized as transparent,
also?
Probably (they are instead by default initialized to opaque). This would change
some of the most longstanding behavior of Notcurses, though,
so it isn't happening.
I get linker errors when statically linking.
Are you linking all necessary libraries? Use
`pkg-config --static --libs notcurses`
(or `--libs notcurses-core`) to discover them.
Notcurses exits immediately in MSYS2/Cygwin.
Notcurses requires the
[Windows ConPTY](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/)
layer. This is available in Cygwin by default since 3.2.0, but is disabled
by default in MSYS. Launch `mintty` with `-P on`
arguments, or export `MSYS=enable_pcon` before launching it.
Can I avoid manually exporting `COLORTERM=24bit`
everywhere?
Sure. Add `SendEnv COLORTERM` to `.ssh/config`, and
`AcceptEnv COLORTERM` to `sshd_config` on the remote
server. Yes, this will probably require root on the remote server.
Don't blame me, man; I didn't do it.
How about *arbitrary image manipulation here* functionality?
I'm not going to beat ImageMagick et al. on image manipulation, but you can
load an `ncvisual` from RGBA memory using
`ncvisual_from_rgba()`.
My program locks up during initialization.
Notcurses interrogates the terminal. If the terminal doesn't reply to standard
interrogations, file a Notcurses bug, send upstream a patch, or use a different
terminal. No known terminal emulators exhibit this behavior.
How can I draw a large plane, and only make a portion of it visible?
The simplest way is probably to create a plane of the same dimensions immediately above
the plane, and keep a region of it transparent, and the rest opaque. If you want the visible
area to stay in the same place on the display, but the portion being seen to change, try
making a plane twice as large in each dimension as the original plane. Make the desired area
transparent, and the rest opaque. Now move the original plane behind this plane so that the
desired area lines up with the “hole”.
Why no `NCSTYLE_REVERSE`?
It would consume a precious bit. You can use `ncchannels_reverse()`
to correctly invert fore- and background colors.
How do I mix Rendered and Direct mode?
You really don't want to. You can stream a subprocess to a plane with the
`ncsubproc` widget.
How can I clear the screen on startup in Rendered mode when not using
the alternate screen?
Call `notcurses_refresh()` after `notcurses_init()`
returns successfully.
Why do the stats show more Linux framebuffer bitmap bytes written
than total bytes written to the terminal? And why don't Linux console
graphics work when I ssh?
Linux framebuffer graphics aren't implemented via terminal writes, but rather
writes directly into a memory map. This memory map isn't available on remote
machines, and these writes aren't tracked by the standard statistics.
What is the possessive form of Notcurses?
**Notcurses'.** I cite
Garner's Modern English Usage in its third edition: "POSSESSIVES. A. Singular
Possessives.…Biblical and Classical names that end with a /zəs/ or /eez/
sound take only the apostrophe." Some ask: is Notcurses then Biblical, or is it
Classical? Truly, it is both.
I just want to display a bitmap on my terminal. Your library is
complex and stupid. You are simple and stupid.
If you're willing to call a binary, use ncplayer to put an image,
with desired scaling, anywhere on the screen and call it a day. Otherwise,
call notcurses_init(), ncvisual_from_file(),
ncvisual_blit(), notcurses_render(), and
notcurses_stop(). It's not too tough. And thanks—your thoughtful
comments and appreciative tone are why I work on Free Software.
## Useful links
* [BiDi in Terminal Emulators](https://terminal-wg.pages.freedesktop.org/bidi/)
* [The Xterm FAQ](https://invisible-island.net/xterm/xterm.faq.html)
* [XTerm Control Sequences](https://invisible-island.net/xterm/ctlseqs/ctlseqs.pdf)
* [The NCURSES FAQ](https://invisible-island.net/ncurses/ncurses.faq.html)
* [ECMA-35 Character Code Structure and Extension Techniques](https://www.ecma-international.org/publications/standards/Ecma-035.htm) (ISO/IEC 2022)
* [ECMA-43 8-bit Coded Character Set Structure and Rules](https://www.ecma-international.org/publications/standards/Ecma-043.htm)
* [ECMA-48 Control Functions for Coded Character Sets](https://www.ecma-international.org/publications/standards/Ecma-048.htm) (ISO/IEC 6429)
* [Unicode 14.0 Full Emoji List](https://unicode.org/emoji/charts/full-emoji-list.html)
* [Unicode Standard Annex #29 Text Segmentation](http://www.unicode.org/reports/tr29)
* [Unicode Standard Annex #15 Normalization Forms](https://unicode.org/reports/tr15/)
* [mintty tips](https://github.com/mintty/mintty/wiki/Tips)
* [The TTY demystified](http://www.linusakesson.net/programming/tty/)
* [Dark Corners of Unicode](https://eev.ee/blog/2015/09/12/dark-corners-of-unicode/)
* [UTF-8 Decoder Capability and Stress Test](https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt)
* [Emoji: how do you get from U+1F355 to 🍕?](https://meowni.ca/posts/emoji-emoji-emoji/)
* [Glyph Hell: An introduction to glyphs, as used and defined in the FreeType engine](http://chanae.walon.org/pub/ttf/ttf_glyphs.htm)
* [Text Rendering Hates You](https://gankra.github.io/blah/text-hates-you/)
* [Use the UTF-8 code page](https://docs.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page)
* My wiki's [Sixel page](https://nick-black.com/dankwiki/index.php?title=Sixel) and Kitty's [extensions](https://sw.kovidgoyal.net/kitty/protocol-extensions.html).
* Linux man pages: [console_codes(4)](http://man7.org/linux/man-pages/man4/console_codes.4.html), [termios(3)](http://man7.org/linux/man-pages/man3/termios.3.html), [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html), [ioctl_console(2)](http://man7.org/linux/man-pages/man2/ioctl_console.2.html)
* The Microsoft Windows [Console Reference](https://docs.microsoft.com/en-us/windows/console/console-reference)
* NCURSES man pages: [terminfo(5)](http://man7.org/linux/man-pages/man5/terminfo.5.html), [user_caps(5)](http://man7.org/linux/man-pages/man5/user_caps.5.html)
> “Our fine arts were developed, their types and uses were established, in times
very different from the present, by men whose power of action upon things was
insignificant in comparison with ours. But the amazing growth of our
techniques, the adaptability and precision they have attained, the ideas and
habits they are creating, make it a certainty that _profound changes are
impending in the ancient craft of the Beautiful_.” —Paul Valéry
---
## File: cffi/README.md
# notcurses
Python bindings for the C [Notcurses](https://github.com/dankamongmen/notcurses)
library. Notcurses is a blingful library for building complex, vibrant textual
user interfaces (TUIs) on modern terminal emulators, of which these Python
bindings offer nowhere near complete coverage.
by [nick black](https://nick-black.com/dankwiki/index.php/Hack_on) ()
for more information, see [my wiki](https://nick-black.com/dankwiki/index.php/Notcurses).
[](https://drone.dsscaw.com:4443/dankamongmen/notcurses)
[](https://opensource.org/licenses/Apache-2.0)
---
## File: doc/examples/src/basics.md
# Basics
Notcurses is a library for terminal applications—programs which do not require
a GUI environment, and write output as cells rather than pixels. Within a GUI
environment, such programs run in a *terminal emulator*; they can also run
on a *virtual console*, a *pseudoterminal* (such as those used by `ssh`), or
even a true hardware terminal. It is inspired by the [X/Open CURSES](https://publications.opengroup.org/c094)
specification, though it is (by necessity) not source-compatible with that API.
Terminal applications emit a stream of *code points*. Code points index into
the terminal's *character set*; visual characters are run through a font engine
to produce *glyphs*, whereas *escape sequences* facilitate in-band control of
the output and operation of the terminal, including changing presentation style
and moving the cursor. A major function of Notcurses is to portably and
efficiently emit the sequences necessary to effect higher-level client goals.
Notcurses offers two major modes of operation:
* **[Direct mode](./directmode.md)** can be used together with standard I/O. It is primarily meant
to enhance simple scrolling applications via coloring and styling, though it
can also move the cursor, read raw keyboard input, and render media. Use
direct mode if you intend to primarily output through standard library
functions such as `printf()`. Direct mode uses `struct ncdirect`s.
* **[Rendered mode](./rendered.md)** facilitates more complex Text User Interface applications.
These applications maintain virtual state in the form of ordered stacks of
`struct ncplane`s; when ready, the visible area is redrawn. It can provide
much greater performance than direct mode, but does not tolerate the use of
standard I/O. Rendered mode uses `struct notcurses`.
Whichever mode is used, it is essential to destroy all Notcurses contexts upon
program exit, or the terminal can be left in an undesirable state. By default,
Notcurses registers handlers for most fatal signals, to destroy its own
contexts. On a typical exit, the user must destroy these contexts.
Notcurses does not strictly require a terminal device for input or output; it
can be freely redirected to arbitrary character devices or files. When not
connected to a terminal device, many escapes will not be generated.
Whether using rendered or direct mode, there are a few technical minutia
almost every Notcurses program will want to do early on:
* Call `setlocale()` to modify the program's POSIX locale, usually based
on the `LANG` environment variable. This is necessary to place the program
in UTF-8 mode, which is necessary for optimal Notcurses operation [^Unless
the `INHIBIT_SETLOCALE` flag is used, Notcurses will handle this for you
if you don't do it, but it's ideally done as one of the very first steps of
your program.].
* Mask out `SIGWINCH`, especially if you intend to create any threads. This is
necessary to ensure WINdow CHange notifications go to the desired thread.
---
## File: doc/examples/src/directmode.md
# Direct mode
Direct mode allows you to use Notcurses together with standard I/O. While
the cursor can still be moved arbitrarily, direct mode is intended to be used
with newline-delimited, scrolling output. Direct mode has no concept of frame
rendering; output is intended to appear immediately (subject to buffering). It
is still necessary to have a valid `TERM` environment variable identifying a
valid terminfo database entry for the running terminal.
The authoritative reference for direct mode is the `notcurses_direct(3)`
man page.
Enter direct mode with a call to `ncdirect_init()`. It takes three arguments:
`struct ncdirect* ncdirect_init(const char* termtype, FILE* fp, uint64_t flags);`
You can usually simply pass `NULL`, `NULL`, and 0. This will use the terminal
entry specified by the `TERM` environment variable, and write to `stdout`. If
the terminfo entry cannot be loaded, `ncdirect_init()` will fail. Otherwise,
the active style (italics, reverse video, etc.) will be reset to the default,
and all `ncdirect` functions are available to use. When done with the context,
call `ncdirect_stop()` to release its resources, and restore the terminal's
preserved status.
The cursor is not moved by initialization. If your program was invoked as
`ncdirect-demo` from an interactive shell, the cursor is most likely to be
on the first column of the line following your command prompt, exactly where
a program like `ls` would start its output.
```c
{{#include directmode-helloworld.c}}
```
The terminal will scroll on output just like it normally does, and if you have
a scrollback buffer, any output you generate will be present there. Remember:
direct mode simply *styles* standard output. With that said, the cursor can be
freely controlled in direct mode, and moved arbitrarily within the viewing
region. Dimensions of the terminal can be acquired with `ncdirect_dim_y()` and
`ncdirect_dim_x()` (if you initialized direct mode with a file not attached to
a terminal, Notcurses will simulate a 80x24 canvas). The cursor's location is
found with `ncdirect_cursor_yx()` (this function fails if run on a
non-terminal, or if the terminal does not support this capability).
**ncdirect_ cursor functions**
The cursor can be moved relative to its current location, or absolutely within
the terminal's boundaries. The location can also be pushed and popped (''FIXME''
why don't we synthesize this in the absence of `sc/rc`? why is this exposed at
all? do some terminals support `sc` but not cursor location discovery?).
The cursor can be hidden and made visible once more with `ncdirect_cursor_disable()`
and `ncdirect_cursor_enable()`. Unlike rendered mode, the cursor is not hidden
by default at initialization.
**example scrolling a screen's worth of text**
**picture before and after run**