Prepares for Fixing #4943 - Refactors ConfigurationManager to be based on MEC#5411
Conversation
Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/480c357e-92ff-437f-9f7a-074cbd72e0bf Co-authored-by: tig <585482+tig@users.noreply.github.com>
- Replace fabricated Driver.ForceMaxColors with actual Driver.SizeDetection - Replace FakeDriver/Fake with valid driver name 'ansi' - Replace fabricated theme names with actual: Default, Dark, Light, TurboPascal 5, Anders, Green Phosphor, Amber Phosphor - Fix Button.DefaultHighlightStyle -> Button.DefaultMouseHighlightStates - Fix CheckBox.DefaultCheckState -> CheckBox.DefaultMouseHighlightStates - Fix Dialog defaults: Heavy border (not Single), Transparent shadow (not Opaque), replace MinimumWidth/Height with ButtonAlignment/AlignmentModes - Fix MessageBox: has DefaultButtonAlignment not DefaultShadow, Heavy border - Fix Window.DefaultShadow: None (not Opaque, config.json overrides) - Remove fabricated MenuBar.UseKeysUpDownAsKeysLeftRight, add MenuBar.DefaultKey - Add missing properties: View.ViewKeyBindings, Color.Colors16, NerdFonts.Enable - Update attribute count from ~195 to ~188 - Record D-01 decision (Option 2: static facade) with rationale - Record D-02 decision (Option 3: support both formats, flat deprecated) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the Microsoft.Extensions.Configuration infrastructure alongside the existing ConfigurationManager (no removals, no breaking changes). New NuGet dependencies: - Microsoft.Extensions.Configuration - Microsoft.Extensions.Configuration.Binder - Microsoft.Extensions.Configuration.Json - Microsoft.Extensions.Options New Settings POCOs (Terminal.Gui/Configuration/Settings/): - ApplicationSettings (AppModel, ForceDriver, IsMouseDisabled) - DriverSettings (Force16Colors, SizeDetection) - ButtonSettings (DefaultShadow, DefaultMouseHighlightStates) - CheckBoxSettings (DefaultMouseHighlightStates) - DialogSettings (DefaultShadow, DefaultBorderStyle, DefaultButtonAlignment, DefaultButtonAlignmentModes) - MessageBoxSettings (DefaultBorderStyle, DefaultButtonAlignment) - WindowSettings (DefaultShadow, DefaultBorderStyle) - ViewBorderSettings (shared POCO for FrameView, HexView, Menu, etc.) Each POCO has a static Defaults facade (D-01 decision: Option 2) so that Views can be constructed before Application.Create() without DI. New infrastructure: - TuiConfigurationExtensions: AddTuiLibraryDefaults(), AddTuiAppDefaults(), AddTuiUserFiles(), AddTuiEnvironmentVariable(), AddTuiRuntimeConfig() - TuiConfigurationBuilder: Convenience class that builds the full MEC provider chain and applies config to static facades. Tests: 14 new tests in Tests/UnitTestsParallelizable covering POCOs, builder, extension methods, precedence, and static facade updates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create individual Settings POCO files for each view/component that needs configurable defaults via the MEC binding pattern: - MenuBarSettings, MenuSettings, PopoverMenuSettings - StatusBarSettings, FrameViewSettings, HexViewSettings - TextFieldSettings, TextViewSettings, SelectorBaseSettings - FileDialogStyleSettings, FileDialogSettings - LinearRangeSettings, CharMapSettings - NerdFontsSettings, KeySettings, TraceSettings, GlyphSettings Delete ViewBorderSettings.cs which combined multiple views in one class. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…OCOs All View/Driver/App static properties now delegate to their corresponding Settings POCO Defaults. The [ConfigurationProperty] attributes are preserved for CM backward compatibility during the transition. - 144 Glyph properties delegate to GlyphSettings.Defaults - 23 View/App properties delegate to their respective POCOs - TuiConfigurationBuilder.ApplyToStaticFacades() binds all 24 sections - Complex types (ThemeManager, SchemeManager, key bindings, Color.Colors16) deferred to Phase 3/4 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tations - IThemeManager interface with SwitchTheme(), CurrentThemeName, ThemeNames - ISchemeManager interface with GetScheme(), AddScheme(), SchemeNames - MecThemeManager delegates to existing ThemeManager during transition - MecSchemeManager delegates to existing SchemeManager during transition - ThemeSettings POCO tracks active theme name - TuiConfigurationBuilder exposes ThemeManager/SchemeManager properties - 9 new tests covering interface implementations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…wire MEC startup - Removed [ConfigurationProperty] from ~174 properties now backed by MEC POCOs - Kept [ConfigurationProperty] on 8 complex properties still managed by CM (ThemeManager.Themes/Theme, SchemeManager.Schemes, key bindings, Color.Colors16, ConfigurationManager.AppSettings/ThrowOnJsonErrors) - Wired MEC into application startup via ModuleInitializers.cs - Cleaned ConfigPropertyHostTypes to only list types still using CM - Updated ScopeJsonConverter to skip unknown properties gracefully - All 17,110 tests pass (0 failures) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tingsScope - Mark AppSettingsScope as [Obsolete] with migration guidance - Add BindAppSettings<T>() method to TuiConfigurationBuilder for app POCOs - Comprehensive XML doc examples on TuiConfigurationBuilder - 4 new tests demonstrating the app-developer workflow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ConfigurationManager marked [Obsolete] with migration guidance - ConfigProperty, ConfigPropertyHostTypes, SettingsScope, ThemeScope marked [Obsolete] - ConfigurationPropertyAttribute marked [Obsolete] - Targeted #pragma warning disable CS0618 in 27 internal files that still reference obsolete types during transition - Public MEC APIs remain clean (no obsolete markers) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Re-adds [ConfigurationProperty (Scope = typeof (ThemeScope))] and [ConfigurationProperty (Scope = typeof (SettingsScope))] attributes to static properties that delegate to POCO settings. These attributes are needed for backward compatibility with existing ConfigurationManager tests and theme/settings serialization discovery. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…verter - Restore full ConfigPropertyHostTypes (29 types) for CM reflection scan - Restore [ConfigurationProperty] on all 144 Glyphs.cs properties - Revert ScopeJsonConverter to throw on unknown properties (fixes test cascade) - Add [UnconditionalSuppressMessage] for IL2026/IL3050 on MEC binder methods - Add IL3050 to NoWarn in csproj alongside IL2026 - Restore removed InlineData test cases in ScopeJsonConverterTests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Cloner In NativeAOT, Activator.CreateInstance fails for dictionary types whose constructors are trimmed. The JSON serialization path (which uses source-generated code) is AOT-safe but was guarded by 'comparer is null', preventing it from being used when dictionaries have default comparers. Remove the guard so the JSON path is always attempted first, plus add explicit typed paths for Dictionary<Command, PlatformKeyBinding> and Dictionary<string, Dictionary<Command, PlatformKeyBinding>>. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4e59e6e to
1711f21
Compare
There was a problem hiding this comment.
Pull request overview
This PR advances the CM→MEC migration by introducing Microsoft.Extensions.Configuration-based configuration building and a set of Settings POCO “Defaults” facades, then rewiring many existing static configuration properties to read/write through those POCOs while marking legacy CM types obsolete during the transition.
Changes:
- Add MEC foundation:
TuiConfigurationBuilder+TuiConfigurationExtensions, plus newIThemeManager/ISchemeManagerinterfaces with MEC-backed implementations. - Introduce Settings POCOs (Application/Driver/Glyphs/etc.) with static
Defaultsfacades and update numerous view/static defaults to delegate to them. - Add/adjust unit tests and update package references to include Microsoft.Extensions.Configuration/Options dependencies.
Reviewed changes
Copilot reviewed 86 out of 86 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| Tests/UnitTestsParallelizable/Configuration/SourcesManagerTests.cs | Updates existing CM SourcesManager tests to use a different SettingsScope key. |
| Tests/UnitTestsParallelizable/Configuration/MecThemeTests.cs | Adds tests for MEC-backed theme/scheme manager interfaces. |
| Tests/UnitTestsParallelizable/Configuration/MecSettingsTests.cs | Adds tests for Settings POCO defaults and TuiConfigurationBuilder/extensions behavior. |
| Tests/UnitTestsParallelizable/Configuration/MecAppSettingsTests.cs | Adds tests for app-developer POCO binding via BindAppSettings<T>(). |
| Terminal.Gui/Views/Window.cs | Routes Window theme defaults through WindowSettings.Defaults. |
| Terminal.Gui/Views/TextInput/TextView/TextView.cs | Routes TextView cursor default through TextViewSettings.Defaults. |
| Terminal.Gui/Views/TextInput/TextField/TextField.cs | Routes TextField cursor default through TextFieldSettings.Defaults. |
| Terminal.Gui/Views/StatusBar.cs | Routes StatusBar separator default through StatusBarSettings.Defaults and suppresses obsolete warnings during transition. |
| Terminal.Gui/Views/Selectors/SelectorBase.cs | Routes selector mouse-highlight defaults through SelectorBaseSettings.Defaults. |
| Terminal.Gui/Views/MessageBox.cs | Routes MessageBox visual defaults through MessageBoxSettings.Defaults. |
| Terminal.Gui/Views/Menu/PopoverMenu.cs | Routes PopoverMenu default key through PopoverMenuSettings.Defaults. |
| Terminal.Gui/Views/Menu/MenuBar.cs | Routes MenuBar default key/border defaults through MenuBarSettings.Defaults and suppresses obsolete warnings during transition. |
| Terminal.Gui/Views/Menu/Menu.cs | Routes Menu default border style through MenuSettings.Defaults and suppresses obsolete warnings during transition. |
| Terminal.Gui/Views/LinearRange/LinearRangeDefaults.cs | Routes LinearRange cursor defaults through LinearRangeSettings.Defaults. |
| Terminal.Gui/Views/HexView.cs | Routes HexView cursor defaults through HexViewSettings.Defaults. |
| Terminal.Gui/Views/FrameView.cs | Routes FrameView border defaults through FrameViewSettings.Defaults. |
| Terminal.Gui/Views/FileDialogs/FileDialogStyle.cs | Routes FileDialogStyle defaults through FileDialogStyleSettings.Defaults. |
| Terminal.Gui/Views/FileDialogs/FileDialog.cs | Routes FileDialog max search results through FileDialogSettings.Defaults. |
| Terminal.Gui/Views/Dialog.cs | Routes Dialog visual defaults through DialogSettings.Defaults. |
| Terminal.Gui/Views/CheckBox.cs | Routes CheckBox mouse-highlight defaults through CheckBoxSettings.Defaults. |
| Terminal.Gui/Views/CharMap/CharMap.cs | Routes CharMap cursor defaults through CharMapSettings.Defaults. |
| Terminal.Gui/Views/Button.cs | Routes Button visual defaults through ButtonSettings.Defaults. |
| Terminal.Gui/ViewBase/View.Keyboard.cs | Suppresses obsolete warnings related to configuration attributes during transition. |
| Terminal.Gui/Text/NerdFonts.cs | Routes NerdFonts enable flag through NerdFontsSettings.Defaults. |
| Terminal.Gui/Terminal.Gui.csproj | Adds MEC/Options package references and extends NoWarn for IL3050. |
| Terminal.Gui/ModuleInitializers.cs | Adds MEC facade application during module initialization (after CM initialization). |
| Terminal.Gui/Input/Keyboard/Key.cs | Routes Key.Separator through KeySettings.Defaults. |
| Terminal.Gui/Drivers/Driver.cs | Routes driver settings through DriverSettings.Defaults (and preserves change event). |
| Terminal.Gui/Drawing/LineCanvas/LineCanvas.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Drawing/Glyphs.cs | Routes glyph defaults through GlyphSettings.Defaults and expands property accessors. |
| Terminal.Gui/Drawing/Color/Color.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/ThemeScope.cs | Marks ThemeScope obsolete and suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/ThemeManager.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/SourcesManager.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/SourceGenerationContext.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/SettingsScope.cs | Marks SettingsScope obsolete and suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/Settings/WindowSettings.cs | Adds Settings POCO for Window defaults. |
| Terminal.Gui/Configuration/Settings/TuiConfigurationExtensions.cs | Adds IConfigurationBuilder extension methods to add standard TUI config sources. |
| Terminal.Gui/Configuration/Settings/TuiConfigurationBuilder.cs | Adds the MEC configuration builder and static facade binding entry point. |
| Terminal.Gui/Configuration/Settings/TraceSettings.cs | Adds Settings POCO for trace defaults. |
| Terminal.Gui/Configuration/Settings/ThemeSettings.cs | Adds Settings POCO for active theme selection. |
| Terminal.Gui/Configuration/Settings/TextViewSettings.cs | Adds Settings POCO for TextView defaults. |
| Terminal.Gui/Configuration/Settings/TextFieldSettings.cs | Adds Settings POCO for TextField defaults. |
| Terminal.Gui/Configuration/Settings/StatusBarSettings.cs | Adds Settings POCO for StatusBar defaults. |
| Terminal.Gui/Configuration/Settings/SelectorBaseSettings.cs | Adds Settings POCO for SelectorBase defaults. |
| Terminal.Gui/Configuration/Settings/PopoverMenuSettings.cs | Adds Settings POCO for PopoverMenu defaults. |
| Terminal.Gui/Configuration/Settings/NerdFontsSettings.cs | Adds Settings POCO for NerdFonts defaults. |
| Terminal.Gui/Configuration/Settings/MessageBoxSettings.cs | Adds Settings POCO for MessageBox defaults. |
| Terminal.Gui/Configuration/Settings/MenuSettings.cs | Adds Settings POCO for Menu defaults. |
| Terminal.Gui/Configuration/Settings/MenuBarSettings.cs | Adds Settings POCO for MenuBar defaults. |
| Terminal.Gui/Configuration/Settings/MecThemeManager.cs | Adds MEC-backed theme manager wrapper over legacy ThemeManager. |
| Terminal.Gui/Configuration/Settings/MecSchemeManager.cs | Adds MEC-backed scheme manager wrapper over legacy SchemeManager. |
| Terminal.Gui/Configuration/Settings/LinearRangeSettings.cs | Adds Settings POCO for LinearRange defaults. |
| Terminal.Gui/Configuration/Settings/KeySettings.cs | Adds Settings POCO for Key parsing defaults. |
| Terminal.Gui/Configuration/Settings/IThemeManager.cs | Adds theme manager abstraction interface. |
| Terminal.Gui/Configuration/Settings/ISchemeManager.cs | Adds scheme manager abstraction interface. |
| Terminal.Gui/Configuration/Settings/HexViewSettings.cs | Adds Settings POCO for HexView defaults. |
| Terminal.Gui/Configuration/Settings/GlyphSettings.cs | Adds Settings POCO for glyph defaults. |
| Terminal.Gui/Configuration/Settings/FrameViewSettings.cs | Adds Settings POCO for FrameView defaults. |
| Terminal.Gui/Configuration/Settings/FileDialogStyleSettings.cs | Adds Settings POCO for FileDialogStyle defaults. |
| Terminal.Gui/Configuration/Settings/FileDialogSettings.cs | Adds Settings POCO for FileDialog defaults. |
| Terminal.Gui/Configuration/Settings/DriverSettings.cs | Adds Settings POCO for driver configuration. |
| Terminal.Gui/Configuration/Settings/DialogSettings.cs | Adds Settings POCO for Dialog defaults. |
| Terminal.Gui/Configuration/Settings/CheckBoxSettings.cs | Adds Settings POCO for CheckBox defaults. |
| Terminal.Gui/Configuration/Settings/CharMapSettings.cs | Adds Settings POCO for CharMap defaults. |
| Terminal.Gui/Configuration/Settings/ButtonSettings.cs | Adds Settings POCO for Button defaults. |
| Terminal.Gui/Configuration/Settings/ApplicationSettings.cs | Adds Settings POCO for application-level settings. |
| Terminal.Gui/Configuration/ScopeJsonConverter.cs | Removes TODO commentary while keeping unknown-property behavior. |
| Terminal.Gui/Configuration/Scope.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/SchemeManager.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/SchemeJsonConverter.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/DictionaryJsonConverter.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/DeepCloner.cs | Adds more AOT-safe dictionary construction paths and adjusts dictionary creation behavior. |
| Terminal.Gui/Configuration/ConfigurationPropertyAttribute.cs | Marks configuration attribute obsolete (migration guidance). |
| Terminal.Gui/Configuration/ConfigurationManager.cs | Marks ConfigurationManager obsolete and suppresses warnings internally during transition. |
| Terminal.Gui/Configuration/ConfigPropertyHostTypes.cs | Marks ConfigPropertyHostTypes obsolete and suppresses warnings during transition. |
| Terminal.Gui/Configuration/ConfigProperty.cs | Marks ConfigProperty obsolete and suppresses warnings during transition. |
| Terminal.Gui/Configuration/ConcurrentDictionaryJsonConverter.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/AttributeJsonConverter.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/Configuration/AppSettingsScope.cs | Marks AppSettingsScope obsolete and suppresses warnings during transition. |
| Terminal.Gui/App/Tracing/Trace.cs | Routes trace enablement through Settings POCOs while retaining async-local behavior. |
| Terminal.Gui/App/Legacy/Application.Mouse.cs | Routes legacy Application mouse setting through ApplicationSettings.Defaults. |
| Terminal.Gui/App/ApplicationImpl.Lifecycle.cs | Suppresses obsolete warnings during transition. |
| Terminal.Gui/App/Application.cs | Adjusts global using aliasing for CM with targeted obsolete warning suppression. |
| specs/replace-cm-with-mec.md | Adds the CM→MEC replacement specification document. |
| Directory.Packages.props | Adds MEC/Options package versions to central package management. |
Fixes: - Trace.EnabledCategories: restore async-local isolation (getter no longer reads from global TraceSettings.Defaults) - TuiConfigurationBuilder.BindSection: handle flat dotted keys (e.g. Driver.Force16Colors) that MEC JSON provider stores literally - ThemeSettings: bind as scalar key, not nested section - MecThemeManager.SwitchTheme: remove ApplyToStaticFacades call that would reset the theme selection - Remove filesystem/env access from module initializer - Remove unused 'using Microsoft.Extensions.Options' - Restore Glyphs.cs from base (fix encoding/mojibake) and use GlyphSettings.ApplyToStaticGlyphs() instead of property delegation - Add [Collection] to tests that mutate static Defaults - Update spec status from 'Draft' to 'In Progress' Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ConfigurationManager to be based on MEC
Mops up the small static facade for NerdFonts.Enable, matching the
A2.2 pattern used for the Glyphs facade. NerdFontsSettings was already
converted to a sealed record + Default/Current in A2.1; A2.3 just
removes the CM-reflection scaffolding on the consumer-facing static
facade.
Changes
=======
Terminal.Gui/Text/NerdFonts.cs
- NerdFonts.Enable rewritten from
[ConfigurationProperty (Scope = typeof (ThemeScope))]
public static bool Enable
{
get => NerdFontsSettings.Current.Enable;
set => NerdFontsSettings.Current = NerdFontsSettings.Current with { Enable = value };
}
to a bare expression-bodied reader:
public static bool Enable => NerdFontsSettings.Current.Enable;
- [ConfigurationProperty] attribute removed.
- `with`-swap setter removed; NerdFontsSettings.Current is now
exclusively written by MecThemeManager via BindThemeScope<T>.
- Caller surface unchanged: every NerdFonts.Enable reader keeps
working; only the host changed.
Terminal.Gui/Configuration/ConfigPropertyHostTypes.cs
- Drops `typeof (NerdFonts)` from the `_types` list and removes
the matching [DynamicDependency (PRESERVED_MEMBERS, typeof
(NerdFonts))]. NerdFonts is no longer a CM reflection host.
No Resources/config.json change needed
======================================
Grep against `Resources/config.json` for `NerdFonts` returns zero
matches; the file has never carried NerdFonts.X overrides. The A2.2
non-Default-theme dormancy footnote therefore does not apply here.
NerdFonts.Enable resolves to the C# init default
(NerdFontsSettings.Default.Enable = false) at startup and remains so
unless a consumer assigns NerdFontsSettings.Current via MEC binding,
which today happens only via TuiConfigurationBuilder's
BindThemeScope<NerdFontsSettings> against a (currently absent) MEC
section.
Test results
============
Tests/UnitTestsParallelizable: total 17292 / 17272 passed / 0 failed
/ 20 skipped (unchanged from A2.2; no new skips, no regressions).
Tests/UnitTests.NonParallelizable: total 74 / 72 passed / 0 failed /
2 skipped (unchanged).
Design context
==============
This is commit A2.3 of the A2 series (POCO ownership migration on
PR #5416, stacked on copilot/replace-cm-with-mec). A2.1 (2f7c13a)
landed the 17 ThemeScope POCOs and BindThemeScope<T>. A2.2 (441ef60
post-amend) landed the 18th (GlyphSettings) + Glyphs facade. A2.3
mops up NerdFonts. A2.4 will remove dead public static setters on
Button.DefaultShadow etc.
Cross-session review (PR #5411 owner) signed off on:
- One-line reader pattern for NerdFonts.Enable; drop the
`with`-swap setter that bridged CM's reflection write path.
- ConfigPropertyHostTypes row removal mirrors A2.2's Glyphs
treatment.
Deferred (per A2 contract)
==========================
- A2.4: removal of dead public static setters on view facades
(Button.DefaultShadow, etc.) -- next commit.
- Step D: CM deletion, config.json schema rewrite, BindThemeScope<T>
suppression re-justification.
Refs: A2.1 = 2f7c13a, A2.2 = 441ef60, stacked on
copilot/replace-cm-with-mec.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removes [ConfigurationProperty (Scope = typeof (ThemeScope))] from
all view-class static facade properties (Button.DefaultShadow,
Dialog.DefaultBorderStyle, etc.) and collapses their bridge get/set
bodies to bare expression-bodied readers, matching the A2.2 Glyphs
and A2.3 NerdFonts patterns.
These properties existed solely as CM-reflection bind targets — the
`with`-swap setter (`Current = Current with { X = value }`) was the
only writer, called by ConfigProperty.Apply via PropertyInfo.SetValue
against the embedded Resources/config.json flat keys. Audit confirmed
zero external callers of the setters; tests that read the getters
(e.g. ButtonTests asserting `button.ShadowStyle == Button.DefaultShadow`)
continue to work — only the host plumbing changed.
Net effect at runtime
=====================
For every affected property:
- Default theme: value comes from `<X>Settings.Default.<Prop>`'s
C# init default. Unchanged.
- Non-Default themes (Dark, Light, TurboPascal 5, Anders, etc.):
flat-key overrides like `"Button.DefaultShadow": "Opaque"` in
Resources/config.json are dormant from this commit through step D.
Same scope as the A2.2 Glyphs dormancy: CM path no longer matches
these keys (the [ConfigurationProperty] hosts are gone) and MEC
path can't read them (the JSON is still flat-keyed, not nested).
Step D rewrites Resources/config.json to nested form, which
reactivates non-Default theme view-facade overrides for all
theme-overlay POCOs uniformly via the existing
BindThemeScope<ButtonSettings> / <DialogSettings> / etc. calls in
TuiConfigurationBuilder.ApplyToStaticFacades.
Files changed
=============
Terminal.Gui/Views/Button.cs (2 props)
Terminal.Gui/Views/CheckBox.cs (1 prop)
Terminal.Gui/Views/CharMap/CharMap.cs (1 prop)
Terminal.Gui/Views/Dialog.cs (4 props)
Terminal.Gui/Views/FrameView.cs (1 prop)
Terminal.Gui/Views/HexView.cs (1 prop)
Terminal.Gui/Views/LinearRange/LinearRangeDefaults.cs (1 prop)
Terminal.Gui/Views/Menu/Menu.cs (1 prop)
Terminal.Gui/Views/Menu/MenuBar.cs (1 prop)
Terminal.Gui/Views/MessageBox.cs (2 props)
Terminal.Gui/Views/Selectors/SelectorBase.cs (1 prop)
Terminal.Gui/Views/StatusBar.cs (1 prop)
Terminal.Gui/Views/TextInput/TextField/TextField.cs (1 prop)
Terminal.Gui/Views/TextInput/TextView/TextView.cs (1 prop)
Terminal.Gui/Views/Window.cs (2 props)
All ThemeScope-scoped view-facade props converted; total 21 properties
across 15 files. Pattern per property:
Before:
/// <summary>...</summary>
[ConfigurationProperty (Scope = typeof (ThemeScope))]
public static T Name
{
get => XSettings.Current.Name;
set => XSettings.Current = XSettings.Current with { Name = value };
}
After:
/// <summary>...</summary>
public static T Name => XSettings.Current.Name;
Out of scope
============
SettingsScope-scoped [ConfigurationProperty] on view classes
(FileDialog.MaxSearchResults, FileDialogStyle.DefaultUseColors,
MenuBar.DefaultKey, PopoverMenu.DefaultKey, View.DefaultMouseBindings,
View.ViewMouseBindings, BorderView.DefaultMouseBindings) are NOT
touched. SettingsScope follows the mutable-Defaults pattern (per
A2.1's divergence note in specs/remove-legacy-cm.md §4.2) and remains
CM-managed until step D.
Terminal.Gui/Configuration/ConfigPropertyHostTypes.cs
- Drops 14 entries (typeof + matching [DynamicDependency]) for
types whose only [ConfigurationProperty] attrs were ThemeScope
and are therefore now empty hosts:
Button, CharMap, CheckBox, Dialog, FrameView, HexView,
LinearRangeDefaults, Menu, MessageBox, SelectorBase,
StatusBar, TextField, TextView, Window.
- Keeps entries that still hold SettingsScope [ConfigurationProperty]:
FileDialog, FileDialogStyle, MenuBar, PopoverMenu, View,
BorderView, plus the unchanged Application / Color / Driver /
Key / Trace / ConfigurationManager / SchemeManager /
ThemeManager facades.
Tests/UnitTestsParallelizable/Configuration/ScopeJsonConverterTests.cs
- Drops the one InlineData row that exercised CM's
ScopeJsonConverter with `"Dialog.DefaultButtonAlignment": "End"`
(Dialog.DefaultButtonAlignment is one of the 21 properties this
commit removes [ConfigurationProperty] from; the converter now
rejects the key as Unknown). Comment notes the rationale and the
expected removal alongside CM in step D. Sibling InlineData rows
that don't reference dropped facade props continue to test the
converter.
Test results
============
Tests/UnitTestsParallelizable: total 17291 / 17271 passed / 0 failed
/ 20 skipped (one fewer test row vs. A2.3 baseline because the
ScopeJsonConverter InlineData row was removed by design; no
failures, no new skips, ConfigPropertyHostTypes drift-detector
still green because it tracks reflected hosts and we removed
matching list entries in lockstep).
Tests/UnitTests.NonParallelizable: total 74 / 72 passed / 0 failed /
2 skipped (unchanged).
Design context
==============
This is commit A2.4 of the A2 series (POCO ownership migration on
PR #5416, stacked on copilot/replace-cm-with-mec). A2.1 (2f7c13a)
landed the 17 ThemeScope POCOs and BindThemeScope<T>. A2.2 (441ef60)
landed GlyphSettings + Glyphs facade. A2.3 (f85e930) mopped up
NerdFonts. A2.4 finishes the series by removing the dead view-facade
setter scaffolding.
A2 status: complete. The cleared-out view-facade properties leave
ButtonSettings, CheckBoxSettings, DialogSettings, FrameViewSettings,
etc. as the sole owners of theme-overlayed state; MecThemeManager
mutates `<X>Settings.Current` exclusively via BindThemeScope<T>
intra-assembly; consumer reads go through the bare expression-bodied
getters on the view facades or directly through `<X>Settings.Current`.
Cross-session review (PR #5411 owner) signed off on:
- Removal of public static setters on view facades; "zero external
callers" audit accepted.
- Inheriting the A2.2 dormancy framing — Dark/Light/etc. theme
overrides for view facades are dormant from A2.4 through step D's
config.json rewrite. Same window as Glyphs.
Deferred to step D / later commits
==================================
- Resources/config.json rewrite to nested form (B/D).
- CM deletion (D).
- BindThemeScope<T> [UnconditionalSuppressMessage] re-justification
once ConfigPropertyHostTypes goes (D).
- ThemeSettings record + Current conversion (future micro-commit).
- Mec* prefix drops on the manager types (post-D).
Refs: A2.1 = 2f7c13a, A2.2 = 441ef60, A2.3 = f85e930,
stacked on copilot/replace-cm-with-mec.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… refs to TuiSerializerContext.Instance
Mechanical rename of remaining CS0618-bound references on the obsolete
ConfigurationManager.SerializerContext field (= TuiSerializerContext.Instance,
same readonly field) to the non-obsolete home directly.
- DeepCloner.cs: remove now-stale '#pragma warning disable CS0618' (no
SerializerContext references remain; all migrated in Phase C-extract).
- 4 test files (Key/Rune/Scheme/ScopeJsonConverterTests): mechanical
ConfigurationManager.SerializerContext.{Options,SettingsScope} ->
TuiSerializerContext.Instance.{Options,SettingsScope}.
Behavior-neutral: ConfigurationManager.SerializerContext is literally
'= TuiSerializerContext.Instance' (ConfigurationManager.cs:720). Both
references resolve to the same readonly static field.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previous commit re-encoded 4 test files via PowerShell Set-Content -NoNewline which stripped UTF-8 BOM and mangled Unicode literals in [InlineData] strings. This broke RuneJsonConverterTests.RoundTripConversion_Positive on CI runners where the input emoji codepoints were corrupted into invalid sequences. Re-applied the SerializerContext rename preserving the original UTF-8 BOM encoding via [System.Text.UTF8Encoding]::new(true) and File.WriteAllText. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…test migration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…elop # Conflicts: # Terminal.Gui/App/Application.cs # Terminal.Gui/Configuration/ConcurrentDictionaryJsonConverter.cs # Terminal.Gui/Drawing/Glyphs.cs
Adds specs/breaking-changes-cm-mec.md analyzing the real consumer-facing impact of the CM->MEC migration: - #5411 removes/renames no public API; only marks 6 public CM types [Obsolete] (CS0618) and adds 4 Microsoft.Extensions.* dependencies. - In-repo builds hide CS0618 via .editorconfig; external NuGet consumers will see the deprecation warnings. - All hard, compile-breaking removals are deferred to #5416. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merge conflicts with
|
| File | Resolution |
|---|---|
App/Application.cs |
Kept develop's reordered global usings; re-wrapped the obsolete CM alias in #pragma warning disable/restore CS0618. |
Configuration/ConcurrentDictionaryJsonConverter.cs |
Kept this PR's TuiSerializerContext.Instance with develop's correct spacing. |
Drawing/Glyphs.cs |
Kept the POCO-delegation pattern; moved develop's new glyph values (☑, ⬛, from develop commit bbd16ad1e) into GlyphSettings.cs so Default_CheckState_Glyphs_Are_Distinct passes. |
Full solution builds clean; Configuration (230) + CheckBox (36) parallelizable suites pass.
Breaking changes: this PR vs #5416
Despite the BREAKING CHANGE label, #5411 is source-compatible. Verified against the actual diff over develop:
- Removes nothing public — 0 deleted files, 0 removed/renamed/re-signatured public members. The
-public …lines in the diff are auto-properties converted to delegating properties (identical signatures, backed by Settings POCOs). - Only deprecates — marks 6 public types
[Obsolete]:ConfigurationManager,ConfigurationPropertyAttribute,ConfigProperty,SettingsScope,ThemeScope,AppSettingsScope.ThemeManager/SchemeManagerremain public and non-obsolete. ⚠️ In-repo builds hide this:.editorconfigsetsdotnet_diagnostic.cs0618.severity = nonerepo-wide (pre-existing, added in Fixes #4361 - ConsolidateFakeDriverinto library and refactor driver architecture #4362 — not by this PR), soTerminal.Gui/UICatalog/tests emit zero CS0618 even thoughRunner.cscallsConfigurationManager.Enable/Load/Applydirectly. External NuGet consumers are not covered by that suppression and will see the deprecation warnings — a source break only for consumers usingTreatWarningsAsErrors.- Adds 4 transitive deps:
Microsoft.Extensions.Configuration[.Binder/.Json],Microsoft.Extensions.Options(changes the dependency closure; relevant to AOT/size). - Behavior intended-preserved (shims kept, effective config routed through MEC).
All the hard, compile-breaking removals are deferred to #5416 — it strips the [ConfigurationProperty] surface (~1260 lines from Glyphs.cs alone), removes the CM machinery, reworks theme/scheme data ownership, and ships a Tools/MigrateConfig utility (i.e. that's where the on-disk config.json format can break too).
Full write-up in specs/breaking-changes-cm-mec.md.
🤖 Generated with Claude Code
ConfigurationManager to be based on MECConfigurationManager to be based on MEC
|
A couple of things to double check that a Claude-based code review surfaced:
|
|
@copilot resolve the merge conflicts in this pull request |
Two issues surfaced by code review on #5411: 1. MEC binding was inert against the shipped config.json format. The real config uses flat dotted keys (e.g. "Driver.Force16Colors", "Key.Separator") and a scalar "Theme" key, but ApplyToStaticFacades bound nested sections via GetSection(name).Bind(), which reads nothing because the MEC JSON provider stores dotted keys literally (only ':' is a section separator). - BindSection now falls back to BindFlatDottedKeys when the nested section does not exist, mapping flat "Section.Property" keys onto the POCO. - BindThemeScalar binds the scalar "Theme" key to ThemeSettings.Theme. - Nested-section format still binds, so existing config keeps working. - SwitchTheme records the switched theme after ApplyToStaticFacades so the config re-apply (which can now read "Theme") cannot reset the selection. 2. MecThemeManager leaked a static-event subscription. The ctor did ThemeManager.ThemeChanged += OnLegacyThemeChanged with no unsubscribe, so every instance was pinned alive by the static event and fired once per live instance. Forwarding is now wired up lazily via custom event accessors only while the instance has subscribers, and torn down when the last detaches. Test-first: adds MecDottedKeyTests (flat/scalar/nested binding) and MecThemeManagerLeakTests (no leak, subscribe/unsubscribe, forwarding). Gates the pre-existing MEC tests that mutate static Defaults into the shared "StaticSettingsTests" collection to keep them race-free. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Both points are valid — thanks for catching them. Verified against the branch and addressed in 349db3c (test-first). 1. Flat-key / scalar-
Re-applied the intended behavior:
New regression tests in 2. The ctor did New tests in I rebased onto the latest |
PR #5411 marks ConfigurationManager [Obsolete], and the Validate Doc Snippets CI job elevates CS0618 to an error. Update the "set theme at startup" snippet to the MEC replacement (TuiConfigurationBuilder + RuntimeConfig + ApplyToStaticFacades), which the flat/scalar binding fix now makes functional for the "Theme" scalar key. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…OT-safe ConvertValue fell back to TypeDescriptor.GetConverter (RequiresUnreferencedCode / RequiresDynamicCode) for non-scalar settings, breaking NativeAOT/trimmed consumers (e.g. tui-cs/Editor's `ted`) with IL2026/IL3050. Regression from tui-cs#5411. - ConvertValue: replace the TypeDescriptor.GetConverter fallback with an explicit Key fast path (Key.TryParse). Key was the only non-scalar/non-enum type bound via flat dotted keys (MenuBar.DefaultKey, PopoverMenu.DefaultKey); all other settings are string/bool/int/Rune/enum and already had fast paths. The public binding path now has no RequiresUnreferencedCode/RequiresDynamicCode dependency. - BindSection<T>/BindFlatDottedKeys<T>: annotate T with [DynamicallyAccessedMembers(PublicProperties)] so typeof(T).GetProperties() is trim-safe (fixes IL2090). Callers pass concrete settings types, so it is satisfiable; this preserves the properties the trimmer would otherwise drop. - Drop the now-unused System.ComponentModel using and the no-longer-needed IL2026 suppression on BindFlatDottedKeys. Verified with a trimmed publish of a consumer app: TuiConfigurationBuilder now produces zero IL trim/AOT warnings (previously IL2026 + IL2090). Adds a regression test that PopoverMenu.DefaultKey (a Key-typed flat dotted key) binds via the new fast path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Completes the functional CM → MEC migration for #4943 by finishing migration of the remaining complex CM-managed types, while keeping compatibility shims during the transition.
Motivation
Scope in this PR
1. MEC foundation + POCO-backed defaults
TuiConfigurationBuilder/TuiConfigurationExtensionsDefaultsfacades2. Migration of remaining complex types (finish functional migration)
Theme,Themes) migrated to MEC-backed flowSchemes) migrated to MEC-backed flowColors16) migrated to MEC-backed flow3. Compatibility + transition safety
Testing
Breaking changes
Follow-up PR (stacked)