欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言

如果你为鸿蒙开发了一套 CLI 工具(比如 ohos_deploy),用户在终端输入命令时,如果能像 gitkubectl 那样按下 <TAB> 键就自动补全参数,体验将会有质的飞跃。

completion 是 Dart 官方提供的一个小巧库,专门用于为 Dart 编写的命令行程序生成 Shell 自动补全脚本(支持 Bash/Zsh)。

对于 OpenHarmony 开发者,这意味着你可以用 Dart 编写出专业级的开发辅助工具,分发给团队使用,极大提升内部开发效率。

一、核心原理

自动补全的原理并非魔法。

  1. 安装阶段:生成一段 Shell 脚本(如 .bash_completion),告诉 Shell 当用户输入 my_cli <TAB> 时,去调用 my_cli completion ... 获取建议。
  2. 运行阶段:你的程序接收到特殊的 completion 参数,计算当前光标位置的候选词,输出给 Shell。
你的 Dart CLI Zsh/Bash 用户 (Terminal) 你的 Dart CLI Zsh/Bash 用户 (Terminal) 输入 "ohos_cli dep<TAB>" 运行 "ohos_cli completion --word='dep'" 匹配候选词 (deploy, dependency) 返回 "deploy\ndependency" 显示补全列表

二、OpenHarmony 适配说明

completion 库运行在宿主机的 Shell 环境中(Mac/Linux/Windows)。
当然,如果你在鸿蒙设备上通过 Termux 或 Shell 环境运行 Dart 程序,只要 Shell 支持(鸿蒙自带的 shell 较为精简,可能不支持高级补全),它也能工作。

主要场景
它是为鸿蒙工具链开发者准备的。你的工具运行在 PC 上,辅佐鸿蒙开发。

三、基础用例

3.1 定义补全逻辑

import 'package:args/args.dart';
import 'package:completion/completion.dart';

void main(List<String> args) {
  final parser = ArgParser();
  parser.addOption('target', allowed: ['android', 'ios', 'ohos']);
  
  // 1. 尝试处理补全请求
  // 如果当前是补全模式,tryArgsCompletion 会直接打印建议并退出程序
  // 否则返回正常的 args
  tryArgsCompletion(args, parser);

  // 2. 正常的业务逻辑
  final results = parser.parse(args);
  print('正在构建目标: ${results['target']}');
}

在这里插入图片描述

3.2 安装补全脚本

用户在使用你的工具前,需要运行一次安装命令(只需一次)。
该库并没有自动安装功能,通常你需要提示用户配置 .zshrc.bashrc

生成的补全脚本通常长这样:

# 自动生成的 setup
if type complete &>/dev/null; then
  _my_cli_completion() {
    local si="$IFS"
    IFS=$'\n' COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
                           COMP_LINE="$COMP_LINE" \
                           COMP_POINT="$COMP_POINT" \
                           my_cli completion -- "${COMP_WORDS[@]}" \
                           2>/dev/null)) || return $?
    IFS="$si"
  }
  complete -F _my_cli_completion my_cli
fi

四、完整实战示例:鸿蒙多模块构建工具

假设你管理着一个包含 50 个 HAP 模块的超大鸿蒙项目,你写了一个工具来单独构建指定的模块。

import 'dart:io';
import 'package:args/args.dart';
import 'package:completion/completion.dart';

void main(List<String> args) {
  final parser = ArgParser();
  
  // 动态获取所有模块名作为补全候选
  List<String> getModuleNames() {
    // 假设当前目录下所有以 feature_ 开头的文件夹都是模块
    final dir = Directory.current;
    if (!dir.existsSync()) return [];
    
    return dir.listSync()
        .whereType<Directory>()
        .map((d) => d.path.split(Platform.pathSeparator).last)
        .where((name) => name.startsWith('feature_'))
        .toList();
  }

  parser.addCommand('build');
  parser.addCommand('clean');
  parser.addOption('module', help: '指定模块名');

  // 拦截补全请求
  // 注意:tryArgsCompletion 默认只处理静态 allowed 列表
  // 如果需要动态补全(如扫描文件夹),需要自定义 completion 逻辑(略高级,本库提供基础支持)
  // 这里演示最基础的静态补全
  tryArgsCompletion(args, parser);

  // 业务逻辑
  var results = parser.parse(args);
  if (results.command?.name == 'build') {
    print('🔨 正在构建模块: ${results['module'] ?? 'ALL'}');
  }
}

在这里插入图片描述

五、总结

completion 是那种“一旦拥有,别无所求”的功能。
虽然它不直接运行在鸿蒙 App 里,但它是提升鸿蒙开发体验的重要一环。如果你致力于打造一套让开发者爱不释手的鸿蒙工具链,请务必为你的 CLI 加上自动补全功能。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