Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c700d81
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
c511c14
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
eef1267
Initial plan
Copilot Apr 20, 2026
002fcb6
Fix MarkdownCodeBlock rendering codeblocks with incorrect background …
Copilot Apr 20, 2026
9b04c9b
Merge branch 'develop' into copilot/fix-markdown-codeblock-background
tig Apr 20, 2026
6c77b70
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
c743916
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
95a095b
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
83fe8f7
Merge branch 'develop' into copilot/fix-markdown-codeblock-background
tig Apr 20, 2026
0854803
Merge branch 'copilot/fix-markdown-codeblock-background' of github.co…
tig Apr 20, 2026
10e1773
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
033a494
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
f11f46b
Merge branch 'develop' of github.com:gui-cs/Terminal.Gui into develop
tig Apr 20, 2026
9fc2f9e
Fix Markdown code block background and highlighter logic
tig Apr 20, 2026
909ace4
Merge branch 'develop' into copilot/fix-markdown-codeblock-background
tig Apr 20, 2026
86f541a
fixed gitversion yml bug
tig Apr 20, 2026
83082d8
Fix SyntaxHighlighter/UseThemeBackground setters to invalidate layout
tig Apr 20, 2026
f2cfae4
Default UseThemeBackground to true
tig Apr 20, 2026
b3a01ae
Add ThemeName property to ISyntaxHighlighter interface
tig Apr 20, 2026
8aeb7ad
Auto-select syntax theme based on terminal background
tig Apr 20, 2026
3e9ddc4
Fix code block dimmer direction for light themes
tig Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Examples/UICatalog/Scenarios/Deepdives.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public override void Main ()

_markdownView = new Markdown
{
Width = Dim.Fill (), Height = Dim.Fill (), SyntaxHighlighter = new TextMateSyntaxHighlighter (ThemeName.Abbys), UseThemeBackground = true
Width = Dim.Fill (), Height = Dim.Fill (), SyntaxHighlighter = new TextMateSyntaxHighlighter (ThemeName.Abbys)
};

_markdownView.ViewportSettings |= ViewportSettingsFlags.HasHorizontalScrollBar;
Expand Down Expand Up @@ -134,7 +134,7 @@ public override void Main ()

Shortcut themeShortcut = new () { Text = "_Theme:", CommandView = themeDropDown, MouseHighlightStates = MouseState.None };

CheckBox themeBgCheckBox = new () { Text = "Theme _BG", Value = CheckState.UnChecked };
CheckBox themeBgCheckBox = new () { Text = "Theme _BG", Value = _markdownView.UseThemeBackground ? CheckState.Checked : CheckState.UnChecked };

themeBgCheckBox.ValueChanged += (_, e) =>
{
Expand Down
16 changes: 11 additions & 5 deletions Examples/UICatalog/Scenarios/MarkdownTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ public override void Main ()
using IApplication app = Application.Create ();
app.Init ();

Window window = new () { Title = "Markdown Tester", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.None };
Window window = new ()
{
Title = "Markdown Tester",
Width = Dim.Fill (),
Height = Dim.Fill (),
BorderStyle = LineStyle.None,
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Accent)
};

// --- Source editor (top half) ---
FrameView editorFrame = new ()
Expand All @@ -24,7 +31,7 @@ public override void Main ()
X = 0,
Y = 0,
Width = Dim.Fill (),
Height = Dim.Percent (40)
Height = Dim.Percent (40),
};
editorFrame.Border.Thickness = new Thickness (0, 2, 0, 0);

Expand Down Expand Up @@ -59,8 +66,7 @@ public override void Main ()
Width = Dim.Fill (),
Height = Dim.Fill (),
Text = Markdown.DefaultMarkdownSample,
SyntaxHighlighter = new TextMateSyntaxHighlighter (),
UseThemeBackground = true
SyntaxHighlighter = new TextMateSyntaxHighlighter ()
};

previewFrame.Add (preview);
Expand Down Expand Up @@ -88,7 +94,7 @@ public override void Main ()

Shortcut themeShortcut = new () { Title = "Theme", CommandView = themeDropDown };

CheckBox themeBgCheckBox = new () { Text = "Theme _BG", Value = CheckState.UnChecked };
CheckBox themeBgCheckBox = new () { Text = "Theme _BG", Value = preview.UseThemeBackground ? CheckState.Checked : CheckState.UnChecked };

