Flutter命令行交互插件cli_repl的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter命令行交互插件cli_repl的使用

cli_repl 是一个用于在Dart中创建命令行REPL(读取-评估-打印循环)的简单库。

特性

示例用法:

/// Echoes all entered lines
for (var line in new Repl().run()) {
  print(line);
} 
语句验证

通过将 validator 传递给 Repl 构造函数,您可以告诉REPL输入的文本是否为完整语句。当按下回车键时,REPL会调用此方法来确定是否返回一个完整的语句或继续在新行上进行。默认验证器对所有文本都返回true。

自定义提示符

默认情况下,REPL在请求语句时不给用户提供任何提示符。您可以通过将 prompt 传递给 Repl 构造函数来更改这一点。默认情况下,新行上的语句延续将以与 prompt 长度相等的空白字符开头。您可以通过传入 continuation 来覆盖此行为。

参见 example/example.dart 以查看语句验证和自定义提示符的演示。

历史记录

存储已输入行的历史记录。历史记录条目在编辑时会被修改。

默认情况下,最多存储50个条目。您可以通过将 maxHistory 传递给 Repl 构造函数来更改此值。

导航
  • Left/Ctrl-B: 向左移动一个字符
  • Right/Ctrl-F: 向右移动一个字符
  • Home/Ctrl-A: 移动到行首
  • End/Ctrl-E: 移动到行尾
  • Ctrl-L: 清屏
  • Ctrl-D: 如果有文本,则删除光标下的字符。如果没有文本,则退出。
  • Ctrl-F: 向前移动一个字符
  • Ctrl-B: 向后移动一个字符
  • Ctrl-U: 删除(剪切)到行首
  • Ctrl-K: 删除(剪切)到行尾
  • Ctrl-Y: 粘贴(插入)之前剪切的文本,插入到光标处
  • Up/Down: 在历史记录中导航
测试REPLs

如果在没有终端的情况下运行,输入将与提示符一起打印,允许您通过比较stdout与预期的日志输入和输出来测试使用此库创建的REPL。

参见 test/repl_test.dart 以查看此示例。

在Node上运行

如果您使用Dart 2将其编译为JS,可以在Node上运行它。

有一些行为差异:

  • 使用Node内置的readline库,因此支持的导航和历史命令可能与Dart版本不同。
  • 同样,行历史由Node管理,您无法从Dart手动更改最大条目数或编辑历史记录。
  • 只有 Repl.runAsync() 起作用。调用 Repl.run() 将抛出错误。

完整示例Demo

以下是一个完整的示例,展示了如何使用 cli_repl 库创建一个简单的命令行REPL,该REPL查找分号以完成语句并回显所有已完成的语句。

/// Example REPL that looks for a semicolon to complete a statement and then
/// echoes all completed statements.

import 'package:cli_repl/cli_repl.dart';

main(args) async {
  // 创建一个验证器函数,检查字符串是否为空或以分号结尾
  var v = (str) => str.trim().isEmpty || str.trim().endsWith(';');
  
  // 创建一个新的Repl实例,设置提示符、延续提示符和验证器
  var repl = new Repl(prompt: '>>> ', continuation: '... ', validator: v);
  
  // 异步运行REPL,处理用户输入
  await for (var x in repl.runAsync()) {
    // 忽略空行
    if (x.trim().isEmpty) continue;
    
    // 如果输入是 'throw;' 则抛出异常
    if (x == 'throw;') throw "oh no!";
    
    // 打印用户输入
    print(x);
  }
}

更多关于Flutter命令行交互插件cli_repl的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter命令行交互插件cli_repl的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用cli_repl插件来实现命令行交互的示例代码。cli_repl插件允许你在Flutter应用中创建一个简单的命令行界面(REPL,Read-Eval-Print Loop),这对于调试和交互非常有用。

首先,确保你的Flutter环境已经正确设置,并且你的项目已经初始化。然后,你可以按照以下步骤来集成和使用cli_repl插件。

1. 添加依赖

在你的pubspec.yaml文件中添加cli_repl依赖:

dependencies:
  flutter:
    sdk: flutter
  cli_repl: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 使用cli_repl

下面是一个简单的示例,展示如何在Flutter应用中集成并使用cli_repl

main.dart

import 'package:flutter/material.dart';
import 'package:cli_repl/cli_repl.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter CLI REPL Example'),
        ),
        body: Center(
          child: REPLScreen(),
        ),
      ),
    );
  }
}

class REPLScreen extends StatefulWidget {
  @override
  _REPLScreenState createState() => _REPLScreenState();
}

class _REPLScreenState extends State<REPLScreen> {
  REPLController? _replController;

  @override
  void initState() {
    super.initState();
    _initRepl();
  }

  void _initRepl() {
    _replController = REPLController(
      prompt: '> ',
      onEvaluate: (String input) async {
        // 在这里处理用户输入
        try {
          // 简单示例:计算表达式结果
          final result = await compute(evaluateExpression, input);
          return result.toString();
        } catch (e) {
          return 'Error: $e';
        }
      },
    );

    // 启动REPL循环
    _replController!.start();
  }

  @override
  void dispose() {
    _replController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Expanded(
          child: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Text(
                _replController!.output,
                style: TextStyle(fontFamily: 'monospace'),
              ),
            ),
          ),
        ),
        TextField(
          onSubmitted: (String input) {
            _replController!.evaluate(input);
          },
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            labelText: 'Enter command',
          ),
          style: TextStyle(fontFamily: 'monospace'),
        ),
      ],
    );
  }
}

// 一个简单的表达式求值函数,使用compute函数在非UI线程中执行
Future<dynamic> evaluateExpression(String expression) async {
  return Function.apply(null, [expression]);
}

3. 解释代码

  • REPLController: 这是cli_repl包中的核心类,负责管理REPL循环。
  • prompt: 设置REPL提示符。
  • onEvaluate: 定义如何评估用户输入的表达式。在这个示例中,我们简单地尝试计算输入的字符串表达式。
  • TextField: 用于用户输入。当用户提交输入时,调用_replController!.evaluate(input)来评估输入。
  • Text: 显示REPL的输出。

4. 运行应用

确保你的Flutter开发环境配置正确,然后运行flutter run来启动应用。在应用中,你应该能看到一个简单的命令行界面,允许你输入表达式并查看结果。

注意:上述示例中的evaluateExpression函数非常基础,仅用于演示目的。在实际应用中,你可能需要实现更复杂的逻辑来处理用户输入。

这个示例提供了一个基础框架,你可以根据需求进一步扩展和优化。

回到顶部