From 113baac567f91b30a7fb8164fa72eafb7cfb68e0 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Tue, 22 Jul 2025 23:48:11 +0100 Subject: [PATCH 01/12] Smart thousands and decimals ## Core Logic * **Advanced Number Parsing:** We now process numbers with various decimal and thousand-separator formats (e.g., `1,234.56` and `1.234,56`). We distinguish between separator types based on their position and surrounding digits. * **Context-Aware Output Formatting:** We now mirror the output format based on the user's input. If a query includes thousand separators, the result will also have them. The decimal separator in the result will match the one used in the query. ## Code Cleanup * **Deleted Unused File:** `NumberTranslator.cs` was unused and therefore removed. * **Removed Redundant UI Code:** The `CalculatorSettings_Loaded` event handler in `CalculatorSettings.xaml.cs` (and its XAML registration) was removed. The functionality was already handled automatically by data binding. ## Maintainability * **Added Code Documentation:** An XML summary comment was added to the new `NormalizeNumber` method in `Main.cs` to clarify its purpose. So, the plugin is now much more flexible, and will accept whatever format the user gives it regardless of Windows region settings. --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 157 ++++++++++++++---- .../NumberTranslator.cs | 91 ---------- .../Views/CalculatorSettings.xaml | 1 - .../Views/CalculatorSettings.xaml.cs | 8 - .../plugin.json | 6 +- 5 files changed, 129 insertions(+), 134 deletions(-) delete mode 100644 Plugins/Flow.Launcher.Plugin.Calculator/NumberTranslator.cs diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 3d06c4ce0b5..2787adbbcba 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows.Controls; @@ -23,6 +24,7 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider @"[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]]" + @")+$", RegexOptions.Compiled); private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled); + private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))"); private static Engine MagesEngine; private const string comma = ","; private const string dot = "."; @@ -32,6 +34,9 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider private static Settings _settings; private static SettingsViewModel _viewModel; + private string _inputDecimalSeparator; + private bool _inputUsesGroupSeparators; + public void Init(PluginInitContext context) { Context = context; @@ -54,20 +59,13 @@ public List Query(Query query) return new List(); } + _inputDecimalSeparator = null; + _inputUsesGroupSeparators = false; + try { - string expression; - - switch (_settings.DecimalSeparator) - { - case DecimalSeparator.Comma: - case DecimalSeparator.UseSystemLocale when CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator == ",": - expression = query.Search.Replace(",", "."); - break; - default: - expression = query.Search; - break; - } + var numberRegex = new Regex(@"[\d\.,]+"); + var expression = numberRegex.Replace(query.Search, m => NormalizeNumber(m.Value)); var result = MagesEngine.Interpret(expression); @@ -80,7 +78,7 @@ public List Query(Query query) if (!string.IsNullOrEmpty(result?.ToString())) { decimal roundedResult = Math.Round(Convert.ToDecimal(result), _settings.MaxDecimalPlaces, MidpointRounding.AwayFromZero); - string newResult = ChangeDecimalSeparator(roundedResult, GetDecimalSeparator()); + string newResult = FormatResult(roundedResult); return new List { @@ -115,6 +113,121 @@ public List Query(Query query) return new List(); } + + /// + /// Parses a string representation of a number, detecting its format. It uses structural analysis + /// (checking for 3-digit groups) and falls back to system culture for ambiguous cases (e.g., "1,234"). + /// It sets instance fields to remember the user's format for later output formatting. + /// + /// A normalized number string with '.' as the decimal separator for the Mages engine. + private string NormalizeNumber(string numberStr) + { + var systemFormat = CultureInfo.CurrentCulture.NumberFormat; + string systemDecimalSeparator = systemFormat.NumberDecimalSeparator; + + bool hasDot = numberStr.Contains(dot); + bool hasComma = numberStr.Contains(comma); + + // Unambiguous case: both separators are present. The last one wins as decimal separator. + if (hasDot && hasComma) + { + _inputUsesGroupSeparators = true; + int lastDotPos = numberStr.LastIndexOf(dot); + int lastCommaPos = numberStr.LastIndexOf(comma); + + if (lastDotPos > lastCommaPos) // e.g. 1,234.56 + { + _inputDecimalSeparator = dot; + return numberStr.Replace(comma, string.Empty); + } + else // e.g. 1.234,56 + { + _inputDecimalSeparator = comma; + return numberStr.Replace(dot, string.Empty).Replace(comma, dot); + } + } + + if (hasComma) + { + string[] parts = numberStr.Split(','); + // If all parts after the first are 3 digits, it's a potential group separator. + bool isGroupCandidate = parts.Length > 1 && parts.Skip(1).All(p => p.Length == 3); + + if (isGroupCandidate) + { + // Ambiguous case: "1,234". Resolve using culture. + if (systemDecimalSeparator == comma) + { + _inputDecimalSeparator = comma; + return numberStr.Replace(comma, dot); + } + else + { + _inputUsesGroupSeparators = true; + return numberStr.Replace(comma, string.Empty); + } + } + else + { + // Unambiguous decimal: "123,45" or "1,2,345" + _inputDecimalSeparator = comma; + return numberStr.Replace(comma, dot); + } + } + + if (hasDot) + { + string[] parts = numberStr.Split('.'); + bool isGroupCandidate = parts.Length > 1 && parts.Skip(1).All(p => p.Length == 3); + + if (isGroupCandidate) + { + if (systemDecimalSeparator == dot) + { + _inputDecimalSeparator = dot; + return numberStr; + } + else + { + _inputUsesGroupSeparators = true; + return numberStr.Replace(dot, string.Empty); + } + } + else + { + _inputDecimalSeparator = dot; + return numberStr; // Already in Mages-compatible format + } + } + + // No separators. + return numberStr; + } + + private string FormatResult(decimal roundedResult) + { + // Use the detected decimal separator from the input; otherwise, fall back to settings. + string decimalSeparator = _inputDecimalSeparator ?? GetDecimalSeparator(); + string groupSeparator = decimalSeparator == dot ? comma : dot; + + string resultStr = roundedResult.ToString(CultureInfo.InvariantCulture); + + string[] parts = resultStr.Split('.'); + string integerPart = parts[0]; + string fractionalPart = parts.Length > 1 ? parts[1] : string.Empty; + + if (_inputUsesGroupSeparators) + { + integerPart = ThousandGroupRegex.Replace(integerPart, groupSeparator); + } + + if (!string.IsNullOrEmpty(fractionalPart)) + { + return integerPart + decimalSeparator + fractionalPart; + } + + return integerPart; + } private bool CanCalculate(Query query) { @@ -134,27 +247,9 @@ private bool CanCalculate(Query query) return false; } - if ((query.Search.Contains(dot) && GetDecimalSeparator() != dot) || - (query.Search.Contains(comma) && GetDecimalSeparator() != comma)) - return false; - return true; } - private string ChangeDecimalSeparator(decimal value, string newDecimalSeparator) - { - if (String.IsNullOrEmpty(newDecimalSeparator)) - { - return value.ToString(); - } - - var numberFormatInfo = new NumberFormatInfo - { - NumberDecimalSeparator = newDecimalSeparator - }; - return value.ToString(numberFormatInfo); - } - private static string GetDecimalSeparator() { string systemDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/NumberTranslator.cs b/Plugins/Flow.Launcher.Plugin.Calculator/NumberTranslator.cs deleted file mode 100644 index 4eacb9d349c..00000000000 --- a/Plugins/Flow.Launcher.Plugin.Calculator/NumberTranslator.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Globalization; -using System.Text; -using System.Text.RegularExpressions; - -namespace Flow.Launcher.Plugin.Calculator -{ - /// - /// Tries to convert all numbers in a text from one culture format to another. - /// - public class NumberTranslator - { - private readonly CultureInfo sourceCulture; - private readonly CultureInfo targetCulture; - private readonly Regex splitRegexForSource; - private readonly Regex splitRegexForTarget; - - private NumberTranslator(CultureInfo sourceCulture, CultureInfo targetCulture) - { - this.sourceCulture = sourceCulture; - this.targetCulture = targetCulture; - - this.splitRegexForSource = GetSplitRegex(this.sourceCulture); - this.splitRegexForTarget = GetSplitRegex(this.targetCulture); - } - - /// - /// Create a new - returns null if no number conversion - /// is required between the cultures. - /// - /// source culture - /// target culture - /// - public static NumberTranslator Create(CultureInfo sourceCulture, CultureInfo targetCulture) - { - bool conversionRequired = sourceCulture.NumberFormat.NumberDecimalSeparator != targetCulture.NumberFormat.NumberDecimalSeparator - || sourceCulture.NumberFormat.PercentGroupSeparator != targetCulture.NumberFormat.PercentGroupSeparator - || sourceCulture.NumberFormat.NumberGroupSizes != targetCulture.NumberFormat.NumberGroupSizes; - return conversionRequired - ? new NumberTranslator(sourceCulture, targetCulture) - : null; - } - - /// - /// Translate from source to target culture. - /// - /// - /// - public string Translate(string input) - { - return this.Translate(input, this.sourceCulture, this.targetCulture, this.splitRegexForSource); - } - - /// - /// Translate from target to source culture. - /// - /// - /// - public string TranslateBack(string input) - { - return this.Translate(input, this.targetCulture, this.sourceCulture, this.splitRegexForTarget); - } - - private string Translate(string input, CultureInfo cultureFrom, CultureInfo cultureTo, Regex splitRegex) - { - var outputBuilder = new StringBuilder(); - - string[] tokens = splitRegex.Split(input); - foreach (string token in tokens) - { - decimal number; - outputBuilder.Append( - decimal.TryParse(token, NumberStyles.Number, cultureFrom, out number) - ? number.ToString(cultureTo) - : token); - } - - return outputBuilder.ToString(); - } - - private Regex GetSplitRegex(CultureInfo culture) - { - var splitPattern = $"((?:\\d|{Regex.Escape(culture.NumberFormat.NumberDecimalSeparator)}"; - if (!string.IsNullOrEmpty(culture.NumberFormat.NumberGroupSeparator)) - { - splitPattern += $"|{Regex.Escape(culture.NumberFormat.NumberGroupSeparator)}"; - } - splitPattern += ")+)"; - return new Regex(splitPattern); - } - } -} diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml index ceee3897c18..36beebc33f3 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml @@ -10,7 +10,6 @@ xmlns:viewModels="clr-namespace:Flow.Launcher.Plugin.Calculator.ViewModels" d:DesignHeight="450" d:DesignWidth="800" - Loaded="CalculatorSettings_Loaded" mc:Ignorable="d"> diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs index edb73470cec..117a19b25dc 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs @@ -1,4 +1,3 @@ -using System.Windows; using System.Windows.Controls; using Flow.Launcher.Plugin.Calculator.ViewModels; @@ -19,13 +18,6 @@ public CalculatorSettings(SettingsViewModel viewModel) DataContext = viewModel; InitializeComponent(); } - - private void CalculatorSettings_Loaded(object sender, RoutedEventArgs e) - { - DecimalSeparatorComboBox.SelectedItem = _settings.DecimalSeparator; - MaxDecimalPlaces.SelectedItem = _settings.MaxDecimalPlaces; - } } - } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json index 3168edfccb7..739572930d0 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json @@ -2,9 +2,9 @@ "ID": "CEA0FDFC6D3B4085823D60DC76F28855", "ActionKeyword": "*", "Name": "Calculator", - "Description": "Perform mathematical calculations (including hexadecimal values)", - "Author": "cxfksword", - "Version": "1.0.0", + "Description": "Perform mathematical calculations (including hexadecimal values). Use ',' or '.' as thousand separator or decimal place.", + "Author": "cxfksword, dcog989", + "Version": "1.1.0", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Calculator.dll", From c83a29fb1824e0f4d11a662bdee62c3b057ab1c1 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Wed, 23 Jul 2025 01:18:26 +0100 Subject: [PATCH 02/12] PR review changes --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 2787adbbcba..2894c215985 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -25,6 +25,8 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider @")+$", RegexOptions.Compiled); private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled); private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))"); + private static readonly Regex NumberRegex = new Regex(@"[\d\.,]+", RegexOptions.Compiled); + private static Engine MagesEngine; private const string comma = ","; private const string dot = "."; @@ -34,8 +36,15 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider private static Settings _settings; private static SettingsViewModel _viewModel; - private string _inputDecimalSeparator; - private bool _inputUsesGroupSeparators; + /// + /// Holds the formatting information for a single query. + /// This is used to ensure thread safety by keeping query state local. + /// + private class ParsingContext + { + public string InputDecimalSeparator { get; set; } + public bool InputUsesGroupSeparators { get; set; } + } public void Init(PluginInitContext context) { @@ -59,13 +68,11 @@ public List Query(Query query) return new List(); } - _inputDecimalSeparator = null; - _inputUsesGroupSeparators = false; + var context = new ParsingContext(); try { - var numberRegex = new Regex(@"[\d\.,]+"); - var expression = numberRegex.Replace(query.Search, m => NormalizeNumber(m.Value)); + var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value, context)); var result = MagesEngine.Interpret(expression); @@ -78,7 +85,7 @@ public List Query(Query query) if (!string.IsNullOrEmpty(result?.ToString())) { decimal roundedResult = Math.Round(Convert.ToDecimal(result), _settings.MaxDecimalPlaces, MidpointRounding.AwayFromZero); - string newResult = FormatResult(roundedResult); + string newResult = FormatResult(roundedResult, context); return new List { @@ -117,10 +124,10 @@ public List Query(Query query) /// /// Parses a string representation of a number, detecting its format. It uses structural analysis /// (checking for 3-digit groups) and falls back to system culture for ambiguous cases (e.g., "1,234"). - /// It sets instance fields to remember the user's format for later output formatting. + /// It populates the provided ParsingContext with the detected format for later use. /// /// A normalized number string with '.' as the decimal separator for the Mages engine. - private string NormalizeNumber(string numberStr) + private string NormalizeNumber(string numberStr, ParsingContext context) { var systemFormat = CultureInfo.CurrentCulture.NumberFormat; string systemDecimalSeparator = systemFormat.NumberDecimalSeparator; @@ -131,18 +138,18 @@ private string NormalizeNumber(string numberStr) // Unambiguous case: both separators are present. The last one wins as decimal separator. if (hasDot && hasComma) { - _inputUsesGroupSeparators = true; + context.InputUsesGroupSeparators = true; int lastDotPos = numberStr.LastIndexOf(dot); int lastCommaPos = numberStr.LastIndexOf(comma); if (lastDotPos > lastCommaPos) // e.g. 1,234.56 { - _inputDecimalSeparator = dot; + context.InputDecimalSeparator = dot; return numberStr.Replace(comma, string.Empty); } else // e.g. 1.234,56 { - _inputDecimalSeparator = comma; + context.InputDecimalSeparator = comma; return numberStr.Replace(dot, string.Empty).Replace(comma, dot); } } @@ -158,19 +165,19 @@ private string NormalizeNumber(string numberStr) // Ambiguous case: "1,234". Resolve using culture. if (systemDecimalSeparator == comma) { - _inputDecimalSeparator = comma; + context.InputDecimalSeparator = comma; return numberStr.Replace(comma, dot); } else { - _inputUsesGroupSeparators = true; + context.InputUsesGroupSeparators = true; return numberStr.Replace(comma, string.Empty); } } else { // Unambiguous decimal: "123,45" or "1,2,345" - _inputDecimalSeparator = comma; + context.InputDecimalSeparator = comma; return numberStr.Replace(comma, dot); } } @@ -184,18 +191,18 @@ private string NormalizeNumber(string numberStr) { if (systemDecimalSeparator == dot) { - _inputDecimalSeparator = dot; + context.InputDecimalSeparator = dot; return numberStr; } else { - _inputUsesGroupSeparators = true; + context.InputUsesGroupSeparators = true; return numberStr.Replace(dot, string.Empty); } } else { - _inputDecimalSeparator = dot; + context.InputDecimalSeparator = dot; return numberStr; // Already in Mages-compatible format } } @@ -204,10 +211,10 @@ private string NormalizeNumber(string numberStr) return numberStr; } - private string FormatResult(decimal roundedResult) + private string FormatResult(decimal roundedResult, ParsingContext context) { // Use the detected decimal separator from the input; otherwise, fall back to settings. - string decimalSeparator = _inputDecimalSeparator ?? GetDecimalSeparator(); + string decimalSeparator = context.InputDecimalSeparator ?? GetDecimalSeparator(); string groupSeparator = decimalSeparator == dot ? comma : dot; string resultStr = roundedResult.ToString(CultureInfo.InvariantCulture); @@ -216,7 +223,7 @@ private string FormatResult(decimal roundedResult) string integerPart = parts[0]; string fractionalPart = parts.Length > 1 ? parts[1] : string.Empty; - if (_inputUsesGroupSeparators) + if (context.InputUsesGroupSeparators) { integerPart = ThousandGroupRegex.Replace(integerPart, groupSeparator); } From 5161bbe660a5dce00034ed4cec77f12a59d71a06 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 23 Jul 2025 09:33:14 +0800 Subject: [PATCH 03/12] Remove unused comments & blank line --- .../Views/CalculatorSettings.xaml.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs index 117a19b25dc..d0d79cd72b1 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs @@ -1,11 +1,8 @@ -using System.Windows.Controls; +using System.Windows.Controls; using Flow.Launcher.Plugin.Calculator.ViewModels; namespace Flow.Launcher.Plugin.Calculator.Views { - /// - /// Interaction logic for CalculatorSettings.xaml - /// public partial class CalculatorSettings : UserControl { private readonly SettingsViewModel _viewModel; @@ -19,5 +16,4 @@ public CalculatorSettings(SettingsViewModel viewModel) InitializeComponent(); } } - } From 5ff8a5b1d59dd95ae8c0a79decb2714ee38e9cf8 Mon Sep 17 00:00:00 2001 From: Jack Ye <1160210343@qq.com> Date: Wed, 23 Jul 2025 09:59:09 +0800 Subject: [PATCH 04/12] Use compiled regex Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 2894c215985..b972394a45a 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -24,7 +24,7 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider @"[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]]" + @")+$", RegexOptions.Compiled); private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled); - private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))"); + private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled); private static readonly Regex NumberRegex = new Regex(@"[\d\.,]+", RegexOptions.Compiled); private static Engine MagesEngine; From 852b2f517be223e3a9be419ea61271a7eefd6206 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Wed, 23 Jul 2025 04:27:19 +0100 Subject: [PATCH 05/12] fix for regression from first review, plus issues with e.g. '0,123' and ',123' --- Flow.Launcher.Core/packages.lock.json | 84 +++-- .../packages.lock.json | 59 ++- Flow.Launcher.Plugin/packages.lock.json | 6 +- Flow.Launcher/packages.lock.json | 357 ++++++++++++++---- .../Flow.Launcher.Plugin.Calculator/Main.cs | 100 ++--- 5 files changed, 429 insertions(+), 177 deletions(-) diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json index 0c513951b82..dec7bf0b450 100644 --- a/Flow.Launcher.Core/packages.lock.json +++ b/Flow.Launcher.Core/packages.lock.json @@ -13,9 +13,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[9.0.101, )", - "resolved": "9.0.101", - "contentHash": "3/YR1SDWFA+Ojx9HiBwND+0UR8ZWoeZfkhD0DWAPCDdr/YI+CyFkArmMGzGSyPXeYtjG0sy0emzfyNwjt7zhig==" + "requested": "[9.0.201, )", + "resolved": "9.0.201", + "contentHash": "Ozq4T0ISTkqTYJ035XW/JkdDDaXofbykvfyVwkjLSqaDZ/4uNXfpf92cjcMI9lf9CxWqmlWHScViPh/4AvnWcw==" }, "Meziantou.Framework.Win32.Jobs": { "type": "Direct", @@ -29,6 +29,12 @@ "resolved": "3.0.1", "contentHash": "s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g==" }, + "SemanticVersioning": { + "type": "Direct", + "requested": "[3.0.0, )", + "resolved": "3.0.0", + "contentHash": "RR+8GbPQ/gjDqov/1QN1OPoUlbUruNwcL3WjWCeLw+MY7+od/ENhnkYxCfAC6rQLIu3QifaJt3kPYyP3RumqMQ==" + }, "squirrel.windows": { "type": "Direct", "requested": "[1.5.2, )", @@ -42,9 +48,9 @@ }, "StreamJsonRpc": { "type": "Direct", - "requested": "[2.20.20, )", - "resolved": "2.20.20", - "contentHash": "gwG7KViLbSWS7EI0kYevinVmIga9wZNrpSY/FnWyC6DbdjKJ1xlv/FV1L9b0rLkVP8cGxfIMexdvo/+2W5eq6Q==", + "requested": "[2.21.10, )", + "resolved": "2.21.10", + "contentHash": "wjBlFiaE+npUco9Jj4K11EEZfmAg4poRFYhcCJOiVdiHZ3UxapbGemtLNRcVYGXa/p8nqvZ38TfJPHnlrromDg==", "dependencies": { "MessagePack": "2.5.187", "Microsoft.VisualStudio.Threading": "17.10.48", @@ -78,6 +84,11 @@ "resolved": "1.0.0", "contentHash": "nwbZAYd+DblXAIzlnwDSnl0CiCm8jWLfHSYnoN4wYhtIav6AegB3+T/vKzLbU2IZlPB8Bvl8U3NXpx3eaz+N5w==" }, + "InputSimulator": { + "type": "Transitive", + "resolved": "1.0.4", + "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" + }, "JetBrains.Annotations": { "type": "Transitive", "resolved": "2024.3.0", @@ -85,22 +96,22 @@ }, "MemoryPack": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==", + "resolved": "1.21.4", + "contentHash": "wy3JTBNBsO8LfQcBvvYsWr3lm2Oakolrfu0UQ3oSJSEiD+7ye0GUhYTaXuYYBowqsXBXWD9gf2218ae0JRiYVQ==", "dependencies": { - "MemoryPack.Core": "1.21.3", - "MemoryPack.Generator": "1.21.3" + "MemoryPack.Core": "1.21.4", + "MemoryPack.Generator": "1.21.4" } }, "MemoryPack.Core": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA==" + "resolved": "1.21.4", + "contentHash": "6RszGorZ0ejNmp37ZcboPBMvvPCuNW2jlrdQfcs/lMzE5b3pmPF6hsm/laDc34hRlbAST1ZxaX/DvYu2DF5sBQ==" }, "MemoryPack.Generator": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA==" + "resolved": "1.21.4", + "contentHash": "g14EsSS85yn0lHTi0J9ivqlZMf09A2iI51fmI+0KkzIzyCbWOBWPi5mdaY7YWmXprk12aYh9u/qfWHQUYthlwg==" }, "MessagePack": { "type": "Transitive", @@ -142,8 +153,8 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.2", - "contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w==" + "resolved": "7.0.0", + "contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ==" }, "Mono.Cecil": { "type": "Transitive", @@ -165,18 +176,28 @@ "resolved": "13.0.1", "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" }, + "NHotkey": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A==" + }, + "NHotkey.Wpf": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==", + "dependencies": { + "NHotkey": "3.0.0" + } + }, "NLog": { "type": "Transitive", "resolved": "4.7.10", "contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow==" }, - "PropertyChanged.Fody": { + "SharpVectors.Wpf": { "type": "Transitive", - "resolved": "3.4.0", - "contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==", - "dependencies": { - "Fody": "6.5.1" - } + "resolved": "1.8.4.2", + "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" }, "Splat": { "type": "Transitive", @@ -185,10 +206,10 @@ }, "System.Drawing.Common": { "type": "Transitive", - "resolved": "9.0.2", - "contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==", + "resolved": "7.0.0", + "contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.2" + "Microsoft.Win32.SystemEvents": "7.0.0" } }, "System.IO.Pipelines": { @@ -217,20 +238,21 @@ "Ben.Demystifier": "[0.4.1, )", "BitFaster.Caching": "[2.5.3, )", "CommunityToolkit.Mvvm": "[8.4.0, )", - "Flow.Launcher.Plugin": "[4.4.0, )", - "MemoryPack": "[1.21.3, )", + "Flow.Launcher.Plugin": "[4.7.0, )", + "InputSimulator": "[1.0.4, )", + "MemoryPack": "[1.21.4, )", "Microsoft.VisualStudio.Threading": "[17.12.19, )", + "NHotkey.Wpf": "[3.0.0, )", "NLog": "[4.7.10, )", - "PropertyChanged.Fody": "[3.4.0, )", - "System.Drawing.Common": "[9.0.2, )", + "SharpVectors.Wpf": "[1.8.4.2, )", + "System.Drawing.Common": "[7.0.0, )", "ToolGood.Words.Pinyin": "[3.0.1.4, )" } }, "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )", - "PropertyChanged.Fody": "[3.4.0, )" + "JetBrains.Annotations": "[2024.3.0, )" } } } diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index f38f91ef97c..27dfd1cd638 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -29,14 +29,20 @@ "resolved": "6.5.5", "contentHash": "Krca41L/PDva1VsmDec5n52cQZxQAQp/bsHdzsNi8iLLI0lqKL94fNIkNaC8tVolUkCyWsbzvxfxJCeD2789fA==" }, + "InputSimulator": { + "type": "Direct", + "requested": "[1.0.4, )", + "resolved": "1.0.4", + "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" + }, "MemoryPack": { "type": "Direct", - "requested": "[1.21.3, )", - "resolved": "1.21.3", - "contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==", + "requested": "[1.21.4, )", + "resolved": "1.21.4", + "contentHash": "wy3JTBNBsO8LfQcBvvYsWr3lm2Oakolrfu0UQ3oSJSEiD+7ye0GUhYTaXuYYBowqsXBXWD9gf2218ae0JRiYVQ==", "dependencies": { - "MemoryPack.Core": "1.21.3", - "MemoryPack.Generator": "1.21.3" + "MemoryPack.Core": "1.21.4", + "MemoryPack.Generator": "1.21.4" } }, "Microsoft.VisualStudio.Threading": { @@ -60,6 +66,15 @@ "Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental" } }, + "NHotkey.Wpf": { + "type": "Direct", + "requested": "[3.0.0, )", + "resolved": "3.0.0", + "contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==", + "dependencies": { + "NHotkey": "3.0.0" + } + }, "NLog": { "type": "Direct", "requested": "[4.7.10, )", @@ -75,13 +90,19 @@ "Fody": "6.5.1" } }, + "SharpVectors.Wpf": { + "type": "Direct", + "requested": "[1.8.4.2, )", + "resolved": "1.8.4.2", + "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" + }, "System.Drawing.Common": { "type": "Direct", - "requested": "[9.0.2, )", - "resolved": "9.0.2", - "contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==", + "requested": "[7.0.0, )", + "resolved": "7.0.0", + "contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.2" + "Microsoft.Win32.SystemEvents": "7.0.0" } }, "ToolGood.Words.Pinyin": { @@ -97,13 +118,13 @@ }, "MemoryPack.Core": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA==" + "resolved": "1.21.4", + "contentHash": "6RszGorZ0ejNmp37ZcboPBMvvPCuNW2jlrdQfcs/lMzE5b3pmPF6hsm/laDc34hRlbAST1ZxaX/DvYu2DF5sBQ==" }, "MemoryPack.Generator": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA==" + "resolved": "1.21.4", + "contentHash": "g14EsSS85yn0lHTi0J9ivqlZMf09A2iI51fmI+0KkzIzyCbWOBWPi5mdaY7YWmXprk12aYh9u/qfWHQUYthlwg==" }, "Microsoft.VisualStudio.Threading.Analyzers": { "type": "Transitive", @@ -117,8 +138,8 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.2", - "contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w==" + "resolved": "7.0.0", + "contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ==" }, "Microsoft.Windows.SDK.Win32Docs": { "type": "Transitive", @@ -138,6 +159,11 @@ "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview" } }, + "NHotkey": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A==" + }, "System.Reflection.Metadata": { "type": "Transitive", "resolved": "5.0.0", @@ -146,8 +172,7 @@ "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )", - "PropertyChanged.Fody": "[3.4.0, )" + "JetBrains.Annotations": "[2024.3.0, )" } } } diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json index 6cdf96e0719..aad21a318f3 100644 --- a/Flow.Launcher.Plugin/packages.lock.json +++ b/Flow.Launcher.Plugin/packages.lock.json @@ -4,9 +4,9 @@ "net9.0-windows7.0": { "Fody": { "type": "Direct", - "requested": "[6.5.4, )", - "resolved": "6.5.4", - "contentHash": "GXZuti428IZctfby10xkMbWLCibcb6s29I/psLbBoO2vHJI5eTNVybnlV/Wi1tlIu9GG0bgW/PQwMH+MCldHxw==" + "requested": "[6.5.5, )", + "resolved": "6.5.5", + "contentHash": "Krca41L/PDva1VsmDec5n52cQZxQAQp/bsHdzsNi8iLLI0lqKL94fNIkNaC8tVolUkCyWsbzvxfxJCeD2789fA==" }, "JetBrains.Annotations": { "type": "Direct", diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index 0170650443a..f0409c131fe 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -16,25 +16,57 @@ }, "Fody": { "type": "Direct", - "requested": "[6.5.4, )", - "resolved": "6.5.4", - "contentHash": "GXZuti428IZctfby10xkMbWLCibcb6s29I/psLbBoO2vHJI5eTNVybnlV/Wi1tlIu9GG0bgW/PQwMH+MCldHxw==" + "requested": "[6.5.5, )", + "resolved": "6.5.5", + "contentHash": "Krca41L/PDva1VsmDec5n52cQZxQAQp/bsHdzsNi8iLLI0lqKL94fNIkNaC8tVolUkCyWsbzvxfxJCeD2789fA==" }, - "InputSimulator": { + "MdXaml": { "type": "Direct", - "requested": "[1.0.4, )", - "resolved": "1.0.4", - "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" + "requested": "[1.27.0, )", + "resolved": "1.27.0", + "contentHash": "VWhqhCeKVkJe8vkPmXuGZlRX01WDrTugOLeUvJn18jH/8DrGGVBvtgIlJoELHD2f1DiEWqF3lxxjV55vnzE7Tg==", + "dependencies": { + "AvalonEdit": "6.3.0.90", + "MdXaml.Plugins": "1.27.0" + } }, - "Jack251970.TaskScheduler": { + "MdXaml.AnimatedGif": { "type": "Direct", - "requested": "[2.12.1, )", - "resolved": "2.12.1", - "contentHash": "+epAtsLMugiznJCNRYCYB6eBcr+bx+CVlwPWMprO5CbnNkWu9mlSV8XN5BQJrGYwmlAtlGfZA3p3PcFFlrgR6A==", + "requested": "[1.27.0, )", + "resolved": "1.27.0", + "contentHash": "Xrr9IgyAfqDbruqCp2Wxzthbc87QMvMR2YXQsGDyacLtowleefP1Jt3cesZCbI44YcZTGjyJNIkvRAyzzlgsOQ==", "dependencies": { - "Microsoft.Win32.Registry": "5.0.0", - "System.Diagnostics.EventLog": "8.0.0", - "System.Security.AccessControl": "6.0.1" + "MdXaml.Plugins": "1.27.0", + "WpfAnimatedGif": "2.0.2" + } + }, + "MdXaml.Html": { + "type": "Direct", + "requested": "[1.27.0, )", + "resolved": "1.27.0", + "contentHash": "3AI0g7EwsTuvhhNd9bjb3J7v5aXFk1dLaf1CNbLjkcZs/MwnEUHNgzF+sLQBYYVdG2DqfV1BsuFoPWSG7IdHvg==", + "dependencies": { + "AvalonEdit": "6.3.0.90", + "HtmlAgilityPack": "1.11.42", + "MdXaml": "1.27.0", + "MdXaml.Plugins": "1.27.0" + } + }, + "MdXaml.Plugins": { + "type": "Direct", + "requested": "[1.27.0, )", + "resolved": "1.27.0", + "contentHash": "We7LtBdoukRg9mqTfa1f5n8z/GQPMKBRj3URk9DiMuqzIHkW1lTgK5njVPSScxsRt4YzW22423tSnLWNm2MJKg==" + }, + "MdXaml.Svg": { + "type": "Direct", + "requested": "[1.27.0, )", + "resolved": "1.27.0", + "contentHash": "zHtzcQrEVDoTDRvxFAccAIQG3UHCUW2cdWrGCg9yfT6344hhqc6d9t/93kBqQ6j+f580YeevtMeraz9PWmzpfw==", + "dependencies": { + "MdXaml": "1.27.0", + "MdXaml.Plugins": "1.27.0", + "Svg": "3.0.84" } }, "Microsoft.Extensions.DependencyInjection": { @@ -88,32 +120,12 @@ "System.ValueTuple": "4.5.0" } }, - "Microsoft.Windows.CsWin32": { - "type": "Direct", - "requested": "[0.3.106, )", - "resolved": "0.3.106", - "contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==", - "dependencies": { - "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", - "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview", - "Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental" - } - }, "ModernWpfUI": { "type": "Direct", "requested": "[0.9.4, )", "resolved": "0.9.4", "contentHash": "HJ07Be9KOiGKGcMLz/AwY+84h3yGHRPuYpYXCE6h1yPtaFwGMWfanZ70jX7W5XWx8+Qk1vGox+WGKgxxsy6EHw==" }, - "NHotkey.Wpf": { - "type": "Direct", - "requested": "[3.0.0, )", - "resolved": "3.0.0", - "contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==", - "dependencies": { - "NHotkey": "3.0.0" - } - }, "PropertyChanged.Fody": { "type": "Direct", "requested": "[3.4.0, )", @@ -129,12 +141,28 @@ "resolved": "3.0.0", "contentHash": "RR+8GbPQ/gjDqov/1QN1OPoUlbUruNwcL3WjWCeLw+MY7+od/ENhnkYxCfAC6rQLIu3QifaJt3kPYyP3RumqMQ==" }, + "TaskScheduler": { + "type": "Direct", + "requested": "[2.12.1, )", + "resolved": "2.12.1", + "contentHash": "DzSVmVs0i5yHmuDy9ZMcTtKg48GU0aEFBbhp2XJrzA4saTRec/KbU5aGE/4P4FE499G3PDx9KPOHysoKzS/i3g==", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0", + "System.Diagnostics.EventLog": "9.0.2", + "System.Security.AccessControl": "6.0.1" + } + }, "VirtualizingWrapPanel": { "type": "Direct", "requested": "[2.1.1, )", "resolved": "2.1.1", "contentHash": "Fc/yjU8jqC3qpIsNxeO5RjK2lPU7xnJtBLMSQ6L9egA2PyJLQeVeXpG8WBb5N1kN15rlJEYG8dHWJ5qUGgaNrg==" }, + "AvalonEdit": { + "type": "Transitive", + "resolved": "6.3.0.90", + "contentHash": "WVTb5MxwGqKdeasd3nG5udlV4t6OpvkFanziwI133K0/QJ5FvZmfzRQgpAjGTJhQfIA8GP7AzKQ3sTY9JOFk8Q==" + }, "Ben.Demystifier": { "type": "Transitive", "resolved": "0.4.1", @@ -161,10 +189,25 @@ "YamlDotNet": "9.1.0" } }, + "Fizzler": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "jH8KFyDJtgqLl3jZwbwgR3nA9dyebKPBgLwBx0bjPvxvvoCqHPD5IPedRGYzki8RYFpjxCFMlLtnNFPYq2OgmQ==" + }, "FSharp.Core": { "type": "Transitive", - "resolved": "9.0.101", - "contentHash": "3/YR1SDWFA+Ojx9HiBwND+0UR8ZWoeZfkhD0DWAPCDdr/YI+CyFkArmMGzGSyPXeYtjG0sy0emzfyNwjt7zhig==" + "resolved": "9.0.201", + "contentHash": "Ozq4T0ISTkqTYJ035XW/JkdDDaXofbykvfyVwkjLSqaDZ/4uNXfpf92cjcMI9lf9CxWqmlWHScViPh/4AvnWcw==" + }, + "HtmlAgilityPack": { + "type": "Transitive", + "resolved": "1.11.42", + "contentHash": "LDc1bEfF14EY2DZzak4xvzWvbpNXK3vi1u0KQbBpLUN4+cx/VrvXhgCAMSJhSU5vz0oMfW9JZIR20vj/PkDHPA==" + }, + "InputSimulator": { + "type": "Transitive", + "resolved": "1.0.4", + "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" }, "JetBrains.Annotations": { "type": "Transitive", @@ -173,22 +216,22 @@ }, "MemoryPack": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==", + "resolved": "1.21.4", + "contentHash": "wy3JTBNBsO8LfQcBvvYsWr3lm2Oakolrfu0UQ3oSJSEiD+7ye0GUhYTaXuYYBowqsXBXWD9gf2218ae0JRiYVQ==", "dependencies": { - "MemoryPack.Core": "1.21.3", - "MemoryPack.Generator": "1.21.3" + "MemoryPack.Core": "1.21.4", + "MemoryPack.Generator": "1.21.4" } }, "MemoryPack.Core": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA==" + "resolved": "1.21.4", + "contentHash": "6RszGorZ0ejNmp37ZcboPBMvvPCuNW2jlrdQfcs/lMzE5b3pmPF6hsm/laDc34hRlbAST1ZxaX/DvYu2DF5sBQ==" }, "MemoryPack.Generator": { "type": "Transitive", - "resolved": "1.21.3", - "contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA==" + "resolved": "1.21.4", + "contentHash": "g14EsSS85yn0lHTi0J9ivqlZMf09A2iI51fmI+0KkzIzyCbWOBWPi5mdaY7YWmXprk12aYh9u/qfWHQUYthlwg==" }, "MessagePack": { "type": "Transitive", @@ -440,6 +483,16 @@ "resolved": "17.6.3", "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "Microsoft.VisualStudio.Threading": { "type": "Transitive", "resolved": "17.12.19", @@ -470,26 +523,8 @@ }, "Microsoft.Win32.SystemEvents": { "type": "Transitive", - "resolved": "9.0.2", - "contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w==" - }, - "Microsoft.Windows.SDK.Win32Docs": { - "type": "Transitive", - "resolved": "0.1.42-alpha", - "contentHash": "Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA==" - }, - "Microsoft.Windows.SDK.Win32Metadata": { - "type": "Transitive", - "resolved": "60.0.34-preview", - "contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA==" - }, - "Microsoft.Windows.WDK.Win32Metadata": { - "type": "Transitive", - "resolved": "0.11.4-experimental", - "contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==", - "dependencies": { - "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview" - } + "resolved": "7.0.0", + "contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ==" }, "Mono.Cecil": { "type": "Transitive", @@ -516,11 +551,29 @@ "resolved": "3.0.0", "contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A==" }, + "NHotkey.Wpf": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==", + "dependencies": { + "NHotkey": "3.0.0" + } + }, "NLog": { "type": "Transitive", "resolved": "4.7.10", "contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow==" }, + "runtime.osx.10.10-x64.CoreCompat.System.Drawing": { + "type": "Transitive", + "resolved": "5.8.64", + "contentHash": "Ey7xQgWwixxdrmhzEUvaR4kxZDSQMWQScp8ViLvmL5xCBKG6U3TaMv/jzHilpfQXpHmJ4IylKGzzMvnYX2FwHQ==" + }, + "SharpVectors.Wpf": { + "type": "Transitive", + "resolved": "1.8.4.2", + "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" + }, "Splat": { "type": "Transitive", "resolved": "1.6.2", @@ -538,8 +591,8 @@ }, "StreamJsonRpc": { "type": "Transitive", - "resolved": "2.20.20", - "contentHash": "gwG7KViLbSWS7EI0kYevinVmIga9wZNrpSY/FnWyC6DbdjKJ1xlv/FV1L9b0rLkVP8cGxfIMexdvo/+2W5eq6Q==", + "resolved": "2.21.10", + "contentHash": "wjBlFiaE+npUco9Jj4K11EEZfmAg4poRFYhcCJOiVdiHZ3UxapbGemtLNRcVYGXa/p8nqvZ38TfJPHnlrromDg==", "dependencies": { "MessagePack": "2.5.187", "Microsoft.VisualStudio.Threading": "17.10.48", @@ -550,6 +603,37 @@ "System.IO.Pipelines": "8.0.0" } }, + "Svg": { + "type": "Transitive", + "resolved": "3.0.84", + "contentHash": "QI35/+zRerIuOTBAw0GhbEQhuesSd3nYha9ibgyv6ofe4XRpFSjaXyQJJGssaUVZaBb2vwMAFKqb5uWnTAB2Sg==", + "dependencies": { + "Fizzler": "1.1.0", + "System.Drawing.Common": "4.5.1", + "System.ObjectModel": "4.3.0", + "runtime.osx.10.10-x64.CoreCompat.System.Drawing": "5.8.64" + } + }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Diagnostics.Debug": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "7.0.1", @@ -557,15 +641,37 @@ }, "System.Diagnostics.EventLog": { "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==" + "resolved": "9.0.2", + "contentHash": "i+Fe6Fpst/onydFLBGilCr/Eh9OFdlaTU/c3alPp6IbLZXQJOgpIu3l4MOnmsN8fDYq5nAyHSqNIJesc74Yw3Q==" }, "System.Drawing.Common": { "type": "Transitive", - "resolved": "9.0.2", - "contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==", + "resolved": "7.0.0", + "contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==", "dependencies": { - "Microsoft.Win32.SystemEvents": "9.0.2" + "Microsoft.Win32.SystemEvents": "7.0.0" + } + }, + "System.Globalization": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" } }, "System.IO.Pipelines": { @@ -573,6 +679,30 @@ "resolved": "8.0.0", "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" }, + "System.ObjectModel": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, "System.Reflection.Emit": { "type": "Transitive", "resolved": "4.7.0", @@ -583,6 +713,37 @@ "resolved": "5.0.0", "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Resources.ResourceManager": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "6.0.1", @@ -593,6 +754,16 @@ "resolved": "5.0.0", "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Text.Encodings.Web": { "type": "Transitive", "resolved": "7.0.0", @@ -606,6 +777,25 @@ "System.Text.Encodings.Web": "7.0.0" } }, + "System.Threading": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==", + "dependencies": { + "System.Runtime": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.ValueTuple": { "type": "Transitive", "resolved": "4.5.0", @@ -616,6 +806,11 @@ "resolved": "3.0.1.4", "contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew==" }, + "WpfAnimatedGif": { + "type": "Transitive", + "resolved": "2.0.2", + "contentHash": "B0j9SqtThyHVTiOPvu6yR+39Te0g3o+7Jjb+qEm7+Iz1HRqbE5/4QV+ntHWOYYBPOUFr9x1mdzGl/EzWP+nKiA==" + }, "YamlDotNet": { "type": "Transitive", "resolved": "9.1.0", @@ -625,12 +820,13 @@ "type": "Project", "dependencies": { "Droplex": "[1.7.0, )", - "FSharp.Core": "[9.0.101, )", + "FSharp.Core": "[9.0.201, )", "Flow.Launcher.Infrastructure": "[1.0.0, )", - "Flow.Launcher.Plugin": "[4.4.0, )", + "Flow.Launcher.Plugin": "[4.7.0, )", "Meziantou.Framework.Win32.Jobs": "[3.4.0, )", "Microsoft.IO.RecyclableMemoryStream": "[3.0.1, )", - "StreamJsonRpc": "[2.20.20, )", + "SemanticVersioning": "[3.0.0, )", + "StreamJsonRpc": "[2.21.10, )", "squirrel.windows": "[1.5.2, )" } }, @@ -640,20 +836,21 @@ "Ben.Demystifier": "[0.4.1, )", "BitFaster.Caching": "[2.5.3, )", "CommunityToolkit.Mvvm": "[8.4.0, )", - "Flow.Launcher.Plugin": "[4.4.0, )", - "MemoryPack": "[1.21.3, )", + "Flow.Launcher.Plugin": "[4.7.0, )", + "InputSimulator": "[1.0.4, )", + "MemoryPack": "[1.21.4, )", "Microsoft.VisualStudio.Threading": "[17.12.19, )", + "NHotkey.Wpf": "[3.0.0, )", "NLog": "[4.7.10, )", - "PropertyChanged.Fody": "[3.4.0, )", - "System.Drawing.Common": "[9.0.2, )", + "SharpVectors.Wpf": "[1.8.4.2, )", + "System.Drawing.Common": "[7.0.0, )", "ToolGood.Words.Pinyin": "[3.0.1.4, )" } }, "flow.launcher.plugin": { "type": "Project", "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )", - "PropertyChanged.Fody": "[3.4.0, )" + "JetBrains.Annotations": "[2024.3.0, )" } } } diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 2894c215985..afd0ddfe5a4 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -24,7 +24,7 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider @"[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]]" + @")+$", RegexOptions.Compiled); private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled); - private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))"); + private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled); private static readonly Regex NumberRegex = new Regex(@"[\d\.,]+", RegexOptions.Compiled); private static Engine MagesEngine; @@ -120,100 +120,108 @@ public List Query(Query query) return new List(); } - + /// /// Parses a string representation of a number, detecting its format. It uses structural analysis - /// (checking for 3-digit groups) and falls back to system culture for ambiguous cases (e.g., "1,234"). + /// and falls back to system culture for truly ambiguous cases (e.g., "1,234"). /// It populates the provided ParsingContext with the detected format for later use. /// /// A normalized number string with '.' as the decimal separator for the Mages engine. private string NormalizeNumber(string numberStr, ParsingContext context) { - var systemFormat = CultureInfo.CurrentCulture.NumberFormat; - string systemDecimalSeparator = systemFormat.NumberDecimalSeparator; - - bool hasDot = numberStr.Contains(dot); - bool hasComma = numberStr.Contains(comma); + var systemGroupSep = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; + int dotCount = numberStr.Count(f => f == '.'); + int commaCount = numberStr.Count(f => f == ','); - // Unambiguous case: both separators are present. The last one wins as decimal separator. - if (hasDot && hasComma) + // Case 1: Unambiguous mixed separators (e.g., "1.234,56") + if (dotCount > 0 && commaCount > 0) { context.InputUsesGroupSeparators = true; - int lastDotPos = numberStr.LastIndexOf(dot); - int lastCommaPos = numberStr.LastIndexOf(comma); - - if (lastDotPos > lastCommaPos) // e.g. 1,234.56 + if (numberStr.LastIndexOf('.') > numberStr.LastIndexOf(',')) { context.InputDecimalSeparator = dot; return numberStr.Replace(comma, string.Empty); } - else // e.g. 1.234,56 + else { context.InputDecimalSeparator = comma; return numberStr.Replace(dot, string.Empty).Replace(comma, dot); } } - if (hasComma) + // Case 2: Only dots + if (dotCount > 0) { - string[] parts = numberStr.Split(','); - // If all parts after the first are 3 digits, it's a potential group separator. - bool isGroupCandidate = parts.Length > 1 && parts.Skip(1).All(p => p.Length == 3); - - if (isGroupCandidate) + if (dotCount > 1) { - // Ambiguous case: "1,234". Resolve using culture. - if (systemDecimalSeparator == comma) + context.InputUsesGroupSeparators = true; + return numberStr.Replace(dot, string.Empty); + } + // A number is ambiguous if it has a single dot in the thousands position, + // and does not start with a "0." or "." + bool isAmbiguous = numberStr.Length - numberStr.LastIndexOf('.') == 4 + && !numberStr.StartsWith("0.") + && !numberStr.StartsWith("."); + if (isAmbiguous) + { + if (systemGroupSep == dot) { - context.InputDecimalSeparator = comma; - return numberStr.Replace(comma, dot); + context.InputUsesGroupSeparators = true; + return numberStr.Replace(dot, string.Empty); } else { - context.InputUsesGroupSeparators = true; - return numberStr.Replace(comma, string.Empty); + context.InputDecimalSeparator = dot; + return numberStr; } } - else + else // Unambiguous decimal (e.g., "12.34" or "0.123" or ".123") { - // Unambiguous decimal: "123,45" or "1,2,345" - context.InputDecimalSeparator = comma; - return numberStr.Replace(comma, dot); + context.InputDecimalSeparator = dot; + return numberStr; } } - if (hasDot) + // Case 3: Only commas + if (commaCount > 0) { - string[] parts = numberStr.Split('.'); - bool isGroupCandidate = parts.Length > 1 && parts.Skip(1).All(p => p.Length == 3); - - if (isGroupCandidate) + if (commaCount > 1) + { + context.InputUsesGroupSeparators = true; + return numberStr.Replace(comma, string.Empty); + } + // A number is ambiguous if it has a single comma in the thousands position, + // and does not start with a "0," or "," + bool isAmbiguous = numberStr.Length - numberStr.LastIndexOf(',') == 4 + && !numberStr.StartsWith("0,") + && !numberStr.StartsWith(","); + if (isAmbiguous) { - if (systemDecimalSeparator == dot) + if (systemGroupSep == comma) { - context.InputDecimalSeparator = dot; - return numberStr; + context.InputUsesGroupSeparators = true; + return numberStr.Replace(comma, string.Empty); } else { - context.InputUsesGroupSeparators = true; - return numberStr.Replace(dot, string.Empty); + context.InputDecimalSeparator = comma; + return numberStr.Replace(comma, dot); } } - else + else // Unambiguous decimal (e.g., "12,34" or "0,123" or ",123") { - context.InputDecimalSeparator = dot; - return numberStr; // Already in Mages-compatible format + context.InputDecimalSeparator = comma; + return numberStr.Replace(comma, dot); } } - // No separators. + // Case 4: No separators return numberStr; } + private string FormatResult(decimal roundedResult, ParsingContext context) { - // Use the detected decimal separator from the input; otherwise, fall back to settings. string decimalSeparator = context.InputDecimalSeparator ?? GetDecimalSeparator(); string groupSeparator = decimalSeparator == dot ? comma : dot; From cf40045acdc31740782c036e87d8593aaca681fd Mon Sep 17 00:00:00 2001 From: dcog989 <89043002+dcog989@users.noreply.github.com> Date: Wed, 23 Jul 2025 04:34:54 +0100 Subject: [PATCH 06/12] Delete Flow.Launcher.Core/packages.lock.json --- Flow.Launcher.Core/packages.lock.json | 260 -------------------------- 1 file changed, 260 deletions(-) delete mode 100644 Flow.Launcher.Core/packages.lock.json diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json deleted file mode 100644 index dec7bf0b450..00000000000 --- a/Flow.Launcher.Core/packages.lock.json +++ /dev/null @@ -1,260 +0,0 @@ -{ - "version": 1, - "dependencies": { - "net9.0-windows7.0": { - "Droplex": { - "type": "Direct", - "requested": "[1.7.0, )", - "resolved": "1.7.0", - "contentHash": "wutfIus/Ufw/9TDsp86R1ycnIH+wWrj4UhcmrzAHWjsdyC2iM07WEQ9+APTB7pQynsDnYH1r2i58XgAJ3lxUXA==", - "dependencies": { - "YamlDotNet": "9.1.0" - } - }, - "FSharp.Core": { - "type": "Direct", - "requested": "[9.0.201, )", - "resolved": "9.0.201", - "contentHash": "Ozq4T0ISTkqTYJ035XW/JkdDDaXofbykvfyVwkjLSqaDZ/4uNXfpf92cjcMI9lf9CxWqmlWHScViPh/4AvnWcw==" - }, - "Meziantou.Framework.Win32.Jobs": { - "type": "Direct", - "requested": "[3.4.0, )", - "resolved": "3.4.0", - "contentHash": "5GGLckfpwoC1jznInEYfK2INrHyD7K1RtwZJ98kNPKBU6jeu24i4zfgDGHHfb+eK3J+eFPAxo0aYcbUxNXIbNw==" - }, - "Microsoft.IO.RecyclableMemoryStream": { - "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g==" - }, - "SemanticVersioning": { - "type": "Direct", - "requested": "[3.0.0, )", - "resolved": "3.0.0", - "contentHash": "RR+8GbPQ/gjDqov/1QN1OPoUlbUruNwcL3WjWCeLw+MY7+od/ENhnkYxCfAC6rQLIu3QifaJt3kPYyP3RumqMQ==" - }, - "squirrel.windows": { - "type": "Direct", - "requested": "[1.5.2, )", - "resolved": "1.5.2", - "contentHash": "89Y/CFxWm7SEOjvuV2stVa8p+SNM9GOLk4tUNm2nUF792nfkimAgwRA/umVsdyd/OXBH8byXSh4V1qck88ZAyQ==", - "dependencies": { - "DeltaCompressionDotNet": "[1.0.0, 2.0.0)", - "Mono.Cecil": "0.9.6.1", - "Splat": "1.6.2" - } - }, - "StreamJsonRpc": { - "type": "Direct", - "requested": "[2.21.10, )", - "resolved": "2.21.10", - "contentHash": "wjBlFiaE+npUco9Jj4K11EEZfmAg4poRFYhcCJOiVdiHZ3UxapbGemtLNRcVYGXa/p8nqvZ38TfJPHnlrromDg==", - "dependencies": { - "MessagePack": "2.5.187", - "Microsoft.VisualStudio.Threading": "17.10.48", - "Microsoft.VisualStudio.Threading.Analyzers": "17.10.48", - "Microsoft.VisualStudio.Validation": "17.8.8", - "Nerdbank.Streams": "2.11.74", - "Newtonsoft.Json": "13.0.1", - "System.IO.Pipelines": "8.0.0" - } - }, - "Ben.Demystifier": { - "type": "Transitive", - "resolved": "0.4.1", - "contentHash": "axFeEMfmEORy3ipAzOXG/lE+KcNptRbei3F0C4kQCdeiQtW+qJW90K5iIovITGrdLt8AjhNCwk5qLSX9/rFpoA==", - "dependencies": { - "System.Reflection.Metadata": "5.0.0" - } - }, - "BitFaster.Caching": { - "type": "Transitive", - "resolved": "2.5.3", - "contentHash": "Vo/39qcam5Xe+DbyfH0JZyqPswdOoa7jv4PGtRJ6Wj8AU+aZ+TuJRlJcIe+MQjRTJwliI8k8VSQpN8sEoBIv2g==" - }, - "CommunityToolkit.Mvvm": { - "type": "Transitive", - "resolved": "8.4.0", - "contentHash": "tqVU8yc/ADO9oiTRyTnwhFN68hCwvkliMierptWOudIAvWY1mWCh5VFh+guwHJmpMwfg0J0rY+yyd5Oy7ty9Uw==" - }, - "DeltaCompressionDotNet": { - "type": "Transitive", - "resolved": "1.0.0", - "contentHash": "nwbZAYd+DblXAIzlnwDSnl0CiCm8jWLfHSYnoN4wYhtIav6AegB3+T/vKzLbU2IZlPB8Bvl8U3NXpx3eaz+N5w==" - }, - "InputSimulator": { - "type": "Transitive", - "resolved": "1.0.4", - "contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA==" - }, - "JetBrains.Annotations": { - "type": "Transitive", - "resolved": "2024.3.0", - "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" - }, - "MemoryPack": { - "type": "Transitive", - "resolved": "1.21.4", - "contentHash": "wy3JTBNBsO8LfQcBvvYsWr3lm2Oakolrfu0UQ3oSJSEiD+7ye0GUhYTaXuYYBowqsXBXWD9gf2218ae0JRiYVQ==", - "dependencies": { - "MemoryPack.Core": "1.21.4", - "MemoryPack.Generator": "1.21.4" - } - }, - "MemoryPack.Core": { - "type": "Transitive", - "resolved": "1.21.4", - "contentHash": "6RszGorZ0ejNmp37ZcboPBMvvPCuNW2jlrdQfcs/lMzE5b3pmPF6hsm/laDc34hRlbAST1ZxaX/DvYu2DF5sBQ==" - }, - "MemoryPack.Generator": { - "type": "Transitive", - "resolved": "1.21.4", - "contentHash": "g14EsSS85yn0lHTi0J9ivqlZMf09A2iI51fmI+0KkzIzyCbWOBWPi5mdaY7YWmXprk12aYh9u/qfWHQUYthlwg==" - }, - "MessagePack": { - "type": "Transitive", - "resolved": "2.5.187", - "contentHash": "uW4j8m4Nc+2Mk5n6arOChavJ9bLjkis0qWASOj2h2OwmfINuzYv+mjCHUymrYhmyyKTu3N+ObtTXAY4uQ7jIhg==", - "dependencies": { - "MessagePack.Annotations": "2.5.187", - "Microsoft.NET.StringTools": "17.6.3" - } - }, - "MessagePack.Annotations": { - "type": "Transitive", - "resolved": "2.5.187", - "contentHash": "/IvvMMS8opvlHjEJ/fR2Cal4Co726Kj77Z8KiohFhuHfLHHmb9uUxW5+tSCL4ToKFfkQlrS3HD638mRq83ySqA==" - }, - "Microsoft.NET.StringTools": { - "type": "Transitive", - "resolved": "17.6.3", - "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" - }, - "Microsoft.VisualStudio.Threading": { - "type": "Transitive", - "resolved": "17.12.19", - "contentHash": "eLiGMkMYyaSguqHs3lsrFxy3tAWSLuPEL2pIWRcADMDVAs2xqm3dr1d9QYjiEusTgiClF9KD6OB2NdZP72Oy0Q==", - "dependencies": { - "Microsoft.VisualStudio.Threading.Analyzers": "17.12.19", - "Microsoft.VisualStudio.Validation": "17.8.8" - } - }, - "Microsoft.VisualStudio.Threading.Analyzers": { - "type": "Transitive", - "resolved": "17.12.19", - "contentHash": "v3IYeedjoktvZ+GqYmLudxZJngmf/YWIxNT2Uy6QMMN19cvw+nkWoip1Gr1RtnFkUo1MPUVMis4C8Kj8d8DpSQ==" - }, - "Microsoft.VisualStudio.Validation": { - "type": "Transitive", - "resolved": "17.8.8", - "contentHash": "rWXThIpyQd4YIXghNkiv2+VLvzS+MCMKVRDR0GAMlflsdo+YcAN2g2r5U1Ah98OFjQMRexTFtXQQ2LkajxZi3g==" - }, - "Microsoft.Win32.SystemEvents": { - "type": "Transitive", - "resolved": "7.0.0", - "contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ==" - }, - "Mono.Cecil": { - "type": "Transitive", - "resolved": "0.9.6.1", - "contentHash": "yMsurNaOxxKIjyW9pEB+tRrR1S3DFnN1+iBgKvYvXG8kW0Y6yknJeMAe/tl3+P78/2C6304TgF7aVqpqXgEQ9Q==" - }, - "Nerdbank.Streams": { - "type": "Transitive", - "resolved": "2.11.74", - "contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==", - "dependencies": { - "Microsoft.VisualStudio.Threading": "17.10.48", - "Microsoft.VisualStudio.Validation": "17.8.8", - "System.IO.Pipelines": "8.0.0" - } - }, - "Newtonsoft.Json": { - "type": "Transitive", - "resolved": "13.0.1", - "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" - }, - "NHotkey": { - "type": "Transitive", - "resolved": "3.0.0", - "contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A==" - }, - "NHotkey.Wpf": { - "type": "Transitive", - "resolved": "3.0.0", - "contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==", - "dependencies": { - "NHotkey": "3.0.0" - } - }, - "NLog": { - "type": "Transitive", - "resolved": "4.7.10", - "contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow==" - }, - "SharpVectors.Wpf": { - "type": "Transitive", - "resolved": "1.8.4.2", - "contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng==" - }, - "Splat": { - "type": "Transitive", - "resolved": "1.6.2", - "contentHash": "DeH0MxPU+D4JchkIDPYG4vUT+hsWs9S41cFle0/4K5EJMXWurx5DzAkj2366DfK14/XKNhsu6tCl4dZXJ3CD4w==" - }, - "System.Drawing.Common": { - "type": "Transitive", - "resolved": "7.0.0", - "contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==", - "dependencies": { - "Microsoft.Win32.SystemEvents": "7.0.0" - } - }, - "System.IO.Pipelines": { - "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" - }, - "System.Reflection.Metadata": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" - }, - "ToolGood.Words.Pinyin": { - "type": "Transitive", - "resolved": "3.0.1.4", - "contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew==" - }, - "YamlDotNet": { - "type": "Transitive", - "resolved": "9.1.0", - "contentHash": "fuvGXU4Ec5HrsmEc+BiFTNPCRf1cGBI2kh/3RzMWgddM2M4ALhbSPoI3X3mhXZUD1qqQd9oSkFAtWjpz8z9eRg==" - }, - "flow.launcher.infrastructure": { - "type": "Project", - "dependencies": { - "Ben.Demystifier": "[0.4.1, )", - "BitFaster.Caching": "[2.5.3, )", - "CommunityToolkit.Mvvm": "[8.4.0, )", - "Flow.Launcher.Plugin": "[4.7.0, )", - "InputSimulator": "[1.0.4, )", - "MemoryPack": "[1.21.4, )", - "Microsoft.VisualStudio.Threading": "[17.12.19, )", - "NHotkey.Wpf": "[3.0.0, )", - "NLog": "[4.7.10, )", - "SharpVectors.Wpf": "[1.8.4.2, )", - "System.Drawing.Common": "[7.0.0, )", - "ToolGood.Words.Pinyin": "[3.0.1.4, )" - } - }, - "flow.launcher.plugin": { - "type": "Project", - "dependencies": { - "JetBrains.Annotations": "[2024.3.0, )" - } - } - } - } -} \ No newline at end of file From 1fed54b615d7f1fb2a475801cd559157b3434769 Mon Sep 17 00:00:00 2001 From: dcog989 <89043002+dcog989@users.noreply.github.com> Date: Wed, 23 Jul 2025 04:35:18 +0100 Subject: [PATCH 07/12] Delete Flow.Launcher.Plugin/packages.lock.json --- Flow.Launcher.Plugin/packages.lock.json | 77 ------------------------- 1 file changed, 77 deletions(-) delete mode 100644 Flow.Launcher.Plugin/packages.lock.json diff --git a/Flow.Launcher.Plugin/packages.lock.json b/Flow.Launcher.Plugin/packages.lock.json deleted file mode 100644 index aad21a318f3..00000000000 --- a/Flow.Launcher.Plugin/packages.lock.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "version": 1, - "dependencies": { - "net9.0-windows7.0": { - "Fody": { - "type": "Direct", - "requested": "[6.5.5, )", - "resolved": "6.5.5", - "contentHash": "Krca41L/PDva1VsmDec5n52cQZxQAQp/bsHdzsNi8iLLI0lqKL94fNIkNaC8tVolUkCyWsbzvxfxJCeD2789fA==" - }, - "JetBrains.Annotations": { - "type": "Direct", - "requested": "[2024.3.0, )", - "resolved": "2024.3.0", - "contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug==" - }, - "Microsoft.SourceLink.GitHub": { - "type": "Direct", - "requested": "[1.1.1, )", - "resolved": "1.1.1", - "contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==", - "dependencies": { - "Microsoft.Build.Tasks.Git": "1.1.1", - "Microsoft.SourceLink.Common": "1.1.1" - } - }, - "Microsoft.Windows.CsWin32": { - "type": "Direct", - "requested": "[0.3.106, )", - "resolved": "0.3.106", - "contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==", - "dependencies": { - "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", - "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview", - "Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental" - } - }, - "PropertyChanged.Fody": { - "type": "Direct", - "requested": "[3.4.0, )", - "resolved": "3.4.0", - "contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==", - "dependencies": { - "Fody": "6.5.1" - } - }, - "Microsoft.Build.Tasks.Git": { - "type": "Transitive", - "resolved": "1.1.1", - "contentHash": "AT3HlgTjsqHnWpBHSNeR0KxbLZD7bztlZVj7I8vgeYG9SYqbeFGh0TM/KVtC6fg53nrWHl3VfZFvb5BiQFcY6Q==" - }, - "Microsoft.SourceLink.Common": { - "type": "Transitive", - "resolved": "1.1.1", - "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" - }, - "Microsoft.Windows.SDK.Win32Docs": { - "type": "Transitive", - "resolved": "0.1.42-alpha", - "contentHash": "Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA==" - }, - "Microsoft.Windows.SDK.Win32Metadata": { - "type": "Transitive", - "resolved": "60.0.34-preview", - "contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA==" - }, - "Microsoft.Windows.WDK.Win32Metadata": { - "type": "Transitive", - "resolved": "0.11.4-experimental", - "contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==", - "dependencies": { - "Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview" - } - } - } - } -} \ No newline at end of file From 4d22e6c352c4d1b70d6fe67b29ff0d3f201ecaae Mon Sep 17 00:00:00 2001 From: dcog989 <89043002+dcog989@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:26:18 +0100 Subject: [PATCH 08/12] Delete Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs --- .../Views/CalculatorSettings.xaml.cs | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs deleted file mode 100644 index d0d79cd72b1..00000000000 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Windows.Controls; -using Flow.Launcher.Plugin.Calculator.ViewModels; - -namespace Flow.Launcher.Plugin.Calculator.Views -{ - public partial class CalculatorSettings : UserControl - { - private readonly SettingsViewModel _viewModel; - private readonly Settings _settings; - - public CalculatorSettings(SettingsViewModel viewModel) - { - _viewModel = viewModel; - _settings = viewModel.Settings; - DataContext = viewModel; - InitializeComponent(); - } - } -} From 76f834ff1b88fe09c2025cef55b7aa968e85f424 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Wed, 23 Jul 2025 17:56:58 +0100 Subject: [PATCH 09/12] PR review changes --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 15 +++++++++++---- .../Flow.Launcher.Plugin.Calculator/plugin.json | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index afd0ddfe5a4..e9ea2d08c68 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -219,11 +219,10 @@ private string NormalizeNumber(string numberStr, ParsingContext context) return numberStr; } - private string FormatResult(decimal roundedResult, ParsingContext context) { string decimalSeparator = context.InputDecimalSeparator ?? GetDecimalSeparator(); - string groupSeparator = decimalSeparator == dot ? comma : dot; + string groupSeparator = GetGroupSeparator(decimalSeparator); string resultStr = roundedResult.ToString(CultureInfo.InvariantCulture); @@ -231,7 +230,7 @@ private string FormatResult(decimal roundedResult, ParsingContext context) string integerPart = parts[0]; string fractionalPart = parts.Length > 1 ? parts[1] : string.Empty; - if (context.InputUsesGroupSeparators) + if (context.InputUsesGroupSeparators && integerPart.Length > 3) { integerPart = ThousandGroupRegex.Replace(integerPart, groupSeparator); } @@ -244,9 +243,17 @@ private string FormatResult(decimal roundedResult, ParsingContext context) return integerPart; } + private string GetGroupSeparator(string decimalSeparator) + { + // Use system culture's group separator when available and it doesn't conflict + var systemGroupSep = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; + return decimalSeparator == systemGroupSep + ? (decimalSeparator == dot ? comma : dot) + : systemGroupSep; + } + private bool CanCalculate(Query query) { - // Don't execute when user only input "e" or "i" keyword if (query.Search.Length < 2) { return false; diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json index 739572930d0..c9435e04315 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json @@ -4,7 +4,7 @@ "Name": "Calculator", "Description": "Perform mathematical calculations (including hexadecimal values). Use ',' or '.' as thousand separator or decimal place.", "Author": "cxfksword, dcog989", - "Version": "1.1.0", + "Version": "1.0.0", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Calculator.dll", From f8a6b02c80559d020437ebc166a18c8e88fd78d9 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Thu, 24 Jul 2025 02:33:59 +0100 Subject: [PATCH 10/12] fix for GitHub build server failure Removes external dependency for NumberGroupSeparator so it builds anywhere. --- .../Flow.Launcher.Plugin.Calculator/Main.cs | 8 +++---- .../Views/CalculatorSettings.xaml.cs | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index e9ea2d08c68..cc5032c6b2c 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -245,11 +245,9 @@ private string FormatResult(decimal roundedResult, ParsingContext context) private string GetGroupSeparator(string decimalSeparator) { - // Use system culture's group separator when available and it doesn't conflict - var systemGroupSep = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; - return decimalSeparator == systemGroupSep - ? (decimalSeparator == dot ? comma : dot) - : systemGroupSep; + // This logic is now independent of the system's group separator + // to ensure consistent output for unit testing. + return decimalSeparator == dot ? comma : dot; } private bool CanCalculate(Query query) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs new file mode 100644 index 00000000000..64e2adc6e40 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml.cs @@ -0,0 +1,23 @@ +using System.Windows.Controls; +using Flow.Launcher.Plugin.Calculator.ViewModels; + +namespace Flow.Launcher.Plugin.Calculator.Views +{ + /// + /// Interaction logic for CalculatorSettings.xaml + /// + public partial class CalculatorSettings : UserControl + { + private readonly SettingsViewModel _viewModel; + private readonly Settings _settings; + + public CalculatorSettings(SettingsViewModel viewModel) + { + _viewModel = viewModel; + _settings = viewModel.Settings; + DataContext = viewModel; + InitializeComponent(); + } + } + +} \ No newline at end of file From 443d4f7c02d0ea00eb593a9e7af12029100b2dd1 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sun, 27 Jul 2025 18:39:38 +0800 Subject: [PATCH 11/12] Build regex at compile time --- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 5 ++--- Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 78c182f30cd..0744024f4d2 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -15,9 +15,8 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider { private static readonly Regex RegValidExpressChar = MainRegexHelper.GetRegValidExpressChar(); private static readonly Regex RegBrackets = MainRegexHelper.GetRegBrackets(); - private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled); - private static readonly Regex NumberRegex = new Regex(@"[\d\.,]+", RegexOptions.Compiled); - + private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex(); + private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex(); private static Engine MagesEngine; private const string Comma = ","; diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs index 8ffc547d10d..f4e2090e740 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs @@ -10,4 +10,10 @@ internal static partial class MainRegexHelper [GeneratedRegex(@"^(ceil|floor|exp|pi|e|max|min|det|abs|log|ln|sqrt|sin|cos|tan|arcsin|arccos|arctan|eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|bin2dec|hex2dec|oct2dec|factorial|sign|isprime|isinfty|==|~=|&&|\|\||(?:\<|\>)=?|[ei]|[0-9]|0x[\da-fA-F]+|[\+\%\-\*\/\^\., ""]|[\(\)\|\!\[\]])+$", RegexOptions.Compiled)] public static partial Regex GetRegValidExpressChar(); + + [GeneratedRegex(@"[\d\.,]+", RegexOptions.Compiled)] + public static partial Regex GetNumberRegex(); + + [GeneratedRegex(@"\B(?=(\d{3})+(?!\d))", RegexOptions.Compiled)] + public static partial Regex GetThousandGroupRegex(); } From afc969d00fc54be017bb7da7edadecd446142de0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sun, 27 Jul 2025 20:03:33 +0800 Subject: [PATCH 12/12] Update translations in language file --- Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml index 502c07238e6..25aaf97e71c 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml @@ -4,7 +4,7 @@ xmlns:system="clr-namespace:System;assembly=mscorlib"> Calculator - Allows to do mathematical calculations.(Try 5*3-2 in Flow Launcher) + Perform mathematical calculations (including hexadecimal values). Use ',' or '.' as thousand separator or decimal place. Not a number (NaN) Expression wrong or incomplete (Did you forget some parentheses?) Copy this number to the clipboard