themeBgCheckBox.ValueChanged += (_, e) =>
{
Expand Down
6 changes: 3 additions & 3 deletions GitVersion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# - develop: Develop branch for V2
#
# Package Naming:
# - from develop: 2.1.0-develop.1 (minor version increments)
# - from develop: 2.0.0-develop.1 (patch version increments)
# - from main (pre-release): 2.0.0-prealpha.1 or 2.0.0-beta.1
# - from main (release): 2.0.0 (patch version increments)
#
Expand Down Expand Up @@ -46,8 +46,8 @@ branches:
regex: develop
# Adds 'develop' as pre-release label (e.g., 2.1.0-develop.1)
label: develop
# Increments minor version (x.y+1.z) on commits
increment: Minor
# Increments patch version (x.y.z+1) on commits
increment: Patch
Comment thread
tig marked this conversation as resolved.
# No source branches specified as this is the root of development
source-branches: []
# Indicates this branch feeds into release branches
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/Markdown/MarkdownCodeBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ protected override bool OnDrawingContent (DrawContext? context)

foreach (StyledSegment segment in segments)
{
Attribute attr = MarkdownAttributeHelper.GetAttributeForSegment (this, segment, SyntaxHighlighter);
Attribute attr = MarkdownAttributeHelper.GetAttributeForSegment (this, segment, SyntaxHighlighter, codeBg);
SetAttribute (attr);

foreach (string grapheme in GraphemeHelper.GetGraphemes (segment.Text))
Expand Down
3 changes: 2 additions & 1 deletion Terminal.Gui/Views/Markdown/MarkdownView.Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ private void SyncCodeBlockViews ()

MarkdownCodeBlock codeBlock = new ()
{
SyntaxHighlighter = SyntaxHighlighter,
ThemeBackground = SyntaxHighlighter?.DefaultBackground,
StyledLines = codeLines,
X = 0,
Y = start,
Width = Dim.Fill (),
ThemeBackground = UseThemeBackground ? SyntaxHighlighter?.DefaultBackground : null,
ShowCopyButton = ShowCopyButtons
Comment thread
tig marked this conversation as resolved.
};

Expand Down
271 changes: 271 additions & 0 deletions Tests/UnitTestsParallelizable/Views/Markdown/MarkdownViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,4 +1350,275 @@ Middle text.
}

#endregion

#region CodeBlock background attribute tests

// Copilot

[Fact]
public void UseThemeBackground_True_CodeBlock_Uses_Theme_Background ()
{
// Copilot
// When UseThemeBackground is true, the code block should use the highlighter's
// DefaultBackground — matching the theme, not the dark VisualRole.Code background.
IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (20, 6);

Color themeBg = new (30, 30, 30);
ThemeBackgroundHighlighter highlighter = new (themeBg);

Runnable window = new () { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.None };
window.SetScheme (new Scheme (new Attribute (Color.White, Color.Blue)));

Terminal.Gui.Views.Markdown mv = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
SyntaxHighlighter = highlighter,
UseThemeBackground = true,
Text = "Hello\n\n```\ncode\n```"
};
mv.SetScheme (new Scheme (new Attribute (Color.White, Color.Blue)));
window.Add (mv);

app.Begin (window);
app.LayoutAndDraw ();

Cell [,]? contents = app.Driver.Contents;
Assert.NotNull (contents);

// Row 2 = code block line "code" — should use theme background
Color codeBg = contents! [2, 0].Attribute!.Value.Background;
Assert.Equal (themeBg, codeBg);

Comment thread
tig marked this conversation as resolved.
Outdated
window.Dispose ();
app.Dispose ();
}
Comment thread
tig marked this conversation as resolved.
Outdated

[Fact]
public void UseThemeBackground_False_CodeBlock_Text_Matches_Fill_Background ()
{
// Copilot
// When UseThemeBackground is false, the code block text segments should use
// the same background as the code block fill (Code role background).
IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (20, 6);

Runnable window = new () { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.None };
window.SetScheme (new Scheme (new Attribute (Color.White, Color.Blue)));

Terminal.Gui.Views.Markdown mv = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
UseThemeBackground = false,
Text = "Hello\n\n```\ncode\n```"
};
mv.SetScheme (new Scheme (new Attribute (Color.White, Color.Blue)));
window.Add (mv);

app.Begin (window);
app.LayoutAndDraw ();

Cell [,]? contents = app.Driver.Contents;
Assert.NotNull (contents);

// Row 2 = code block line "code"
// The text cell (col 0, 'c') background should match the fill cell (col 10, empty) background
Color textBg = contents! [2, 0].Attribute!.Value.Background;
Color fillBg = contents [2, 10].Attribute!.Value.Background;

Assert.Equal (textBg, fillBg);

// The code block background should also differ from the main content background
Color mainBg = contents [0, 0].Attribute!.Value.Background;
Assert.NotEqual (mainBg, textBg);

window.Dispose ();
app.Dispose ();
}

