Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
278ac37
perf: UTF-8 batch mode + Utf8Buffer eliminates char[] to UTF8 conversion
liuqihonggit Aug 26, 2026
2104cbd
fix: merge upstream #5633 skip-clean-runs with Utf8Buffer
liuqihonggit Aug 26, 2026
470c6b2
fix: CountingOutput override Write(ReadOnlySpan<byte>) for Utf8Buffer…
liuqihonggit Aug 26, 2026
732bfef
fix: address Copilot review comments on PR #5650
liuqihonggit Aug 27, 2026
6b8516e
fix: address Copilot review comments from PR #5651 (shared with #5650)
liuqihonggit Aug 27, 2026
09da5e7
Fix timeout callback queue locking
harder Aug 31, 2026
16c971a
Track active timeout occurrences individually
harder Sep 1, 2026
2513f6d
Aggregate pending timer callback exceptions
harder Sep 1, 2026
4387f67
Simplify timer runner and cancellation semantics
harder Sep 1, 2026
6103007
Document cancellation state and pin in-flight Remove contract
harder Sep 1, 2026
cabd60d
Bound timer passes and harden timeout APIs
harder Sep 2, 2026
d5507b1
Prevent repeaters from consuming peer timer slots
harder Sep 2, 2026
c8a3ead
Raise Added outside the occurrence-completion finally
harder Sep 2, 2026
5bf212b
Remove unreachable exception-ordering contract
harder Sep 2, 2026
6a43661
Document active RemoveTimeout cancellation
harder Sep 2, 2026
986c7db
Keep timer extension points outside queue lock
harder Sep 2, 2026
3f96910
Test cross-thread invoke during nested timer run
harder Sep 2, 2026
ddb2be4
Skip time reads for empty timer passes
harder Sep 2, 2026
8de9e59
Prevent timer regressions from hanging tests
harder Sep 2, 2026
a093d36
Fix nested paste focus after application begin
invalid-email-address Sep 4, 2026
663f962
Bump Microsoft.Extensions.Configuration and Microsoft.Extensions.Conf…
dependabot[bot] Sep 9, 2026
3d551b2
Bump Microsoft.Extensions.Options from 10.0.11 to 10.0.12
dependabot[bot] Sep 9, 2026
5404c03
Bump Microsoft.NET.Test.Sdk from 18.9.0 to 18.10.0
dependabot[bot] Sep 9, 2026
b4cc493
Merge pull request #5674 from tui-cs/backmerge/v2.5.0
tig Sep 11, 2026
baaed25
Fixes #5675. MenuBar overrides DefaultBorderStyle
BDisp Sep 13, 2026
71db96d
Delete Examples/UICatalog/Scenarios/CustomMenuBarBorderStyle.cs
BDisp Sep 13, 2026
6509960
Add the correct unit test file
BDisp Sep 13, 2026
555858b
Bump xunit.v3 from 4.0.0 to 4.0.1
dependabot[bot] Sep 14, 2026
1d3504e
Merge pull request #5676 from BDisp/fix/5675-menubar_overrides-defaul…
tig Sep 14, 2026
48f863b
Merge pull request #5650 from liuqihonggit/pr/utf8-batch-mode
tig Sep 14, 2026
8b986b1
Merge pull request #5655 from harder/fix/5652-timed-events-locking
tig Sep 14, 2026
ce95ec4
Merge pull request #5663 from elkampu/elkampu/fix-nested-paste-focus-…
tig Sep 14, 2026
7e382c4
Merge pull request #5668 from tui-cs/dependabot/nuget/multi-0f1dc55064
tig Sep 14, 2026
2dd6e68
Merge pull request #5670 from tui-cs/dependabot/nuget/Microsoft.Exten…
tig Sep 14, 2026
dbc3ae8
Merge pull request #5671 from tui-cs/dependabot/nuget/Microsoft.NET.T…
tig Sep 14, 2026
970f4fa
Merge pull request #5679 from tui-cs/dependabot/nuget/xunit.v3-4.0.1
tig Sep 14, 2026
f3658ca
Bump Microsoft.Extensions.Configuration.Json from 10.0.11 to 10.0.12
dependabot[bot] Sep 15, 2026
9fa111e
Merge pull request #5681 from tui-cs/dependabot/nuget/Microsoft.Exten…
tig Sep 15, 2026
3cc1ac8
Bump Microsoft.NET.Test.Sdk from 18.10.0 to 18.10.1 (#5682)
dependabot[bot] Sep 16, 2026
22ef38a
Bump Markdig from 1.3.2 to 1.4.0 (#5685)
dependabot[bot] Sep 21, 2026
40215da
fix(listview): sync navigator on source changes (#5684)
YourRobotOverlord Sep 21, 2026
ff43d04
Bump Xunit.Combinatorial from 2.1.41 to 2.1.43 (#5686)
dependabot[bot] Sep 28, 2026
33c72a1
Bump Moq from 4.20.72 to 4.21.0 (#5688)
dependabot[bot] Sep 28, 2026
12489df
Bump TestableIO.System.IO.Abstractions.TestingHelpers from 22.2.0 to …
dependabot[bot] Sep 28, 2026
02236a1
Fixes #5695. Harden UTF-8 output rendering
harder Sep 30, 2026
d06b893
Preserve legacy output hooks and recover failed frames
harder Sep 30, 2026
7f85fc0
Address Claude review: recover output failures and bound encoding all…
harder Sep 30, 2026
4cde18e
Harden output failure paths and remove legacy hook quadratic cost
harder Oct 1, 2026
77d686a
Let DriverImpl own output failure logging
harder Oct 1, 2026
c44042b
Apply output retry backoff to every Refresh
harder Oct 1, 2026
413e7ec
Merge pull request #5696 from harder/fix/5695-complete-output
harder Oct 3, 2026
7fba245
feat(analyzers): add Terminal.Gui.Analyzers package to catch v1 API h…
omm-prakash18 Oct 4, 2026
ce910cf
fix(analyzers): resolve RS1038, CS9208, and CS8600 warnings and confi…
omm-prakash18 Oct 5, 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
2 changes: 1 addition & 1 deletion .github/workflows/perf-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
--configuration Release \
--no-build \
-- \
--filter '*Scroll*' '*Config*' '*Scheme*' '*Theme*' \
--filter '*Scroll*' '*Config*' '*Scheme*' '*Theme*' '*OutputWriteBenchmark*' '*UnixRawOutputBenchmark*' \
--job short \
--exporters json \
--artifacts ./BenchmarkResults
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,9 @@ artifacts/
docfx/artifacts/
local_packages/
*.cast

# Graphic memory & plan markdown files
GRAPHIC_MEMORY.md
plans/
*.skill.md

27 changes: 15 additions & 12 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
</PropertyGroup>
<ItemGroup>
<!-- Enable Nuget Source Link for github -->
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="5.9.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.14.0" />
Expand All @@ -13,21 +15,22 @@
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.203" />
<PackageVersion Include="Microsoft.CodeAnalysis" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.9.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.11" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />

<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.12" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.12" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.12" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.12" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.7" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.7" />
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
<PackageVersion Include="Spectre.Console" Version="0.57.2" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="22.2.0" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="22.3.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="4.0.0" />
<PackageVersion Include="xunit.v3" Version="4.0.0" />
<PackageVersion Include="Xunit.Combinatorial" Version="2.1.41" />
<PackageVersion Include="xunit.v3" Version="4.0.1" />
<PackageVersion Include="Xunit.Combinatorial" Version="2.1.43" />
<PackageVersion Include="System.IO.Abstractions" Version="22.2.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.7" />
<PackageVersion Include="Wcwidth" Version="4.0.1" />
Expand All @@ -37,7 +40,7 @@
<PackageVersion Include="ColorHelper" Version="1.8.1" />
<PackageVersion Include="TextMateSharp" Version="2.0.4" />
<PackageVersion Include="TextMateSharp.Grammars" Version="2.0.4" />
<PackageVersion Include="Markdig" Version="1.3.2" />
<PackageVersion Include="Markdig" Version="1.4.0" />
<PackageVersion Include="Serilog" Version="4.4.0" />
<PackageVersion Include="Serilog.Extensions.Logging" Version="10.0.0" />
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
Expand All @@ -49,7 +52,7 @@
<PackageVersion Include="ReactiveUI" Version="23.2.27" />
<PackageVersion Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" />
<PackageVersion Include="ReactiveUI.SourceGenerators" Version="2.6.30" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Moq" Version="4.21.0" />
<PackageVersion Include="ReportGenerator" Version="5.5.9" />
<PackageVersion Include="coverlet.collector" Version="10.0.0" />
<PackageVersion Include="GitVersion.MsBuild" Version="6.8.2" />
Expand Down
24 changes: 24 additions & 0 deletions Terminal.Gui.Analyzers/Terminal.Gui.Analyzers.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<!-- Roslyn Analyzers must target netstandard2.0 for MSBuild and Visual Studio compatibility -->
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>Latest</LangVersion>
<Nullable>enable</Nullable>
<RootNamespace>Terminal.Gui.Analyzers</RootNamespace>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<IsRoslynComponent>true</IsRoslynComponent>
<NoWarn>$(NoWarn);RS2008;RS1032;RS1038</NoWarn>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
</ItemGroup>

</Project>
108 changes: 108 additions & 0 deletions Terminal.Gui.Analyzers/V1ApiCodeFixProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System.Collections.Immutable;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Terminal.Gui.Analyzers
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(V1ApiCodeFixProvider)), Shared]
public class V1ApiCodeFixProvider : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(new[] {
V1ApiDiagnosticAnalyzer.RuleClicked.Id,
V1ApiDiagnosticAnalyzer.RuleToplevel.Id,
V1ApiDiagnosticAnalyzer.RuleBounds.Id,
V1ApiDiagnosticAnalyzer.RuleTabView.Id,
V1ApiDiagnosticAnalyzer.RuleRadioGroup.Id,
V1ApiDiagnosticAnalyzer.RuleAcceptingIgnoresArgs.Id });

public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
if (root == null)
{
return;
}

foreach (var diagnostic in context.Diagnostics)
{
var diagnosticSpan = diagnostic.Location.SourceSpan;
var token = root.FindToken(diagnosticSpan.Start);

if (diagnostic.Id == V1ApiDiagnosticAnalyzer.RuleClicked.Id)
{
context.RegisterCodeFix(
CodeAction.Create(
title: "Replace with 'Accepted'",
createChangedDocument: c => ReplaceTokenAsync(context.Document, root, token, "Accepted", c),
equivalenceKey: "UseAccepted"),
diagnostic);
}
else if (diagnostic.Id == V1ApiDiagnosticAnalyzer.RuleBounds.Id)
{
context.RegisterCodeFix(
CodeAction.Create(
title: "Replace with 'Viewport'",
createChangedDocument: c => ReplaceTokenAsync(context.Document, root, token, "Viewport", c),
equivalenceKey: "UseViewport"),
diagnostic);
}
else if (diagnostic.Id == V1ApiDiagnosticAnalyzer.RuleToplevel.Id)
{
context.RegisterCodeFix(
CodeAction.Create(
title: "Replace with 'Window'",
createChangedDocument: c => ReplaceTokenAsync(context.Document, root, token, "Window", c),
equivalenceKey: "UseWindow"),
diagnostic);
}
else if (diagnostic.Id == V1ApiDiagnosticAnalyzer.RuleTabView.Id)
{
context.RegisterCodeFix(
CodeAction.Create(
title: "Replace with 'Tabs'",
createChangedDocument: c => ReplaceTokenAsync(context.Document, root, token, "Tabs", c),
equivalenceKey: "UseTabs"),
diagnostic);
}
else if (diagnostic.Id == V1ApiDiagnosticAnalyzer.RuleRadioGroup.Id)
{
context.RegisterCodeFix(
CodeAction.Create(
title: "Replace with 'OptionSelector'",
createChangedDocument: c => ReplaceTokenAsync(context.Document, root, token, "OptionSelector", c),
equivalenceKey: "UseOptionSelector"),
diagnostic);
}
else if (diagnostic.Id == V1ApiDiagnosticAnalyzer.RuleAcceptingIgnoresArgs.Id)
{
var node = root.FindNode(diagnosticSpan);
if (node is AssignmentExpressionSyntax assignment && assignment.Left is MemberAccessExpressionSyntax memberAccess)
{
var eventToken = memberAccess.Name.Identifier;
context.RegisterCodeFix(
CodeAction.Create(
title: "Switch event to 'Accepted'",
createChangedDocument: c => ReplaceTokenAsync(context.Document, root, eventToken, "Accepted", c),
equivalenceKey: "SwitchToAccepted"),
diagnostic);
}
}
}
}

private static Task<Document> ReplaceTokenAsync(Document document, SyntaxNode root, SyntaxToken oldToken, string newName, CancellationToken cancellationToken)
{
var newToken = SyntaxFactory.Identifier(oldToken.LeadingTrivia, newName, oldToken.TrailingTrivia);
var newRoot = root.ReplaceToken(oldToken, newToken);
return Task.FromResult(document.WithSyntaxRoot(newRoot));
}
}
}
Loading
Loading