mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:09:48 +00:00
[analysis_server] Support formatting leading whitespace at the start or ranges in LSP format range
Fixes https://github.com/Dart-Code/Dart-Code/issues/3583. Change-Id: Id2974b173eb3589ff983316d1cec0ea1e45ecd97 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/218141 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
0fe438812b
commit
9a873bc23f
|
@ -167,7 +167,48 @@ ErrorOr<List<TextEdit>> _generateMinimalEdits(
|
|||
int formattedStart,
|
||||
int formattedEnd,
|
||||
) {
|
||||
final unformattedWhitespace =
|
||||
unformatted.substring(unformattedStart, unformattedEnd);
|
||||
final formattedWhitespace =
|
||||
formatted.substring(formattedStart, formattedEnd);
|
||||
|
||||
if (rangeStart != null && rangeEnd != null) {
|
||||
// If this change crosses over the start of the requested range, discarding
|
||||
// the change may result in leading whitespace of the next line not being
|
||||
// formatted correctly.
|
||||
//
|
||||
// To handle this, if both unformatted/formatted contain at least one
|
||||
// newline, split this change into two around the last newline so that the
|
||||
// final part (likely leading whitespace) can be included without
|
||||
// including the whole change.
|
||||
//
|
||||
// Without this, functionality like VS Code's "format modified lines"
|
||||
// (which uses Git status to know which lines are edited) may appear to
|
||||
// fail to format the first newly added line in a range.
|
||||
if (unformattedStart < rangeStart.result &&
|
||||
unformattedEnd > rangeStart.result &&
|
||||
unformattedWhitespace.contains('\n') &&
|
||||
formattedWhitespace.contains('\n')) {
|
||||
// Find the offsets of the character after the last newlines.
|
||||
final unformattedOffset = unformattedWhitespace.lastIndexOf('\n') + 1;
|
||||
final formattedOffset = formattedWhitespace.lastIndexOf('\n') + 1;
|
||||
// Call us again for the leading part
|
||||
addEditFor(
|
||||
unformattedStart,
|
||||
unformattedStart + unformattedOffset,
|
||||
formattedStart,
|
||||
formattedStart + formattedOffset,
|
||||
);
|
||||
// Call us again for the trailing part
|
||||
addEditFor(
|
||||
unformattedStart + unformattedOffset,
|
||||
unformattedEnd,
|
||||
formattedStart + formattedOffset,
|
||||
formattedEnd,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're formatting only a range, skip over any segments that don't fall
|
||||
// entirely within that range.
|
||||
if (unformattedStart < rangeStart.result ||
|
||||
|
@ -176,11 +217,6 @@ ErrorOr<List<TextEdit>> _generateMinimalEdits(
|
|||
}
|
||||
}
|
||||
|
||||
final unformattedWhitespace =
|
||||
unformatted.substring(unformattedStart, unformattedEnd);
|
||||
final formattedWhitespace =
|
||||
formatted.substring(formattedStart, formattedEnd);
|
||||
|
||||
if (unformattedWhitespace == formattedWhitespace) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,30 @@ void f()
|
|||
await expectRangeFormattedContents(mainFileUri, contents, expected);
|
||||
}
|
||||
|
||||
Future<void> test_formatRange_expandsLeadingWhitespaceToNearestLine() async {
|
||||
const contents = '''
|
||||
void main()
|
||||
{
|
||||
|
||||
[[ print('test'); // line 2
|
||||
print('test'); // line 3
|
||||
print('test'); // line 4]]
|
||||
}
|
||||
''';
|
||||
const expected = '''
|
||||
void main()
|
||||
{
|
||||
|
||||
print('test'); // line 2
|
||||
print('test'); // line 3
|
||||
print('test'); // line 4
|
||||
}
|
||||
''';
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await expectRangeFormattedContents(mainFileUri, contents, expected);
|
||||
}
|
||||
|
||||
Future<void> test_formatRange_invalidRange() async {
|
||||
const contents = '''
|
||||
void f()
|
||||
|
|
Loading…
Reference in a new issue