Преглед изворни кода

逗号键在花括号里也能用(矩阵行分隔)

逗号键的动作一直是"切到函数调用的下一个参数",所以光标在花括号里时
(矩阵的每一行就是一个花括号)它什么都不做 —— 结果矩阵里逗号打不出来,
`{{1,2},{3,4}}` 会变成 `{{12}, {34}}`。

改成:在函数参数里切参数,不在就插一个逗号字面量。nextArgument 相应
改成返回 bool,告诉调用方有没有处理。

新增端到端测试:走函数面板取 Det + 两层花括号 + 换行键,
拼出 `Det[{{1,2}, {3,4}}]`。(顺带学到:测试里用 find.text 点面板项
会被搜索框里刚输入的同样文字命中,要用 widgetWithText(ListTile, ...)。)

91 个测试通过。

Co-Authored-By: Claude Code <noreply@anthropic.com>
nonvioce пре 4 недеља
родитељ
комит
acd195677a
3 измењених фајлова са 34 додато и 6 уклоњено
  1. 2 1
      lib/calculator_page.dart
  2. 7 5
      lib/expr_node.dart
  3. 25 0
      test/widget_test.dart

+ 2 - 1
lib/calculator_page.dart

@@ -291,7 +291,8 @@ class _CalculatorPageState extends State<CalculatorPage> {
           operand: SeqNode(operand == null ? null : [operand]),
         ));
       case _Act.comma:
-        _doc.nextArgument();
+        // 在函数参数里 → 切到下一个参数;在花括号里(矩阵行)→ 插一个逗号
+        if (!_doc.nextArgument()) _doc.insert(LitNode(','));
       case _Act.back:
         _doc.backspace();
       case _Act.clear:

+ 7 - 5
lib/expr_node.dart

@@ -434,16 +434,17 @@ class ExprDoc {
 
   /// 切到当前函数调用的下一个参数;已经是最后一个就新建一个参数槽。
   ///
-  /// 只能用在函数参数里(光标路径的最后一跳指向某个 FuncNode 的参数槽时)。
-  void nextArgument() {
-    if (cursor.steps.isEmpty) return;
+  /// **返回是否真的处理了** —— 光标不在函数参数里时返回 false,
+  /// 调用方(逗号键)据此改成插入一个逗号字面量(矩阵行里就是这个情况)。
+  bool nextArgument() {
+    if (cursor.steps.isEmpty) return false;
     final here = cursor.steps.last;
     final parent = SlotPath(cursor.steps.sublist(0, cursor.steps.length - 1), 0);
     final siblings = slotAt(parent);
-    if (here.child >= siblings.children.length) return;
+    if (here.child >= siblings.children.length) return false;
 
     final node = siblings.children[here.child];
-    if (node is! FuncNode) return;
+    if (node is! FuncNode) return false;
 
     var target = here.slot + 1;
     if (target >= node.args.length) {
@@ -451,6 +452,7 @@ class ExprDoc {
       target = node.args.length - 1;
     }
     cursor = parent.push(here.child, target);
+    return true;
   }
 
   // ------------------------------------------------------------------ 删除

+ 25 - 0
test/widget_test.dart

@@ -250,6 +250,31 @@ void main() {
       expect(await lastExpr(tester), 'Solve[x-1==0, x]');
     });
 
+    testWidgets('拼一个行列式 Det[{{1,2},{3,4}}]', (tester) async {
+      await pumpApp(tester);
+      // 函数面板取 Det
+      await tester.tap(find.byIcon(Icons.functions));
+      await tester.pumpAndSettle();
+      await tester.enterText(find.byType(TextField).last, 'Det');
+      await tester.pumpAndSettle();
+      // 用 ListTile 限定,否则会同时命中搜索框里刚输入的 "Det"
+      await tester.tap(find.widgetWithText(ListTile, 'Det'));
+      await tester.pumpAndSettle();
+
+      // 两层花括号 + 数字
+      await press(tester, '{');
+      await press(tester, '{');
+      await press(tester, '1');
+      await press(tester, ',');
+      await press(tester, '2');
+      await press(tester, '},{');
+      await press(tester, '3');
+      await press(tester, ',');
+      await press(tester, '4');
+
+      expect(await lastExpr(tester), 'Det[{{1,2}, {3,4}}]');
+    });
+
     testWidgets('赋值:x = 1', (tester) async {
       await pumpApp(tester);
       await press(tester, 'x');