Icod.DCurses 0.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Icod.DCurses --version 0.3.0
                    
NuGet\Install-Package Icod.DCurses -Version 0.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Icod.DCurses" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Icod.DCurses" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Icod.DCurses" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Icod.DCurses --version 0.3.0
                    
#r "nuget: Icod.DCurses, 0.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Icod.DCurses@0.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Icod.DCurses&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Icod.DCurses&version=0.3.0
                    
Install as a Cake Tool

Icod.DCurses

Icod TUI Toolchain

Icod.DCurses is a managed, cross-platform curses-like terminal UI library for .NET.

The library sits above Icod.TermInfo and Icod.Terminal. Icod.TermInfo remains the immutable terminal-capability authority; Icod.Terminal owns the live terminal session, host mode, dimensions, lifecycle, input decoding, and reversible presentation and input-protocol leases. Icod.DCurses owns curses-shaped events, virtual screens and windows, terminal cells and styles, rendition policy, and refresh/damage synchronization.

Status

Icod.DCurses 0.2.0 is the current published stable release.

The 0.3.0 Unicode and terminal-cell source contract is now prepared as a stable release candidate for merge. The source version and package version are 0.3.0; publication remains post-merge and therefore the published package is still 0.2.0 until the v0.3.0 release workflow completes.

T301 and T302 established the normalized Unicode text-element pipeline used by CursesWindow.Write(string): malformed UTF-16 is replaced before segmentation, and width decisions operate on complete normalized text elements.

T303 pins the terminal-width data contract to Unicode 17.0.0, replaces the old permanent hand-maintained East Asian Width predicate with checked-in generated data, and exposes explicit narrow/wide East Asian Ambiguous policy. Narrow remains the default; wide-Ambiguous behavior is opt-in and does not depend on locale or environment guessing. Unicode 17 Emoji property data is also generated and checked in for VS16 and emoji-ZWJ candidate classification.

T304 adds public terminal-column helpers through CursesText.MeasureColumns, TruncateToColumns, and SliceByColumns, using the same normalization, segmentation, and width-provider contract as windows.

T305 hardens screen/window two-column leader/continuation footprints across preserved resize and subwindow boundaries while retaining CursesVirtualScreen as an exact low-level cell store when used independently. T306 adds the broader Unicode conformance corpus, package-only consumer coverage, and live Unicode diagnostics showcase.

T307 is complete: the 0.3 public API, Unicode-data contract, dependency boundary, documentation, and package-consumer surface passed the regret gate and are feature-frozen. The 0.3.0-rc.1 validation gate passed on Windows, Linux, macOS, and the canonical package/fresh-consumer job. T308 has promoted that unchanged contract to stable 0.3.0 source for the final PR validation before merge.

0.2.0 completed stable Icod.Terminal 1.0.0 semantic-input parity: the curses facade carries the complete stable key vocabulary, modifier state, press/repeat/release phases, modern character metadata, and optional keyboard reporting while keeping raw terminal decoding and protocol lifecycle in Icod.Terminal.

The dependency baseline remains:

  • Icod.Terminal 1.0.0
  • Icod.TermInfo 1.10.0

The retired DCurses backend, native mode, lifecycle-source, input-decoder, and pre-Terminal session implementations remain removed. DCurses does not add a mouse parser, paste reader, protocol escape emitter, keyboard decoder, or second input loop.

The first release line was driven by the requirements of top, slabtop, and watch. The 1.0 development train broadens that foundation into a general managed TUI contract.

See Icod.DCurses-1.0.0-Development-Roadmap.md for the authoritative release train through 1.0.0, and Icod.DCurses-0.3.0-Development-Roadmap.md for the Unicode/terminal-cell tranche. The 0.3 checkpoints and release gates are recorded in:

  • docs/T302-Normalized-Grapheme-Text-Pipeline.md
  • docs/T303-Unicode-Width-Data-and-Ambiguous-Policy.md
  • docs/T304-Column-Oriented-Text-Helpers.md
  • docs/T305-Wide-Cell-Footprint-Invariants.md
  • docs/T306-Unicode-Conformance-and-Consumer-Acceptance.md
  • docs/T307-Public-API-Documentation-and-Package-Regret-Gate.md
  • docs/T308-0.3.0-Stable-Release-Closure.md
  • docs/Public-API-Baseline-0.3.md

