Skip to content

Commit 2a30e9e

Browse files
authored
Merge pull request #3843 from tig/v2_3841-ConfigManager
Fixes #3841 - `ConfigurationManager` not loading correctly
2 parents 661b904 + 61bfe2f commit 2a30e9e

35 files changed

+700
-247
lines changed

Example/Example.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
using System;
77
using Terminal.Gui;
88

9+
// Override the default configuraiton for the application to use the Light theme
10+
ConfigurationManager.RuntimeConfig = """{ "Theme": "Light" }""";
11+
912
Application.Run<ExampleWindow> ().Dispose ();
1013

1114
// Before the application exits, reset Terminal.Gui for clean shutdown

Terminal.Gui/Application/Application.Initialization.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,14 @@ internal static void InternalInit (
8686
// We're running unit tests. Disable loading config files other than default
8787
if (Locations == ConfigLocations.All)
8888
{
89-
Locations = ConfigLocations.DefaultOnly;
89+
Locations = ConfigLocations.Default;
9090
Reset ();
9191
}
9292
}
9393
}
9494

95+
AddApplicationKeyBindings ();
96+
9597
// Start the process of configuration management.
9698
// Note that we end up calling LoadConfigurationFromAllSources
9799
// multiple times. We need to do this because some settings are only
@@ -106,8 +108,6 @@ internal static void InternalInit (
106108
}
107109
Apply ();
108110

109-
AddApplicationKeyBindings ();
110-
111111
// Ignore Configuration for ForceDriver if driverName is specified
112112
if (!string.IsNullOrEmpty (driverName))
113113
{

Terminal.Gui/Application/Application.Keyboard.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,15 @@ private static void ReplaceKey (Key oldKey, Key newKey)
290290
}
291291
else
292292
{
293-
KeyBindings.ReplaceKey (oldKey, newKey);
293+
if (KeyBindings.TryGet(oldKey, out KeyBinding binding))
294+
{
295+
KeyBindings.Remove (oldKey);
296+
KeyBindings.Add (newKey, binding);
297+
}
298+
else
299+
{
300+
KeyBindings.Add (newKey, binding);
301+
}
294302
}
295303
}
296304

Terminal.Gui/Application/Application.Run.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#nullable enable
22
using System.Diagnostics;
33
using System.Diagnostics.CodeAnalysis;
4+
using System.Text.Json.Serialization;
45
using Microsoft.CodeAnalysis.Diagnostics;
56

67
namespace Terminal.Gui;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#nullable enable
2+
namespace Terminal.Gui;
3+
4+
/// <summary>
5+
/// Describes the location of the configuration files. The constants can be combined (bitwise) to specify multiple
6+
/// locations. The more significant the bit, the higher the priority meaning that the last location will override the
7+
/// earlier ones.
8+
/// </summary>
9+
10+
[Flags]
11+
public enum ConfigLocations
12+
{
13+
/// <summary>No configuration will be loaded.</summary>
14+
/// <remarks>
15+
/// Used for development and testing only. For Terminal,Gui to function properly, at least
16+
/// <see cref="Default"/> should be set.
17+
/// </remarks>
18+
None = 0,
19+
20+
/// <summary>
21+
/// Deafult configuration in <c>Terminal.Gui.dll</c>'s resources (<c>Terminal.Gui.Resources.config.json</c>).
22+
/// </summary>
23+
Default = 0b_0000_0001,
24+
25+
/// <summary>
26+
/// Global settings in the current directory (e.g. <c>./.tui/config.json</c>).
27+
/// </summary>
28+
GlobalCurrent = 0b_0000_0010,
29+
30+
/// <summary>
31+
/// Global settings in the home directory (e.g. <c>~/.tui/config.json</c>).
32+
/// </summary>
33+
GlobalHome = 0b_0000_0100,
34+
35+
/// <summary>
36+
/// App resources (e.g. <c>MyApp.Resources.config.json</c>).
37+
/// </summary>
38+
AppResources = 0b_0000_1000,
39+
40+
/// <summary>
41+
/// App settings in the current directory (e.g. <c>./.tui/MyApp.config.json</c>).
42+
/// </summary>
43+
AppCurrent = 0b_0001_0000,
44+
45+
/// <summary>
46+
/// App settings in the home directory (e.g. <c>~/.tui/MyApp.config.json</c>).
47+
/// </summary>
48+
AppHome = 0b_0010_0000,
49+
50+
/// <summary>
51+
/// Settings in the <see cref="ConfigurationManager.RuntimeConfig"/> static property.
52+
/// </summary>
53+
Runtime = 0b_0100_0000,
54+
55+
/// <summary>This constant is a combination of all locations</summary>
56+
All = 0b_1111_1111
57+
}

