dart-multiline-strings について
複数行のコンソール出力をまとめ、長い文字列リテラルを整理する Dart 向けスキルです。三重引用符が適する場面と、出力の意味を変えかねないリファクタリングを説明します。
主な機能
- 01連続する print 呼び出しを統合
- 02三重引用符で複数行出力を記述
- 03インデントと先頭・末尾の改行を調整
- 04条件付き内容による空行を回避
- 05空白の意味を維持すべき場面を特定
活用シーン
- 01繰り返しの CLI 出力処理を整理
- 02ヘルプメニューやレポートを整形
- 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 のヘルプメニュー、レポート、テンプレートメッセージなど、ユーザーに表示する長いテキストを、読みやすく、保守しやすく、パフォーマンスの高い形式に整える場合。
使用しない場合(適用を控えるためのガードレール)
次の場合は、複数行文字列へのリファクタリングを行わないでください。
- 短い単一行の出力:埋め込み改行がなく、1 行(80 文字未満)に無理なく収まる文字列。
- ローカライズ文字列カタログ:ローカライズバンドル(例:
intl、ARB ファイル)から参照される文字列。改行や書式が外部の翻訳ツールに準拠する必要があります。 - 空白の厳密な扱いが求められる生のクエリ文字列:プロトコル文字列、厳密な CSV 行、または三重引用符内のインデント用空白によってペイロードの意味が変わったり、意図しない先頭スペースが加わったりするクエリ。
- ストリーミングまたは逐次的な I/O:進行状況バー、スピナー、または行ごとの遅延やフラッシュを伴うインタラクティブなコンソールストリーム。
検出
複数行文字列へのリファクタリング候補となるコードブロックを見つけるには、次の点を確認します。
- 関数内、特にループ、コンソールビュー、CLI コントローラー内にある、連続した複数の
print()またはstdout.writeln()の呼び出しを探します。 \nのエスケープシーケンスを多く含む単一行の文字列を探します。- 複数行の出力を表すために、
+演算子を使用した複数の文字列連結や、隣接する文字列リテラルへの分割を探します。
2. ガイドライン
連続した出力をまとめる
複数行の出力に対して print() を繰り返し呼び出す代わりに、内容を単一の三重引用符付き文字列リテラルにまとめます。print('''...''') のように記述します。
明示的で整った位置合わせ
三重引用符付きリテラルでは、引用符の内側にある空白や書式がそのまま保持されます。手動で空白を付けたプレフィックス(例:' ')を使う代わりに、インデントのレベルを見た目で指定できます。
空の print 呼び出しを削除する
出力セグメント間の縦方向の区切りとして使われている空の print() または print('') 文は、複数行文字列ブロックの末尾の改行で自然に区切ることで置き換えます。
先頭の改行の扱い
開始側の三重引用符の直後に改行がある場合、コンパイラーはその改行を破棄します。
- 先頭に空行を入れたくない場合は、ソースコード上で文字列の内容を次の行から始めると、レイアウトがすっきりします。
- 出力に先頭の空行を入れたい場合は、三重引用符付きブロック内に空行をもう 1 行入れるか、先頭に
\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 ルールは、複数行文字列リテラル内の行を自動的に無視します。三重引用符の内側では、リンターの警告を発生させたり、行を分割したりすることなく、長い行を記述できます。
補間式内の動的な switch 式
Dart 3 の switch 式を文字列補間内で直接活用し、任意の行、条件付きラベル、補助的な指示を動的に選択して挿入できます。これにより、命令的に文字列を組み立てたり、複数の if 文を使ったりして、周囲のコードが煩雑になるのを避けられます。
print('''
Status: ${status.isSuccess ? 'PASS' : 'FAIL'}${switch (status) {
Status.failed => '\nError details: $errorMessage',
_ => '',
}}''');
3. 例
インデントを付けた連続する print のリファクタリング
避けてください:
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.''' : ''}''');
}