diff --git a/Coder.Graph/AstGraphEditor.cs b/Coder.Graph/AstGraphEditor.cs
index 8834913..62c9e81 100644
--- a/Coder.Graph/AstGraphEditor.cs
+++ b/Coder.Graph/AstGraphEditor.cs
@@ -50,7 +50,7 @@ public sealed class AstGraphEditor(AstNode root)
/// sits beside the graph, and the names it draws — Visibility, Parameters — are
/// longer than most of the values beside them. It stays the user's to drag either way.
///
- /// Fractions are spelled to fifteen significant digits rather than the widget's six decimal
+ /// Fractions are spelled to seventeen significant digits rather than the widget's six decimal
/// places. A literal is a value the generated source will carry, so the row has to show what the
/// document holds: 3.14 has to read as 3.14 rather than as 3.140000, and a value with more digits
/// than that has to keep them when the user opens the box to change something else about it.
@@ -59,7 +59,7 @@ public sealed class AstGraphEditor(AstNode root)
private static readonly ImGuiWidgets.PropertyGridOptions InspectorGridOptions = new()
{
LabelColumnWeight = 0.95f,
- DoubleFormat = "%.15g",
+ DoubleFormat = "%.17g",
};
private string statusMessage = string.Empty;
diff --git a/Coder.Test/Graph/AstGraphEditorInspectorPanelTests.cs b/Coder.Test/Graph/AstGraphEditorInspectorPanelTests.cs
index f48721c..aaefb9f 100644
--- a/Coder.Test/Graph/AstGraphEditorInspectorPanelTests.cs
+++ b/Coder.Test/Graph/AstGraphEditorInspectorPanelTests.cs
@@ -2,6 +2,8 @@
namespace ktsu.Coder.Test.Graph;
+using System.Globalization;
+using System.Reflection;
using System.Numerics;
using Hexa.NET.ImGui;
@@ -42,6 +44,14 @@ private static FunctionDeclaration SampleFunction()
return function;
}
+ private static (FunctionDeclaration Function, LiteralExpression Literal) SampleFunctionWithSmallFractionLiteral()
+ {
+ LiteralExpression literal = Literal.DecimalValue(1e-9);
+ FunctionDeclaration function = new("tiny") { ReturnType = "double" };
+ function.Body.Add(new ReturnStatement(literal));
+ return (function, literal);
+ }
+
///
/// Draws the whole editor, because selecting a node is ImNodes' business and it faults inside
/// native code when its context is missing rather than throwing.
@@ -207,4 +217,40 @@ public void Inspector_AddsAndRemovesChildrenFromASlotRow()
Assert.HasCount(1, function.Parameters);
}
+
+ ///
+ /// Tests that a tiny floating-point literal keeps its value through inspector draws and edit
+ /// commits, rather than being collapsed to zero by the row's display format.
+ ///
+ [TestMethod]
+ public void Inspector_PreservesASmallFractionLiteralAcrossDrawAndEdit()
+ {
+ FieldInfo optionsField = typeof(AstGraphEditor).GetField("InspectorGridOptions", BindingFlags.NonPublic | BindingFlags.Static)
+ ?? throw new AssertFailedException("Inspector grid options should exist.");
+
+ ktsu.ImGui.Widgets.ImGuiWidgets.PropertyGridOptions options =
+ (ktsu.ImGui.Widgets.ImGuiWidgets.PropertyGridOptions)optionsField.GetValue(null)!;
+ Assert.AreEqual("%.17g", options.DoubleFormat);
+
+ (FunctionDeclaration function, LiteralExpression literal) = SampleFunctionWithSmallFractionLiteral();
+ AstGraphEditor editor = new(function);
+ double expected = literal.Value;
+
+ using ImGuiAppHarness harness = Inspecting(editor, literal);
+
+ // Rendering and selecting the node must leave the document value untouched.
+ Assert.AreEqual(expected, literal.Value);
+
+ harness.Click("Value");
+ harness.Step(2);
+
+ harness.Keyboard.Press(ImGuiKey.A, ctrl: true);
+ harness.Keyboard.Type(expected.ToString("G17", CultureInfo.InvariantCulture));
+ harness.Step(2);
+
+ harness.Keyboard.Press(ImGuiKey.Enter);
+ harness.Step(2);
+
+ Assert.AreEqual(expected, literal.Value);
+ }
}