blob: fe76b7c7a34b3938e63c17523c1c89924b81777c [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'logger.dart';
import 'platform.dart';
import 'terminal.dart';
const String fire = '🔥';
const int maxLineWidth = 84;
/// Encapsulates the help text construction and printing.
class CommandHelp {
CommandHelp({
required Logger logger,
required AnsiTerminal terminal,
required Platform platform,
required OutputPreferences outputPreferences,
}) : _logger = logger,
_terminal = terminal,
_platform = platform,
_outputPreferences = outputPreferences;
final Logger _logger;
final AnsiTerminal _terminal;
final Platform _platform;
final OutputPreferences _outputPreferences;
// COMMANDS IN ALPHABETICAL ORDER.
// Uppercase first, then lowercase.
// When updating this, update all the tests in command_help_test.dart accordingly.
late final CommandHelpOption I = _makeOption(
'I',
'Toggle oversized image inversion.',
'debugInvertOversizedImages',
);
late final CommandHelpOption L = _makeOption(
'L',
'Dump layer tree to the console.',
'debugDumpLayerTree',
);
late final CommandHelpOption M = _makeOption(
'M',
'Write SkSL shaders to a unique file in the project directory.',
);
late final CommandHelpOption P = _makeOption(
'P',
'Toggle performance overlay.',
'WidgetsApp.showPerformanceOverlay',
);
late final CommandHelpOption R = _makeOption(
'R',
'Hot restart.',
);
late final CommandHelpOption S = _makeOption(
'S',
'Dump accessibility tree in traversal order.',
'debugDumpSemantics',
);
late final CommandHelpOption U = _makeOption(
'U',
'Dump accessibility tree in inverse hit test order.',
'debugDumpSemantics',
);
late final CommandHelpOption a = _makeOption(
'a',
'Toggle timeline events for all widget build methods.',
'debugProfileWidgetBuilds',
);
late final CommandHelpOption b = _makeOption(
'b',
'Toggle platform brightness (dark and light mode).',
'debugBrightnessOverride',
);
late final CommandHelpOption c = _makeOption(
'c',
'Clear the screen',
);
late final CommandHelpOption d = _makeOption(
'd',
'Detach (terminate "flutter run" but leave application running).',
);
late final CommandHelpOption g = _makeOption(
'g',
'Run source code generators.'
);
late final CommandHelpOption hWithDetails = _makeOption(
'h',
'Repeat this help message.',
);
late final CommandHelpOption hWithoutDetails = _makeOption(
'h',
'List all available interactive commands.',
);
late final CommandHelpOption i = _makeOption(
'i',
'Toggle widget inspector.',
'WidgetsApp.showWidgetInspectorOverride',
);
late final CommandHelpOption j = _makeOption(
'j',
'Dump frame raster stats for the current frame. (Unsupported for web)',
);
late final CommandHelpOption k = _makeOption(
'k',
'Toggle CanvasKit rendering.',
);
late final CommandHelpOption o = _makeOption(
'o',
'Simulate different operating systems.',
'defaultTargetPlatform',
);
late final CommandHelpOption p = _makeOption(
'p',
'Toggle the display of construction lines.',
'debugPaintSizeEnabled',
);
late final CommandHelpOption q = _makeOption(
'q',
'Quit (terminate the application on the device).',
);
late final CommandHelpOption r = _makeOption(
'r',
'Hot reload. $fire$fire$fire',
);
late final CommandHelpOption s = _makeOption(
's',
'Save a screenshot to flutter.png.',
);
late final CommandHelpOption t = _makeOption(
't',
'Dump rendering tree to the console.',
'debugDumpRenderTree',
);
late final CommandHelpOption v = _makeOption(
'v',
'Open Flutter DevTools.',
);
late final CommandHelpOption w = _makeOption(
'w',
'Dump widget hierarchy to the console.',
'debugDumpApp',
);
// When updating the list above, see the notes above the list regarding order
// and tests.
CommandHelpOption _makeOption(String key, String description, [
String inParenthesis = '',
]) {
return CommandHelpOption(
key,
description,
inParenthesis: inParenthesis,
logger: _logger,
terminal: _terminal,
platform: _platform,
outputPreferences: _outputPreferences,
);
}
}
/// Encapsulates printing help text for a single option.
class CommandHelpOption {
CommandHelpOption(
this.key,
this.description, {
this.inParenthesis = '',
required Logger logger,
required Terminal terminal,
required Platform platform,
required OutputPreferences outputPreferences,
}) : _logger = logger,
_terminal = terminal,
_platform = platform,
_outputPreferences = outputPreferences;
final Logger _logger;
final Terminal _terminal;
final Platform _platform;
final OutputPreferences _outputPreferences;
/// The key associated with this command.
final String key;
/// A description of what this command does.
final String description;
/// Text shown in parenthesis to give the context.
final String inParenthesis;
bool get _hasTextInParenthesis => inParenthesis.isNotEmpty;
int get _rawMessageLength => key.length + description.length;
@override
String toString() {
final StringBuffer message = StringBuffer();
message.writeAll(<String>[_terminal.bolden(key), description], ' ');
if (!_hasTextInParenthesis) {
return message.toString();
}
bool wrap = false;
final int maxWidth = math.max(
_outputPreferences.wrapColumn,
maxLineWidth,
);
final int adjustedMessageLength = _platform.stdoutSupportsAnsi
? _rawMessageLength + 1
: message.length;
int width = maxWidth - adjustedMessageLength;
final String parentheticalText = '($inParenthesis)';
if (width < parentheticalText.length) {
width = maxWidth;
wrap = true;
}
if (wrap) {
message.write('\n');
}
// pad according to the raw text
message.write(''.padLeft(width - parentheticalText.length));
message.write(_terminal.color(parentheticalText, TerminalColor.grey));
// Terminals seem to require this because we have both bolded and colored
// a line. Otherwise the next line comes out bold until a reset bold.
if (_terminal.supportsColor) {
message.write(AnsiTerminal.resetBold);
}
return message.toString();
}
void print() {
_logger.printStatus(toString());
}
}