Icod.DCurses-0.2.0-Development-Roadmap.md and docs/Public-API-Baseline-0.2.md record the stable semantic-input release. docs/Dependency-Baseline-0.1.1.md retains the Terminal/TermInfo ownership baseline inherited by later releases.

Icod.DCurses-Development-Roadmap.md retains the original project roadmap and 0.1 development history. Historical integration checkpoints remain under docs/.

Architecture

top / slabtop / watch / other TUIs
                 |
            Icod.DCurses
     windows / cells / refresh
       rendition / curses events
                 |
            Icod.Terminal
 session / input / lifecycle / dimensions
 presentation / input-protocol leases
                 |
            Icod.TermInfo
      terminal capability model
                 |
            terminal / tty

Icod.DCurses does not hard-code one terminal family. Terminal-specific output continues to be selected through Icod.TermInfo, while live session ownership and reversible terminal state are centralized in Icod.Terminal.

Target

The implementation targets:

  • .NET 8
  • .NET 9
  • .NET 10
  • C# 13
  • Windows
  • Linux
  • macOS

Installation

The current published stable package is:

dotnet add package Icod.DCurses --version 0.2.0

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();

The session owns the presentation state it enters and restores that state when disposed. Applications should consume terminal input and lifecycle activity through CursesSession rather than adding a parallel terminal reader.

Unicode column helpers (0.3)

Applications can measure or trim printable text using the same terminal-column contract as window writes:

int columns = CursesText.MeasureColumns( "A界B" );
string prefix = CursesText.TruncateToColumns( "A界B", 3 );
string slice = CursesText.SliceByColumns( "A界B", 1, 2 );

The default provider uses Unicode 17.0.0 data and treats East Asian Ambiguous characters as narrow. Applications that deliberately require wide-Ambiguous semantics can pass UnicodeCursesTextWidthProvider.WideAmbiguousInstance to a CursesScreen or to the CursesText helpers.

Column helpers normalize malformed UTF-16 before text-element segmentation, reject terminal controls, and never return half of a two-column text element.

Modern keyboard input (0.2)

Applications which want key-event phases can request them through the curses protocol lease without using Terminal protocol types directly:

var keyboard = await session.AcquireInputProtocolsAsync(
    new CursesInputProtocolOptions {
        KeyboardReportingMode = CursesKeyboardReportingMode.EventTypes
    }
);

if ( keyboard.IsAvailable ) {
    await using CursesInputProtocolLease lease = keyboard.GetRequiredValue();
    CursesEvent current = await session.ReadEventAsync();

    if ( current.Input is {
        Kind: CursesInputEventKind.Key
    } input ) {
        CursesKey key = input.Key;
        CursesKeyEventPhase? phase = input.KeyPhase;
        CursesKeyModifiers modifiers = input.Modifiers;
    }
}

Keyboard reporting is optional. A terminal which cannot provide the requested mode returns a controlled unavailable result; applications can continue using the ordinary curses input stream.

Build

From the repository root:

build.cmd

or:

./build.sh

Both wrappers delegate to packaging/Invoke-Build.ps1 and use the Debug configuration for local development. With no section argument they perform restore, build, test, pack, and package validation. They also accept clean, restore, build, test, pack, or validate; prerequisite phases are run automatically where needed.

Pull-request validation promotes the build to Staging. Pushes to main and release tags use Release. Package validation exercises the packed artifact and a fresh package-only consumer rather than relying only on the repository project references.

The Unicode width-data generator is a maintainer tool outside the solution. See tools/unicode-width-generator/README.md; normal builds do not fetch Unicode data from the network.

Authors

Timothy J. Bruce.

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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 191 9/25/2026
2.1.0 88 9/24/2026
2.0.0 92 9/23/2026
1.6.0 229 9/17/2026
1.5.0 97 9/15/2026
1.4.0 95 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,704 8/29/2026
Loading failed

0.3.0 establishes the Unicode terminal-cell contract for Icod.DCurses: Unicode 17.0.0 generated East Asian Width and Emoji-property data, explicit narrow/wide East Asian Ambiguous policy, normalized grapheme-aware window writes, column-safe measurement/truncation/slicing helpers, Unicode conformance coverage, and hardened wide-cell structural invariants. Dependencies remain Icod.Terminal 1.0.0 and Icod.TermInfo 1.10.0.