ktsu.ImGui.SyntaxHighlighting 3.79.0

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

ktsu.ImGui.SyntaxHighlighting

NuGet License

ImGui.SyntaxHighlighting draws syntax-highlighted source code directly inside Dear ImGui. Like its sibling ktsu.ImGui.Markdown, it is a standalone package layered on ktsu.ImGui.Color only, with no dependency on ktsu.ImGui.App, so it can be dropped into any Hexa.NET.ImGui application.

Tokenizing lives one layer down, in the renderer-agnostic ktsu.SyntaxHighlighting: languages, themes, the token kinds and the embedded-language rules are all defined there and know nothing about ImGui. This package is the drawing half — a background panel, a line-number gutter, and colored token runs painted into the window draw list.

Features

  • Fifteen built-in languages: C#, C, C++, JavaScript, TypeScript, Python, JSON, YAML, XML, HTML, CSS, SQL, shell, Lua, and plain text, each reachable by name or alias (cs, c#, js, py, bash, yml, …)
  • Data-driven definitions: a language is a LanguageDefinition record — comment, string, keyword and operator rules — so an application can register its own, or derive a variant of a built-in with a with expression
  • Embedded languages: XML in a doc comment, JSON in a fixture string and SQL in a query string are found inside the host language and highlighted in place, or named outright with a // lang=json hint comment
  • Theme-aware colors: by default the palette is picked per frame from the luminance of the ImGui window background, and unset palette entries (background, plain text, gutter) come from the active ImGui theme, so code keeps matching the surrounding UI
  • Line numbers: an optional right-aligned gutter that does not shift the code column as the digit count grows
  • Cached tokenization: the static Render caches by source text, and HighlightedCode tokenizes once for hot render paths
  • Tokens without rendering: Highlight returns the classified runs for callers that want to draw, export, or test them themselves
  • Markdown integration: pairs with ktsu.ImGui.Markdown's CodeBlockRenderer hook to highlight fenced code blocks, with neither library depending on the other

Installation

dotnet add package ktsu.ImGui.SyntaxHighlighting

Quick Start

Static render (cached by source)

ImGuiSyntaxHighlighting.Render tokenizes the given code and caches the result keyed by the source text, language and tab width, so calling it every frame with the same code does not re-tokenize it.

using ktsu.ImGui.SyntaxHighlighting;
using Hexa.NET.ImGui;

ImGui.Begin("Code");
ImGuiSyntaxHighlighting.Render("""
    /// <summary>Greets the world.</summary>
    public static void Main()
    {
        Console.WriteLine("Hello, ImGui");
    }
    """, "csharp");
ImGui.End();

The doc comment's tags in that snippet are highlighted as XML while its prose stays comment-colored — see embedded languages for what is recognized and how to change it.

HighlightedCode for hot paths

When the same source is rendered every frame, tokenize it once and render that instance instead of relying on the source-keyed cache. HighlightedCode comes from ktsu.SyntaxHighlighting; Render is an extension this package adds to it.

private static readonly HighlightedCode Snippet = new("SELECT * FROM users;", "sql");

// In the render loop:
Snippet.Render();

Tokens without rendering

Highlight forwards to SyntaxHighlighter.Highlight, so a caller with no ImGui context can reference ktsu.SyntaxHighlighting alone and skip this package entirely.

foreach (HighlightedLine line in ImGuiSyntaxHighlighting.Highlight(source, "python"))
{
    foreach (HighlightedToken token in line.Tokens)
    {
        Console.WriteLine($"{token.Kind}: {token.Text}");
    }
}

Configuration

SyntaxHighlightConfig is a record; every member is optional.

SyntaxHighlightConfig config = new()
{
    ShowLineNumbers = true,
    FirstLineNumber = 1,
    TabWidth = 4,
    Theme = null,                  // null follows the ImGui theme; or SyntaxTheme.Dark / .Light
    FontResolver = size => monoFont,
    ShowBackground = true,
    BackgroundRounding = 3.0f,
    PaddingPixels = 6.0f,
    LineSpacingPixels = 2.0f,
    GutterSpacingPixels = 10.0f,
    FontSizePixels = null,         // null keeps the current size, so DPI scaling is followed
    Width = null,                  // null uses the available content width; the block widens to its longest line
};

Code is never wrapped. A block is as wide as its longest line, or as Width if that is wider, so inside a child window opened with ImGuiWindowFlags.HorizontalScrollbar the end of a long line can be scrolled to; outside one, the window clips it.

