$npx -y skills add kevmoo/dash_skills --skill dart-multiline-stringsGuidelines and best practices for refactoring consecutive prints, single-line string concatenations, and complex output blocks into triple-quoted multi-line string literals (''' or """) in Dart.
| 1 | # Dart Multi-line Strings |
| 2 | |
| 3 | ## 1. When to use this skill |
| 4 | |
| 5 | Use this skill when: |
| 6 | - Refactoring consecutive `print()` or `stdout.writeln()` statements into a |
| 7 | single, cohesive output block. |
| 8 | - Simplifying string literals that span multiple lines, contain embedded |
| 9 | newlines (`\n`), or use nested indentations. |
| 10 | - Formatting large user-facing text output (like CLI help menus, reports, or |
| 11 | templated messages) to be readable, maintainable, and performant. |
| 12 | |
| 13 | ## Discovery |
| 14 | |
| 15 | To find candidate code blocks for multi-line string refactoring: |
| 16 | - Look for multiple back-to-back `print()` or `stdout.writeln()` calls inside |
| 17 | a function, especially inside loops, console views, or CLI controllers. |
| 18 | - Look for single-line strings heavily loaded with `\n` escape sequences. |
| 19 | - Look for multiple string concatenations using the `+` operator or adjacent |
| 20 | string literal splits that are meant to represent multi-line outputs. |
| 21 | |
| 22 | ## 2. Guidelines |
| 23 | |
| 24 | ### Combine Consecutive Outputs |
| 25 | Instead of calling `print()` repeatedly for a multi-line output, group the |
| 26 | contents into a single triple-quoted string literal: `print('''...''')`. |
| 27 | |
| 28 | ### Explicit and Clean Alignment |
| 29 | In a triple-quoted literal, the exact spacing and formatting inside the quotes |
| 30 | are preserved. Use this to specify indentation levels visually instead of using |
| 31 | manually padded space prefixes (e.g., `' '`). |
| 32 | |
| 33 | ### Remove Empty Print Calls |
| 34 | If there are empty `print()` or `print('')` statements serving as vertical |
| 35 | separators between output segments, replace them by letting the trailing |
| 36 | newline of a multi-line string block handle the separation naturally. |
| 37 | |
| 38 | ### Handling the First Newline |
| 39 | If the opening triple-quote is immediately followed by a newline, the compiler |
| 40 | discards it. |
| 41 | - If you do **not** want a leading blank line, start the string content on a |
| 42 | fresh line in the source code for clean layout. |
| 43 | - If you **do** want a leading blank line in the output, leave an extra empty |
| 44 | line inside the triple-quoted block, or use `\n` explicitly at the |
| 45 | beginning: |
| 46 | ```dart |
| 47 | print(''' |
| 48 | |
| 49 | This starts with one blank line above it.'''); |
| 50 | ``` |
| 51 | |
| 52 | ### 80-Character Line Limit Exemption |
| 53 | The `lines_longer_than_80_chars` lint rule **automatically ignores** lines inside |
| 54 | multiline string literals. You can write long lines inside triple-quotes without |
| 55 | triggering linter warnings or being forced to break them up. |
| 56 | |
| 57 | ### Dynamic Switch Expressions inside Interpolation |
| 58 | Leverage Dart 3 switch expressions directly inside string interpolations to |
| 59 | dynamically select and inject optional lines, conditional labels, or helper |
| 60 | instructions. This avoids cluttering the surrounding code with imperatively |
| 61 | constructed strings or multiple `if` statements: |
| 62 | ```dart |
| 63 | print(''' |
| 64 | Status: ${status.isSuccess ? 'PASS' : 'FAIL'} |
| 65 | ${switch (status) { |
| 66 | Status.failed => 'Error details: $errorMessage', |
| 67 | _ => '', |
| 68 | }}'''); |
| 69 | ``` |
| 70 | |
| 71 | ## 3. Examples |
| 72 | |
| 73 | ### Refactoring Consecutive Prints with Indentation |
| 74 | |
| 75 | **Avoid:** |
| 76 | ```dart |
| 77 | void printGerritView(String branch, String desc, bool hasConflicts) { |
| 78 | print('Branch Details:'); |
| 79 | print(' Name: ' + branch); |
| 80 | print(' Description: ' + desc); |
| 81 | print(''); |
| 82 | if (hasConflicts) { |
| 83 | print(' WARNING: This branch has conflicts.'); |
| 84 | print(' Run `git merge origin/main` to resolve.'); |
| 85 | } |
| 86 | } |
| 87 | ``` |
| 88 | |
| 89 | **Prefer:** |
| 90 | ```dart |
| 91 | void printGerritView(String branch, String desc, bool hasConflicts) { |
| 92 | print(''' |
| 93 | Branch Details: |
| 94 | Name: $branch |
| 95 | Description: $desc |
| 96 | ${hasConflicts ? ''' |
| 97 | WARNING: This branch has conflicts. |
| 98 | Run `git merge origin/main` to resolve.''' : ''}'''); |
| 99 | } |
| 100 | ``` |