insertNewSample method

Future<void> insertNewSample({
  1. Type sampleType = SnippetSample,
  2. String? template,
})

Inserts a new sample placeholder into the currentElement, and write it out to the workingFile.

Implementation

Future<void> insertNewSample({Type sampleType = SnippetSample, String? template}) async {
  assert(_workingFile != null, 'Working file must be set to insert a sample');

  // If reloading the file invalidates the current element (because it
  // disappeared), then throw.
  if (_currentElement == null) {
    notifyListeners();
    throw SnippetException(
        'Selected symbol no longer present in file ${workingFile ?? '<none>'}');
  }

  // Find the insertion line automatically. It is either at the end of
  // the comment block, or just before the line that has "See also:" on it, if
  // one exists.
  int? insertAfterLine;
  bool foundSeeAlso = false;
  for (final SourceLine line in _currentElement!.comment) {
    if (line.text.contains('See also:')) {
      insertAfterLine = line.line - 1;
      foundSeeAlso = true;
    }
  }

  // If there's no comment, we want to insert after the line before the
  // location of the element, to be sure to insert before any annotations.
  insertAfterLine ??= _currentElement!.comment.isNotEmpty
      ? _currentElement!.comment.last.line
      : currentElement!.startLine - 1;

  late List<String> insertedTags;
  final List<String> body = <String>[
    '///',
    '/// Replace this text with the description of this sample.',
    '///',
    '/// ```dart',
    '/// Widget build(BuildContext context) {',
    '///   // Sample code goes here.',
    '///   return const SizedBox();',
    '/// }',
    '/// ```',
    '/// {@end-tool}',
    if (foundSeeAlso) '///',
  ];

  switch (sampleType) {
    case SnippetSample:
      insertedTags = <String>[
        if (!foundSeeAlso) '///',
        '/// {@tool snippet}',
        ...body,
      ];
      break;
    case ApplicationSample:
      insertedTags = <String>[
        if (!foundSeeAlso) '///',
        '/// {@tool sample --template=$template}',
        ...body
      ];
      break;
    case DartpadSample:
      insertedTags = <String>[
        if (!foundSeeAlso) '///',
        '/// {@tool dartpad --template=$template}',
        ...body
      ];
      break;
  }

  // Get the indent needed for the new lines.
  final List<String> contents = _workingFileContents!.split('\n');
  final String indent = ' ' * getIndent(contents[insertAfterLine]);
  // Write out the new file, inserting the new tags.
  final List<String> output = contents
    ..insertAll(
      insertAfterLine,
      insertedTags.map<String>((String line) => '$indent$line'),
    );

  _suspendReloads = true;
  await workingFile!.writeAsString(output.join('\n'));

  // Now reload to parse the new sample.
  await reloadWorkingFile(notify: false);

  // If reloading the file invalidates the current element (because it
  // disappeared), then throw.
  if (_currentElement == null) {
    throw SnippetException(
        'Selected symbol no longer present in file ${workingFile ?? '<none>'}');
  }

  // Select the newly inserted sample, assuming that in the reload it was
  // found as the last sample on the current element.
  _currentSample = _currentElement!.samples.last;

  _suspendReloads = false;
  notifyListeners();
}