Only the lines inside the window's clip rectangle are measured and drawn each frame, so a long file in a scrolling child costs what is on screen. The width of the widest line is measured once per block and font and kept.

Themes

SyntaxTheme holds one color per TokenKind as a semantic ktsu.Semantics.Color.Color. SyntaxTheme.Dark and SyntaxTheme.Light are the built-ins, and any theme can be derived with a with expression:

SyntaxTheme theme = SyntaxTheme.Dark with
{
    Comment = Color.FromHex("#7f848e"),
    Keyword = Color.FromHex("#c678dd"),
};

Leaving Background, Plain or LineNumber unset makes the renderer take them from the ImGui theme (FrameBg, Text and TextDisabled).

Registering a language

Definitions live in ktsu.SyntaxHighlighting, and a language is plain data, so nothing needs to be subclassed:

LanguageRegistry.Register(new LanguageDefinition
{
    Name = "ini",
    Aliases = ["conf", "cfg"],
    LineComments = [new LineCommentRule { Prefix = ";" }],
    Strings = [new StringRule { Open = "\"", Close = "\"" }],
    Constants = ["true", "false", "yes", "no"],
    HighlightPropertyNames = true,
    HighlightFunctionCalls = false,
});

Unknown language names never throw — they fall back to plain text, since the name usually comes from a markdown fence or a user-selected file.

Highlighting markdown code blocks

ktsu.ImGui.Markdown exposes a CodeBlockRenderer hook that receives a fence's info string and its text. Pointing it at this package highlights fenced code without either library depending on the other:

MarkdownConfig markdown = new()
{
    CodeBlockRenderer = (language, code) =>
        ImGuiSyntaxHighlighting.Render(code, language ?? "text", highlightConfig),
};

Limitations

  • Highlighting is lexical, not semantic: user-defined type names are not distinguished from other identifiers, and a call is recognized by the ( that follows it
  • Embedded languages are found in comments and strings only, one level deep — script and style bodies inside HTML are still treated as markup text
  • Lines are not wrapped, and there is no built-in scrolling, selection, or editing; this renders code, it is not a text editor

Demo

See examples/ImGuiSyntaxHighlightingDemo/ for a runnable demo covering the language samples, the line-number gutter, palette switching, and markdown code blocks.

dotnet run --project examples/ImGuiSyntaxHighlightingDemo

Acknowledgments

  • ktsu.SyntaxHighlighting - The renderer-agnostic tokenizer, languages and themes this draws
  • Dear ImGui - The immediate mode GUI library this draws into
  • Hexa.NET.ImGui - The .NET bindings for Dear ImGui that this package is built on
  • ktsu.Semantics - The Color type each theme entry is held as, converted at the ImGui seam by ktsu.ImGui.Color

Contributing

Contributions are welcome! For feature requests, bug reports, or questions, please open an issue on the GitHub repository. If you would like to contribute code, please open a pull request with your changes.

License

ImGui.SyntaxHighlighting is licensed under the MIT License. See LICENSE.md for more information.

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
3.79.1-pre.3 51 10/28/2026
3.79.1-pre.2 58 10/27/2026
3.79.1-pre.1 63 10/26/2026
3.79.0 115 10/26/2026
3.78.3 103 10/25/2026
3.78.2 106 10/24/2026
3.78.1 107 10/24/2026
3.78.0 107 10/22/2026
3.77.3 113 10/21/2026
3.77.2 91 10/21/2026
3.77.1 122 10/21/2026
3.77.0 104 10/20/2026
3.76.1 100 10/20/2026
3.76.0 94 10/20/2026
3.75.4 290 10/19/2026
3.75.3 111 10/18/2026
3.75.2 118 10/17/2026
3.75.2-pre.1 66 10/16/2026
3.75.1 119 10/14/2026
3.75.0 120 10/12/2026
Loading failed

## v3.79.0 (minor)

Changes since v3.78.0:

- Size text fields from their value in managed code, with no native buffer (Claude)
- Grow every text field's buffer with its text instead of giving it a fixed capacity (Claude)
- Give every DividerContainer zone the same gap, whatever the zone count or layout (Claude)
- Let StickyHeaderList's pinned header take the pointer from the rows beneath it (Claude)
- Keep a TabPanel's tab across a hidden strip and tab removal (Claude)
- [patch] Keep a value slider's minus sign readable in every culture and font (Claude)
- [patch] Apply a window icon set after launch again once the window shows (Claude)
- [patch] Reopen a window saved maximized as maximized (#725) (matt-edmondson)
- [patch] Reopen a window saved maximized as maximized (Claude)