Icod.DCurses
1.2.0
See the version list below for details.
dotnet add package Icod.DCurses --version 1.2.0
NuGet\Install-Package Icod.DCurses -Version 1.2.0
<PackageReference Include="Icod.DCurses" Version="1.2.0" />
<PackageVersion Include="Icod.DCurses" Version="1.2.0" />
<PackageReference Include="Icod.DCurses" />
paket add Icod.DCurses --version 1.2.0
#r "nuget: Icod.DCurses, 1.2.0"
#:package Icod.DCurses@1.2.0
#addin nuget:?package=Icod.DCurses&version=1.2.0
#tool nuget:?package=Icod.DCurses&version=1.2.0
Icod.DCurses

Icod.DCurses is a managed, cross-platform curses-style terminal UI library for .NET.
It sits above Icod.Terminal and Icod.TermInfo:
Icod.TermInfoowns immutable terminal capability descriptions and expansion;Icod.Terminalowns the live terminal session, host mode, dimensions, lifecycle, input decoding, semantic terminal protocols, and output serialization;Icod.DCursesowns curses-shaped events, logical screens/windows, pads/viewports, retained panels/layers, cells/styles/metadata, composition, and retained refresh policy.
Status
Icod.DCurses 1.2.0 is implementation/API/sample/test complete in PR #26. The branch now declares Icod.Terminal 1.9.0; exact-head dependency-refresh qualification is pending NuGet indexing of that newly published package. A temporary restore failure during package propagation is expected and is not a reason to add version-specific compatibility checks or fallback package sources.
Current source identity:
Version 1.2.0
PackageVersion 1.2.0
AssemblyVersion 1.0.0.0
Icod.Terminal 1.9.0
Icod.TermInfo 1.10.0
Accepted 1.1 compatibility floor:
45 exported types
337 canonical declared contract lines
sha256 21dff2e57d8bbc9b2f0e40aa4ee4dfd575dd765d02d0f670424c93b2bdc1c039
Accepted 1.2 contract:
47 exported types
356 canonical declared contract lines
sha256 4810ebb088764acedbb94aca84b231677886b9c1a1f920d9a30f960cbe1dfce7
The two new exported types are CursesPanel and CursesPanelTransparency.
Installation
Install the current package selected by your normal NuGet policy:
dotnet add package Icod.DCurses
This README describes the source candidate in PR #26. Merge, tag, GitHub Release creation, and NuGet publication are separate explicit release actions.
Architecture
applications / future widgets / compatibility facades
|
Icod.DCurses
windows / pads / panels / cells / semantic metadata
logical composition / retained refresh / events
|
Icod.Terminal
live session / input / lifecycle / semantic protocols
capability routing / serialized output
|
Icod.TermInfo
immutable capability authority
|
terminal / tty
Icod.DCurses does not maintain a second terminal capability database, install a competing raw-input loop, own terminal modes independently of Icod.Terminal, emit private OSC/CSI/DCS/APC framing for Terminal-owned protocols, emulate a terminal, or create/manage PTYs.
Targets
- .NET 8
- .NET 9
- .NET 10
- C# 13
- Windows x64/ARM64
- Linux x64/ARM64
- macOS x64/ARM64
Quick start
using Icod.DCurses;
await using CursesSession session = await CursesSession.OpenAsync();
CursesWindow screen = session.StandardScreen;
screen.Clear();
screen.Move(
0,
0
);
screen.Write(
"Hello from Icod.DCurses",
new CursesStyle(
CursesColor.Default,
CursesColor.Default,
CursesTextAttributes.Bold
)
);
await session.RefreshAsync();
CursesEvent terminalEvent = await session.ReadEventAsync();
A CursesSession restores the presentation and Terminal-owned state it acquires when disposed. Applications should consume terminal input and lifecycle activity through the curses/Terminal ownership model rather than adding a parallel byte reader.
1.2 retained panels and layers
Ordinary CursesWindow instances remain shared logical views. CursesPanel is intentionally different: it owns an independent retained surface and participates in a deterministic screen-owned z-order stack.
using CursesPanel dialog = session.Screen.CreatePanel(
row: 3,
column: 6,
rows: 8,
columns: 36
);
dialog.ContentWindow.Write( "Retained dialog content" );
dialog.MoveToTop();
await session.RefreshAsync();
Panels are opaque by default. A panel can instead make ordinary blank cells transparent:
using CursesPanel overlay = session.Screen.CreatePanel(
row: 2,
column: 4,
rows: 3,
columns: 20
);
overlay.Transparency = CursesPanelTransparency.BlankCellsTransparent;
overlay.ContentWindow.Write( "overlay" );
The 1.2 panel contract includes independent retained content, show/hide with remembered z-order, movement and relative ordering, clipping, opaque/blank-transparent composition, Unicode width-two and semantic-metadata coherence, damage-bounded recomposition, live session refresh/lifecycle integration, and deterministic one-way Dispose() removal.
Disposal removes a transient panel from its owning screen so repeatedly-created popups/dialogs are not retained for the screen lifetime. A disposed panel cannot be reattached or manipulated.
Panel size remains fixed in 1.2. General layout and resize primitives belong to the planned 1.3 release.
1.1 semantic metadata and hyperlinks
Version 1.1 added semantic meaning attached to retained content, beginning with hyperlinks, while keeping visual rendition in CursesStyle.
CursesCellMetadata metadata = new(
new CursesHyperlink(
"https://example.test/docs",
"docs"
)
);
screen.WriteWithMetadata(
"documentation",
metadata
);
Metadata is retained independently of visible glyph/style equality, follows content through supported editing/composition operations, remains coherent across two-column leader/continuation footprints, and is emitted physically through Terminal-owned semantic hyperlink operations. DCurses does not construct OSC 8 directly.
Pads, Unicode, and semantic drawing
CursesPad is an off-screen logical surface that reuses ordinary CursesWindow editing semantics. Multiple viewports may observe one pad independently.
The built-in width provider is pinned to Unicode 17.0.0. East Asian Ambiguous characters are narrow by default and can be made wide explicitly with UnicodeCursesTextWidthProvider.WideAmbiguousInstance.
CursesText.MeasureColumns, TruncateToColumns, and SliceByColumns operate on complete terminal text elements and never return half of a two-column element. Semantic line cells remain distinct from ordinary Unicode box-drawing text.
Concurrency and lifecycle
The library deliberately uses a narrow ownership model rather than pervasive per-cell locking:
- logical screens, windows, pads, viewports, and panels are single-writer unless documented otherwise;
- one Terminal-owned event wait may coexist with serialized refresh/output work;
- caller cancellation does not discard Terminal decoder state;
- disposal unblocks pending DCurses waits while preserving authoritative restoration;
- output uncertainty invalidates retained physical knowledge so a later refresh can repaint safely;
- suspend/resume invalidates physical knowledge but retains logical panel content.
Validation and packaging
Local wrappers use Debug configuration. Pull requests use Staging with warnings-as-errors. Pushes to main and release tags use Release.
Runtime validation covers Windows/Linux/macOS x64 and ARM64; the library/test matrix covers net8.0, net9.0, and net10.0.
Package validation verifies .nupkg/.snupkg, package/assembly identity, dependency groups derived from project declarations, README/license/icon/repository metadata, XML documentation, portable symbols, and a fresh NuGet-only consumer. Package validation does not impose hard-coded sibling dependency versions.
Release documentation
Current post-1.0 authorities:
Icod.DCurses-Development-Roadmap.mdIcod.DCurses-1.1.0-to-1.4.0-Development-Roadmap.mdIcod.DCurses-1.2.0-Development-Roadmap.mddocs/T1208-Panel-Application-Performance-and-Allocation-Acceptance.mddocs/T1209-Public-API-Package-Documentation-and-Regret-Gate.mddocs/T1210-RC-and-Stable-Closure.mddocs/Public-API-Fingerprint-1.2.jsondocs/Public-API-Baseline-1.2.md
Historical 1.0 and 1.1 closure records remain compatibility authorities and are not rewritten merely to reflect later development state.
Authors
Inspired by original work from Bill Joy, author of the original termcap; Mary Ann (born Mark) Horton, author of terminfo; Pavel Curtis, author of pcurses; and Zeyd Ben-Halim, Eric S. Raymond, and Thomas Dickey, whose work developed and maintained libtinfo and ncurses.
Managed .NET implementation by Timothy J. Bruce uniblab@hotmail.com.
Copyright
Copyright (c) 2026 Timothy J. Bruce
License
Licensed under the GNU Lesser General Public License v3.0 or later. See LICENSE.
The NuGet package declares license acceptance as required. Package clients which honor NuGet's requireLicenseAcceptance metadata must obtain acceptance of the license terms before installation.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Icod.Terminal (>= 1.9.0)
- Icod.TermInfo (>= 1.10.0)
-
net8.0
- Icod.Terminal (>= 1.9.0)
- Icod.TermInfo (>= 1.10.0)
-
net9.0
- Icod.Terminal (>= 1.9.0)
- Icod.TermInfo (>= 1.10.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.0 | 196 | 9/25/2026 |
| 2.1.0 | 91 | 9/24/2026 |
| 2.0.0 | 95 | 9/23/2026 |
| 1.6.0 | 232 | 9/17/2026 |
| 1.5.0 | 97 | 9/15/2026 |
| 1.4.0 | 97 | 9/14/2026 |
| 1.3.0 | 104 | 9/12/2026 |
| 1.2.0 | 146 | 9/10/2026 |
| 1.1.0 | 112 | 9/10/2026 |
| 1.0.0 | 104 | 9/9/2026 |
| 0.9.0 | 106 | 9/9/2026 |
| 0.8.0 | 103 | 9/9/2026 |
| 0.7.0 | 108 | 9/9/2026 |
| 0.6.0 | 107 | 9/9/2026 |
| 0.5.0 | 109 | 9/8/2026 |
| 0.4.0 | 105 | 9/8/2026 |
| 0.3.0 | 101 | 9/8/2026 |
| 0.2.0 | 110 | 9/8/2026 |
| 0.1.1 | 112 | 9/8/2026 |
| 0.1.0 | 4,714 | 8/29/2026 |
1.2.0 adds independent retained CursesPanel surfaces over the stable 1.0/1.1 window contract. Panels provide deterministic screen-owned z-order, show/hide, movement, opaque or blank-transparent composition, clipping, Unicode/wide-cell and semantic-metadata coherence, damage-bounded incremental recomposition, live CursesSession refresh/lifecycle integration, and deterministic IDisposable removal for transient panels. Ordinary CursesWindow shared-view semantics remain unchanged and no-panel refresh retains an allocation-free fast path. The 1.2 public contract adds exactly CursesPanel and CursesPanelTransparency over 1.1. Runtime dependencies are Icod.Terminal 1.9.0 and Icod.TermInfo 1.10.0; AssemblyVersion remains 1.0.0.0.