Skip to content

Commit c83a29f

Browse files
committed
PR review changes
1 parent 113baac commit c83a29f

File tree

1 file changed

+28
-21
lines changed
  • Plugins/Flow.Launcher.Plugin.Calculator

1 file changed

+28
-21
lines changed

Plugins/Flow.Launcher.Plugin.Calculator/Main.cs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider
2525
@")+$", RegexOptions.Compiled);
2626
private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled);
2727
private static readonly Regex ThousandGroupRegex = new Regex(@"\B(?=(\d{3})+(?!\d))");
28+
private static readonly Regex NumberRegex = new Regex(@"[\d\.,]+", RegexOptions.Compiled);
29+
2830
private static Engine MagesEngine;
2931
private const string comma = ",";
3032
private const string dot = ".";
@@ -34,8 +36,15 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider
3436
private static Settings _settings;
3537
private static SettingsViewModel _viewModel;
3638

37-
private string _inputDecimalSeparator;
38-
private bool _inputUsesGroupSeparators;
39+
/// <summary>
40+
/// Holds the formatting information for a single query.
41+
/// This is used to ensure thread safety by keeping query state local.
42+
/// </summary>
43+
private class ParsingContext
44+
{
45+
public string InputDecimalSeparator { get; set; }
46+
public bool InputUsesGroupSeparators { get; set; }
47+
}
3948

4049
public void Init(PluginInitContext context)
4150
{
@@ -59,13 +68,11 @@ public List<Result> Query(Query query)
5968
return new List<Result>();
6069
}
6170

62-
_inputDecimalSeparator = null;
63-
_inputUsesGroupSeparators = false;
71+
var context = new ParsingContext();
6472

6573
try
6674
{
67-
var numberRegex = new Regex(@"[\d\.,]+");
68-
var expression = numberRegex.Replace(query.Search, m => NormalizeNumber(m.Value));
75+
var expression = NumberRegex.Replace(query.Search, m => NormalizeNumber(m.Value, context));
6976

7077
var result = MagesEngine.Interpret(expression);
7178

@@ -78,7 +85,7 @@ public List<Result> Query(Query query)
7885
if (!string.IsNullOrEmpty(result?.ToString()))
7986
{
8087
decimal roundedResult = Math.Round(Convert.ToDecimal(result), _settings.MaxDecimalPlaces, MidpointRounding.AwayFromZero);
81-
string newResult = FormatResult(roundedResult);
88+
string newResult = FormatResult(roundedResult, context);
8289

8390
return new List<Result>
8491
{
@@ -117,10 +124,10 @@ public List<Result> Query(Query query)
117124
/// <summary>
118125
/// Parses a string representation of a number, detecting its format. It uses structural analysis
119126
/// (checking for 3-digit groups) and falls back to system culture for ambiguous cases (e.g., "1,234").
120-
/// It sets instance fields to remember the user's format for later output formatting.
127+
/// It populates the provided ParsingContext with the detected format for later use.
121128
/// </summary>
122129
/// <returns>A normalized number string with '.' as the decimal separator for the Mages engine.</returns>
123-
private string NormalizeNumber(string numberStr)
130+
private string NormalizeNumber(string numberStr, ParsingContext context)
124131
{
125132
var systemFormat = CultureInfo.CurrentCulture.NumberFormat;
126133
string systemDecimalSeparator = systemFormat.NumberDecimalSeparator;
@@ -131,18 +138,18 @@ private string NormalizeNumber(string numberStr)
131138
// Unambiguous case: both separators are present. The last one wins as decimal separator.
132139
if (hasDot && hasComma)
133140
{
134-
_inputUsesGroupSeparators = true;
141+
context.InputUsesGroupSeparators = true;
135142
int lastDotPos = numberStr.LastIndexOf(dot);
136143
int lastCommaPos = numberStr.LastIndexOf(comma);
137144

138145
if (lastDotPos > lastCommaPos) // e.g. 1,234.56
139146
{
140-
_inputDecimalSeparator = dot;
147+
context.InputDecimalSeparator = dot;
141148
return numberStr.Replace(comma, string.Empty);
142149
}
143150
else // e.g. 1.234,56
144151
{
145-
_inputDecimalSeparator = comma;
152+
context.InputDecimalSeparator = comma;
146153
return numberStr.Replace(dot, string.Empty).Replace(comma, dot);
147154
}
148155
}
@@ -158,19 +165,19 @@ private string NormalizeNumber(string numberStr)
158165
// Ambiguous case: "1,234". Resolve using culture.
159166
if (systemDecimalSeparator == comma)
160167
{
161-
_inputDecimalSeparator = comma;
168+
context.InputDecimalSeparator = comma;
162169
return numberStr.Replace(comma, dot);
163170
}
164171
else
165172
{
166-
_inputUsesGroupSeparators = true;
173+
context.InputUsesGroupSeparators = true;
167174
return numberStr.Replace(comma, string.Empty);
168175
}
169176
}
170177
else
171178
{
172179
// Unambiguous decimal: "123,45" or "1,2,345"
173-
_inputDecimalSeparator = comma;
180+
context.InputDecimalSeparator = comma;
174181
return numberStr.Replace(comma, dot);
175182
}
176183
}
@@ -184,18 +191,18 @@ private string NormalizeNumber(string numberStr)
184191
{
185192
if (systemDecimalSeparator == dot)
186193
{
187-
_inputDecimalSeparator = dot;
194+
context.InputDecimalSeparator = dot;
188195
return numberStr;
189196
}
190197
else
191198
{
192-
_inputUsesGroupSeparators = true;
199+
context.InputUsesGroupSeparators = true;
193200
return numberStr.Replace(dot, string.Empty);
194201
}
195202
}
196203
else
197204
{
198-
_inputDecimalSeparator = dot;
205+
context.InputDecimalSeparator = dot;
199206
return numberStr; // Already in Mages-compatible format
200207
}
201208
}
@@ -204,10 +211,10 @@ private string NormalizeNumber(string numberStr)
204211
return numberStr;
205212
}
206213

207-
private string FormatResult(decimal roundedResult)
214+
private string FormatResult(decimal roundedResult, ParsingContext context)
208215
{
209216
// Use the detected decimal separator from the input; otherwise, fall back to settings.
210-
string decimalSeparator = _inputDecimalSeparator ?? GetDecimalSeparator();
217+
string decimalSeparator = context.InputDecimalSeparator ?? GetDecimalSeparator();
211218
string groupSeparator = decimalSeparator == dot ? comma : dot;
212219

213220
string resultStr = roundedResult.ToString(CultureInfo.InvariantCulture);
@@ -216,7 +223,7 @@ private string FormatResult(decimal roundedResult)
216223
string integerPart = parts[0];
217224
string fractionalPart = parts.Length > 1 ? parts[1] : string.Empty;
218225

219-
if (_inputUsesGroupSeparators)
226+
if (context.InputUsesGroupSeparators)
220227
{
221228
integerPart = ThousandGroupRegex.Replace(integerPart, groupSeparator);
222229
}

0 commit comments

Comments
 (0)