[Fact]
public void CodeBlock_Uses_Highlighter_DefaultBackground_When_UseThemeBackground_True ()
{
// Copilot
// When UseThemeBackground is true and a SyntaxHighlighter is set,
// the MarkdownCodeBlock SubViews must use the highlighter's DefaultBackground
// as their ThemeBackground — NOT the VisualRole.Code dark background.
// This is the bug: with a light theme (e.g., atomonelight), the code block
// background is dark because ThemeBackground is never set on the code block views.
IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (30, 10);

Color themeBg = new (250, 250, 250); // Light theme background
ThemeBackgroundHighlighter highlighter = new (themeBg);

Runnable window = new () { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.None };
window.SetScheme (new Scheme (new Attribute (Color.Black, Color.White)));

Terminal.Gui.Views.Markdown mv = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
SyntaxHighlighter = highlighter,
UseThemeBackground = true,
Text = "Hello\n\n```csharp\nvar x = 1;\n```"
};
mv.SetScheme (new Scheme (new Attribute (Color.Black, Color.White)));
window.Add (mv);

app.Begin (window);
app.LayoutAndDraw ();

// Find the MarkdownCodeBlock SubView
MarkdownCodeBlock? codeBlockView = null;

foreach (View sub in mv.SubViews)
{
if (sub is not MarkdownCodeBlock cb)
{
continue;
}
codeBlockView = cb;

break;
}

Assert.NotNull (codeBlockView);

// The code block's ThemeBackground must be set to the highlighter's DefaultBackground
Assert.Equal (themeBg, codeBlockView.ThemeBackground);

// Verify the rendered code block background matches the theme background
Cell [,]? contents = app.Driver.Contents;
Assert.NotNull (contents);

// Row 2 = code block line "var x = 1;"
Color codeBg = contents! [2, 0].Attribute!.Value.Background;
Assert.Equal (themeBg, codeBg);

window.Dispose ();
app.Dispose ();
}

[Fact]
public void CodeBlock_Uses_Highlighter_DefaultBackground_When_UseThemeBackground_False ()
{
// Copilot
// Even when UseThemeBackground is false, if a SyntaxHighlighter is set,
// the MarkdownCodeBlock SubViews should use the highlighter's DefaultBackground
// for their code block background (just like standalone MarkdownCodeBlock does
// via the CodeLines setter). The code block should NOT use VisualRole.Code
// when a highlighter provides a DefaultBackground.
IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (30, 10);

Color themeBg = new (250, 250, 250); // Light theme background
ThemeBackgroundHighlighter highlighter = new (themeBg);

Runnable window = new () { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.None };
window.SetScheme (new Scheme (new Attribute (Color.Black, Color.White)));

Terminal.Gui.Views.Markdown mv = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
SyntaxHighlighter = highlighter,
UseThemeBackground = false,
Text = "Hello\n\n```csharp\nvar x = 1;\n```"
};
mv.SetScheme (new Scheme (new Attribute (Color.Black, Color.White)));
window.Add (mv);

app.Begin (window);
app.LayoutAndDraw ();

// Find the MarkdownCodeBlock SubView
MarkdownCodeBlock? codeBlockView = null;

foreach (View sub in mv.SubViews)
{
if (sub is not MarkdownCodeBlock cb)
{
continue;
}
codeBlockView = cb;

break;
}

Assert.NotNull (codeBlockView);

// The code block's ThemeBackground must be the highlighter's DefaultBackground
Assert.Equal (themeBg, codeBlockView.ThemeBackground);

// Verify the rendered code block background matches the theme background
Cell [,]? contents = app.Driver.Contents;
Assert.NotNull (contents);

// Row 2 = code block line
Color codeBg = contents! [2, 0].Attribute!.Value.Background;
Assert.Equal (themeBg, codeBg);

Comment thread
tig marked this conversation as resolved.
Outdated
window.Dispose ();
app.Dispose ();
}

[Fact]
public void CodeBlock_SyntaxHighlighter_Is_Passed_To_SubView ()
{
// Copilot
// The MarkdownCodeBlock SubViews created by SyncCodeBlockViews must receive
// the parent Markdown view's SyntaxHighlighter so that GetAttributeForSegment
// can query the highlighter for scope-specific attributes.
IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (30, 10);

Color themeBg = new (250, 250, 250);
ThemeBackgroundHighlighter highlighter = new (themeBg);

Runnable window = new () { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.None };

Terminal.Gui.Views.Markdown mv = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
SyntaxHighlighter = highlighter,
UseThemeBackground = true,
Text = "```\ncode\n```"
};
window.Add (mv);

app.Begin (window);
app.LayoutAndDraw ();

// Find the MarkdownCodeBlock SubView
MarkdownCodeBlock? codeBlockView = null;

foreach (View sub in mv.SubViews)
{
if (sub is not MarkdownCodeBlock cb)
{
continue;
}
codeBlockView = cb;

break;
}

Assert.NotNull (codeBlockView);

// The code block must have the parent's SyntaxHighlighter set
Assert.Same (highlighter, codeBlockView.SyntaxHighlighter);

window.Dispose ();
app.Dispose ();
}

#endregion
}
Loading