Future insertNewSample()

in packages/sampler/lib/model.dart [228:326]


  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();
  }