mcpField
D
dart-multiline-strings

dart-multiline-strings

github.com/kevmoo开发148111 次安装2 周前更新
代码仓库

关于 dart-multiline-strings

一项 Dart 编码技能,用于合并多行控制台输出并整理较长的字符串字面量。它说明何时适合使用三引号字符串,以及哪些重构可能改变输出语义。

主要功能

  1. 01合并连续的 print 调用
  2. 02用三引号字符串组织多行输出
  3. 03控制缩进及开头或结尾换行
  4. 04处理条件内容以避免空白行
  5. 05识别必须保留空白语义的场景

适用场景

  1. 01重构重复的 CLI 输出语句
  2. 02整理帮助菜单和报告
  3. 03简化包含换行转义符的字符串

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kevmoo/dash_skills --skill dart-multiline-strings

安装后在 Claude Code 中输入/dart-multiline-strings确认已加载。

附带文件evals/evals.json

详细介绍

Dart 多行字符串

1. 何时使用此技能

适用于以下情况:

  • 将连续的 print() 或 stdout.writeln() 语句重构为单个连贯的输出块。
  • 简化跨越多行、包含嵌入换行符(\n)或使用嵌套缩进的字符串字面量。
  • 格式化较长的面向用户的文本输出(例如 CLI 帮助菜单、报告或模板消息),使其易于阅读、维护且性能良好。
何时不应使用(避免滥用的准则)

以下情况不要重构为多行字符串:

  • 简短的单行输出:字符串可以轻松放在一行中(少于 80 个字符),且不含嵌入的换行符。
  • 本地化字符串目录:字符串从本地化资源包(例如 intl、ARB 文件)中查找,换行或格式必须符合外部翻译工具的要求。
  • 对空白字符语义有严格要求的原始查询字符串:协议字符串、严格格式的 CSV 行,或三引号中的缩进空白会改变负载语义或引入意外前导空格的查询。
  • 流式或增量 I/O:进度条、旋转指示器或交互式控制台流,其中各次写入之间会有延迟或刷新操作。

发现

要查找适合重构为多行字符串的代码块:

  • 查找函数中多个连续调用的 print() 或 stdout.writeln(),尤其是在循环、控制台视图或 CLI 控制器中。
  • 查找包含大量 \n 转义序列的单行字符串。
  • 查找使用 + 运算符进行多次字符串拼接,或拆分相邻字符串字面量以表示多行输出的代码。

2. 指南

合并连续输出

不要为多行输出反复调用 print(),而应将内容合并到一个三引号字符串字面量中:print('''...''')。

明确且整洁的对齐方式

在三引号字面量中,引号内的空格和格式会原样保留。利用这一点直观地指定缩进层级,而不是手动添加填充空格前缀(例如 ' ')。

移除空的打印调用

如果空的 print() 或 print('') 语句用作输出片段之间的垂直分隔符,可以让多行字符串块末尾的换行符自然处理分隔,从而移除这些语句。

处理首个换行符

如果开头的三引号后紧接换行符,编译器会将其丢弃。

  • 如果不希望输出开头出现空行,请在源码中新起一行编写字符串内容,以保持排版整洁。
  • 如果希望输出开头出现空行,请在三引号块中多留一个空行,或在开头显式使用 \n:
    print('''
    
    This starts with one blank line above it.''');
    
处理末尾换行符与 print()

print() 会自动在输出末尾追加换行符。

  • 如果将结束的 ''' 放在新的一行(\n''');),输出末尾会多出一个空行。
  • 为避免意外的末尾空行,请将结束的三引号紧接在最后一个字符之后:
    // ✅ Emits standard output with no extra trailing empty line:
    print('''
    Header
    Content''');
    
避免条件插值产生意外空行

通过插值(${condition ? '...' : ''})插入可选内容时,如果将 ${...} 单独放在一行,当条件结果为 '' 时,其所在行的换行符仍会保留,导致输出中出现空行。

  • 将前导换行符放在条件字符串字面量内部,这样只有在存在内容时才会输出换行符:
    // ✅ Clean conditional rendering without ghost blank lines:
    print('''
    Branch Details:
        Name: $branch${hasWarning ? '\n    WARNING: $warningMessage' : ''}''');
    
80 字符行长限制豁免

lines_longer_than_80_chars lint 规则会自动忽略多行字符串字面量内部的行。三引号内可以编写较长的行,不会触发 lint 警告,也不必强行拆分。

插值中的动态 Switch 表达式

直接在字符串插值中使用 Dart 3 的 switch 表达式,动态选择并插入可选行、条件标签或辅助说明。这样可以避免周围代码中出现命令式构造字符串或多个 if 语句造成的杂乱:

print('''
Status: ${status.isSuccess ? 'PASS' : 'FAIL'}${switch (status) {
  Status.failed => '\nError details: $errorMessage',
  _ => '',
}}''');

3. 示例

重构带缩进的连续打印语句

避免:

void printGerritView(String branch, String desc, bool hasConflicts) {
  print('Branch Details:');
  print('    Name:        ' + branch);
  print('    Description: ' + desc);
  print('');
  if (hasConflicts) {
    print('    WARNING: This branch has conflicts.');
    print('    Run `git merge origin/main` to resolve.');
  }
}

建议:

void printGerritView(String branch, String desc, bool hasConflicts) {
  print('''
Branch Details:
    Name:        $branch
    Description: $desc${hasConflicts ? '''

    WARNING: This branch has conflicts.
    Run `git merge origin/main` to resolve.''' : ''}''');
}

评论

支持 Markdown