Icod.DCurses 2.4.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Icod.DCurses --version 2.4.0
                    
NuGet\Install-Package Icod.DCurses -Version 2.4.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="2.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Icod.DCurses" Version="2.4.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 2.4.0
                    
#r "nuget: Icod.DCurses, 2.4.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@2.4.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=2.4.0
                    
Install as a Cake Addin
#tool nuget:?package=Icod.DCurses&version=2.4.0
                    
Install as a Cake Tool

Icod.DCurses

Icod TUI Toolchain

PR Staging build Main Release validation

Icod.DCurses is a managed, cross-platform curses-style terminal UI library for .NET. It provides retained screens, windows, pads and panels; Unicode-aware text layout; viewports and geometry; semantic metadata and mixed media; damage-aware refresh; and deterministic interaction routing without taking ownership of the application's event loop.

Install

dotnet add package Icod.DCurses

The package targets .NET 8, .NET 9 and .NET 10 and uses C# 13. NuGet restores the compatible Icod.Terminal dependency; applications do not need a direct Icod.TermInfo reference for DCurses.

To run the editor-foundation sample from a repository checkout:

dotnet run --project samples/Icod.DCurses.Editor.Sample/Icod.DCurses.Editor.Sample.csproj -c Release -f net10.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 inputEvent = await session.ReadEventAsync();

The application decides how to interpret inputEvent, when to refresh again, and when to exit. DCurses does not start a callback dispatcher or a second input reader.

Clipboard and cursor style

Icod.DCurses 2.4 adds explicit, bounded clipboard operations and reversible semantic cursor-style leases over the canonical terminal session:

CursesSessionOptions options = new() {
	HideCursor = false,
	ClipboardOptions = new CursesClipboardOptions {
		MaximumReadBytes = 65_536,
		MaximumWriteBytes = 65_536
	}
};

await using CursesSession session = await CursesSession.OpenAsync( options );
await using CursesCursorStyleLease caret =
	await session.AcquireCursorStyleAsync(
		CursesCursorStyle.SteadyBar,
		TimeSpan.FromMilliseconds( 250 )
	);

await session.WriteClipboardAsync(
	CursesClipboardSelection.Clipboard,
	"selected text"
);

byte[] payload = await session.ReadClipboardAsync(
	CursesClipboardSelection.Clipboard,
	TimeSpan.FromMilliseconds( 250 )
);

The default read and write budgets are independently 65,536 bytes and may be configured up to 16 MiB before opening an owned session. They are local safety limits, not a negotiation of remote clipboard capacity. Writes confirm that the complete terminal command was emitted, not that the host accepted it. A read timeout is inconclusive; applications should own fallback content and policy.

Cursor style and visibility are independent. The lease restores the exact observed preceding style in LIFO order. If observation is unsupported, times out or is cancelled, no guessed reset or style mutation is emitted.

Editor foundations

The editor sample is deliberately a public-API composition witness, not a document engine. It demonstrates:

  • viewport-local Unicode layout, caret geometry, selection and retained repaint;
  • a synthetic ten-million-record source with work bounded to visible records;
  • bracketed paste as routed text data and key-release suppression;
  • primary-button caret placement and selection with captured outside drag;
  • cancellation on release, focus loss, modal activation, resize and disposal;
  • a separately hit-tested final-column scrollbar without implicit Tab traversal;
  • explicit Ctrl+C/Ctrl+V clipboard commands with an application fallback;
  • a visible caret with a best-effort scoped steady-bar style.

Document storage, undo/redo, revision caches, selection semantics, autoscroll timing, tabs, dialogs and file I/O belong in Icod.Widgets or the application. The complete controls and limitations are documented in the samples guide.

Text layout and retained projection

Source positions are UTF-16 offsets at legal text-element boundaries; visual positions are rows and terminal columns. The application supplies the bounded text slice to lay out and decides which lines to project:

CursesTextLayout layout = CursesTextLayout.Create(
	"Hello 👩‍💻 world",
	new CursesTextLayoutOptions( 20 ) {
		WrapMode = CursesTextWrapMode.TextElement
	}
);
CursesTextPosition afterEmoji =
	layout.GetNextPosition( new CursesTextPosition( 6 ) );
CursesTextVisualPosition caret = layout.GetVisualPosition( afterEmoji );

screen.PresentTextLayout( layout, 0, layout.Lines.Count, 0, 0 );
if ( caret.Line < screen.Rows && caret.Column < screen.Columns ) {
	screen.Move( caret.Line, caret.Column );
}
await session.RefreshAsync();

HitTest and GetSelectionRectangles use the same Unicode/cell geometry. Applications should not build file-sized pads or whole-file layouts; keep document indexing and revision-aware visible-slice caches above DCurses.

Interaction routing