Terminal.Gui/Configuration/ConfigProperty.cs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,42 @@ public class ConfigProperty
3131
/// </remarks>
3232
public object? PropertyValue { get; set; }
3333

34-
/// <summary>Applies the <see cref="PropertyValue"/> to the property described by <see cref="PropertyInfo"/>.</summary>
34+
/// <summary>Applies the <see cref="PropertyValue"/> to the static property described by <see cref="PropertyInfo"/>.</summary>
3535
/// <returns></returns>
3636
public bool Apply ()
3737
{
38-
if (PropertyValue is { })
38+
try
3939
{
40-
try
40+
if (PropertyInfo?.GetValue (null) is { })
4141
{
42-
if (PropertyInfo?.GetValue (null) is { })
43-
{
44-
PropertyInfo?.SetValue (null, DeepMemberWiseCopy (PropertyValue, PropertyInfo?.GetValue (null)));
45-
}
42+
var val = DeepMemberWiseCopy (PropertyValue, PropertyInfo?.GetValue (null));
43+
PropertyInfo?.SetValue (null, val);
4644
}
47-
catch (TargetInvocationException tie)
45+
}
46+
catch (TargetInvocationException tie)
47+
{
48+
// Check if there is an inner exception
49+
if (tie.InnerException is { })
4850
{
49-
// Check if there is an inner exception
50-
if (tie.InnerException is { })
51-
{
52-
// Handle the inner exception separately without catching the outer exception
53-
Exception? innerException = tie.InnerException;
51+
// Handle the inner exception separately without catching the outer exception
52+
Exception? innerException = tie.InnerException;
5453

55-
// Handle the inner exception here
56-
throw new JsonException (
57-
$"Error Applying Configuration Change: {innerException.Message}",
58-
innerException
59-
);
60-
}
61-
62-
// Handle the outer exception or rethrow it if needed
63-
throw new JsonException ($"Error Applying Configuration Change: {tie.Message}", tie);
64-
}
65-
catch (ArgumentException ae)
66-
{
54+
// Handle the inner exception here
6755
throw new JsonException (
68-
$"Error Applying Configuration Change ({PropertyInfo?.Name}): {ae.Message}",
69-
ae
56+
$"Error Applying Configuration Change: {innerException.Message}",
57+
innerException
7058
);
7159
}
60+
61+
// Handle the outer exception or rethrow it if needed
62+
throw new JsonException ($"Error Applying Configuration Change: {tie.Message}", tie);
63+
}
64+
catch (ArgumentException ae)
65+
{
66+
throw new JsonException (
67+
$"Error Applying Configuration Change ({PropertyInfo?.Name}): {ae.Message}",
68+
ae
69+
);
7270
}
7371

7472
return PropertyValue != null;
@@ -94,6 +92,12 @@ public static string GetJsonPropertyName (PropertyInfo pi)
9492
/// <returns></returns>
9593
public object? RetrieveValue () { return PropertyValue = PropertyInfo!.GetValue (null); }
9694

95+
/// <summary>
96+
/// Updates (using reflection) <see cref="PropertyValue"/> with the value in <paramref name="source"/> using a deep memberwise copy.
97+
/// </summary>
98+
/// <param name="source"></param>
99+
/// <returns></returns>
100+
/// <exception cref="ArgumentException"></exception>
97101
internal object? UpdateValueFrom (object source)
98102
{
99103
if (source is null)

0 commit comments

Comments
 (0)