diff --git a/StarterNG.Tests/KeyboardConfigTests.cs b/StarterNG.Tests/KeyboardConfigTests.cs
new file mode 100644
index 0000000..7f20bac
--- /dev/null
+++ b/StarterNG.Tests/KeyboardConfigTests.cs
@@ -0,0 +1,10 @@
+using StarterNG.Classes;
+
+namespace StarterNG.Tests;
+
+public class KeyboardConfigTests
+{
+ [Fact]
+ public void A_description_without_polish_letters_matches_the_bundled_one() =>
+ Assert.Equal("zwiekszenie nastawnika glownego", KeyboardConfig.StripPolish("zwiększenie nastawnika głównego"));
+}
diff --git a/StarterNG/Classes/KeyboardConfig.cs b/StarterNG/Classes/KeyboardConfig.cs
index b717853..99acdaa 100644
--- a/StarterNG/Classes/KeyboardConfig.cs
+++ b/StarterNG/Classes/KeyboardConfig.cs
@@ -86,9 +86,65 @@ public sealed class KeyboardConfig
_savePath = UserConfigPath();
string source = FirstExisting(_savePath, WorkingDirDefaultPath(), BundledDefaultPath());
ParseSource(source);
+ LoadPolishDescriptions();
Dirty = false;
}
+ ///
+ /// The game ships its key file with the descriptions stripped of Polish letters
+ /// ("zwiekszenie nastawnika glownego"); the copy bundled with the starter has
+ /// them. Read once, shown in place of the bare ones, never written back.
+ ///
+ private readonly Dictionary _polishDescriptions = new(StringComparer.OrdinalIgnoreCase);
+
+ private void LoadPolishDescriptions()
+ {
+ _polishDescriptions.Clear();
+ try
+ {
+ string path = BundledDefaultPath();
+ if (!File.Exists(path))
+ return;
+
+ var bundled = new KeyboardConfig();
+ bundled.Parse(File.ReadAllText(path, FileEncoding));
+ foreach (var b in bundled.Bindings)
+ if (!string.IsNullOrEmpty(b.Description))
+ _polishDescriptions.TryAdd(b.Command, b.Description);
+ }
+ catch (Exception ex)
+ {
+ StarterNG.Infrastructure.Diagnostics.Log("reading the bundled key descriptions", ex);
+ }
+ }
+
+ ///
+ /// The description to show: the bundled one with Polish letters when the file's
+ /// is the same text without them, the file's own when someone wrote their own.
+ ///
+ public string DescriptionOf(KeyBinding binding)
+ {
+ if (_polishDescriptions.TryGetValue(binding.Command, out string? polish) &&
+ (string.IsNullOrEmpty(binding.Description) ||
+ string.Equals(StripPolish(polish), binding.Description.Trim(), StringComparison.OrdinalIgnoreCase)))
+ return polish;
+
+ return binding.Description;
+ }
+
+ public static string StripPolish(string text)
+ {
+ var sb = new StringBuilder(text.Length);
+ foreach (char c in text.Trim())
+ sb.Append(c switch
+ {
+ 'ą' => 'a', 'ć' => 'c', 'ę' => 'e', 'ł' => 'l', 'ń' => 'n', 'ó' => 'o', 'ś' => 's', 'ź' => 'z', 'ż' => 'z',
+ 'Ą' => 'A', 'Ć' => 'C', 'Ę' => 'E', 'Ł' => 'L', 'Ń' => 'N', 'Ó' => 'O', 'Ś' => 'S', 'Ź' => 'Z', 'Ż' => 'Z',
+ _ => c
+ });
+ return sb.ToString();
+ }
+
public void LoadDefaults()
{
if (string.IsNullOrEmpty(_savePath))
diff --git a/StarterNG/Views/Settings.axaml.cs b/StarterNG/Views/Settings.axaml.cs
index d99c8ec..8d77728 100644
--- a/StarterNG/Views/Settings.axaml.cs
+++ b/StarterNG/Views/Settings.axaml.cs
@@ -886,7 +886,7 @@ public partial class Settings : UserControl, ISettingsCapture
private static bool MatchesFilter(KeyBinding b, string filter) =>
TextMatch.Contains(b.Command, filter) ||
- TextMatch.Contains(b.Description, filter);
+ TextMatch.Contains(KeyboardConfig.Instance.DescriptionOf(b), filter);
private Control BuildBindingRow(KeyBinding b, HashSet conflicts)
{
@@ -1384,7 +1384,7 @@ public partial class Settings : UserControl, ISettingsCapture
}
private static string CommandLabel(KeyBinding b) =>
- string.IsNullOrEmpty(b.Description) ? b.Command : Capitalize(b.Description);
+ KeyboardConfig.Instance.DescriptionOf(b) is { Length: > 0 } description ? Capitalize(description) : b.Command;
private static string Capitalize(string s) =>
string.IsNullOrEmpty(s) ? s : char.ToUpperInvariant(s[0]) + s.Substring(1);