Applications can register semantic key gestures and sequences, inspect the currently effective bindings for help text, and route one normalized input event at a time. Pending sequences have no hidden timer:

CursesKeyGesture g = CursesKeyGesture.ForCharacter( new Rune( 'g' ) );
CursesCommand goTop = new( "document.go-top" );
router.BindGlobalGestureSequence( [ g, g ], goTop );

IReadOnlyList<CursesCommandSequenceBinding> helpBindings =
	router.GetEffectiveGestureSequenceBindings();

CursesCommandSequenceResult result = router.ProcessCommandSequence( inputEvent );
if ( result.Kind is CursesCommandSequenceResultKind.Completed ) {
	ExecuteApplicationCommand( result.Command! );
} else if ( result.Fallback is not null ) {
	HandleOrdinaryRoutingResult( result.Fallback );
}

Focused-region, active-scope and router-global precedence match ordinary routing. The application owns command execution, labels, localization, prefix timeouts, Tab policy and event-loop timing.

Feature inventory

  • Retained logical screens, windows, pads, viewports and panels.
  • Unicode text-element measurement, wrapping, hit testing and selection geometry.
  • Styles, line drawing, semantic hyperlinks and width-two cell coherence.
  • Sparse/full damage refresh, synchronized output and physical-state invalidation.
  • Geometry, clipping, tracks, docking and prepared bulk cell writes.
  • Normalized keyboard, mouse, focus, paste and lifecycle events.
  • Interaction regions, modal scopes, focus, pointer capture and command sequences.
  • Bounded clipboard access and scoped semantic cursor styles.
  • Retained raster resources/placeholders and bounded cell-aligned raster atlases.
  • net8.0, net9.0 and net10.0 package assets with portable symbols and XML docs.

Architecture and boundaries

application / Icod.Widgets
    document, controls, commands, event loop, files and policy
        |
Icod.DCurses
    retained cells, layout projection, damage and interaction mechanisms
        |
Icod.Terminal
    live session, semantic protocols, host I/O and reversible terminal state
        |
Icod.TermInfo
    immutable capability data and planning
        |
terminal / tty

Icod.DCurses does not provide a widget framework, text buffer, callback dispatcher, terminal emulator, PTY host, native clipboard, private protocol parser, automatic raster replay or application policy. Terminal remains the sole owner of protocol framing, query correlation, live identities and physical state.

Compatibility and versioning

The 2.4 public surface is additive over 2.3.1 and keeps AssemblyVersion 2.0.0.0. It has 109 exported types, 857 canonical declared contract lines and SHA-256 fingerprint 87a3ffe66174634f6db4044b914b05fd31d117b93ecf5b1a151d31d59732e65e.

Version 2.0 changed the public profile/dimensions signatures and advanced AssemblyVersion to 2.0.0.0; applications upgrading from 1.6 must rebuild. See the 2.0 migration guide.

Documentation and samples

Support the project

Icod.DCurses and its ecosystem packages are maintained by a solo developer.

GitHub Sponsors Ko-fi PayPal

Authors

Inspired by Bill Joy (termcap); Ken Arnold (termcap and curses); Mary Ann (born Mark) Horton (terminfo); Pavel Curtis (pcurses); and Zeyd Ben-Halim, Eric S. Raymond and Thomas Dickey (libtinfo and ncurses).

Managed .NET implementation by Timothy J. Bruce uniblab@hotmail.com.

License

Icod.DCurses is licensed under the GNU Lesser General Public License, version 3 or later. Samples and tests are licensed under the GNU General Public License, version 3 or later. See the repository license and per-project/source declarations.

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

Showing the top 1 NuGet packages that depend on Icod.DCurses:

Package Downloads
Icod.Widgets

Reusable terminal UI widgets for .NET, including color themes, Unicode text editing, forms, menus, dialogs, lists, filesystem pickers, and game controls above Icod.DCurses.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.5.0 456 10/12/2026
2.4.0 137 10/11/2026
2.3.1 272 10/10/2026
2.3.0 55 10/9/2026
2.2.0 453 9/25/2026
2.1.0 100 9/24/2026
2.0.0 104 9/23/2026
1.6.0 392 9/17/2026
1.5.0 106 9/15/2026
1.4.0 104 9/14/2026
1.3.0 111 9/12/2026
1.2.0 154 9/10/2026
1.1.0 119 9/10/2026
1.0.0 108 9/9/2026
0.9.0 113 9/9/2026
0.8.0 110 9/9/2026
0.7.0 115 9/9/2026
0.6.0 113 9/9/2026
0.5.0 117 9/8/2026
0.4.0 112 9/8/2026
Loading failed

2.4 adds explicit bounded clipboard read/write facades, reversible semantic cursor-style leases, qualified viewport-local editor projection, and a public-only editor interaction sample. The sole direct runtime dependency is stable Icod.Terminal 1.29.0.