src/vs/editor/contrib/smartSelect/browser/smartSelect.ts/provideSelectionRanges
export async function provideSelectionRanges(registry: LanguageFeatureRegistry<languages.SelectionRangeProvider>, model: ITextModel, positions: Position[], options: SelectionRangesOptions, token: CancellationToken): Promise<Range[][]> {

	const providers = registry.all(model)
		.concat(new WordSelectionRangeProvider()); // ALWAYS have word based selection range

	if (providers.length === 1) {
		// add word selection and bracket selection when no provider exists
		providers.unshift(new BracketSelectionRangeProvider());
	}

	let work: Promise<any>[] = [];
	let allRawRanges: Range[][] = [];

	for (const provider of providers) {

		work.push(Promise.resolve(provider.provideSelectionRanges(model, positions, token)).then(allProviderRanges => {
			if (arrays.isNonEmptyArray(allProviderRanges) && allProviderRanges.length === positions.length) {
				for (let i = 0; i < positions.length; i++) {
					if (!allRawRanges[i]) {
						allRawRanges[i] = [];
					}
					for (const oneProviderRanges of allProviderRanges[i]) {
						if (Range.isIRange(oneProviderRanges.range) && Range.containsPosition(oneProviderRanges.range, positions[i])) {
							allRawRanges[i].push(Range.lift(oneProviderRanges.range));
						}
					}
				}
			}
		}, onUnexpectedExternalError));
	}

	await Promise.all(work);

	return allRawRanges.map(oneRawRanges => {

		if (oneRawRanges.length === 0) {
			return [];
		}

		// sort all by start/end position
		oneRawRanges.sort((a, b) => {
			if (Position.isBefore(a.getStartPosition(), b.getStartPosition())) {
				return 1;
			} else if (Position.isBefore(b.getStartPosition(), a.getStartPosition())) {
				return -1;
			} else if (Position.isBefore(a.getEndPosition(), b.getEndPosition())) {
				return -1;
			} else if (Position.isBefore(b.getEndPosition(), a.getEndPosition())) {
				return 1;
			} else {
				return 0;
			}
		});

		// remove ranges that don't contain the former range or that are equal to the
		// former range
		let oneRanges: Range[] = [];
		let last: Range | undefined;
		for (const range of oneRawRanges) {
			if (!last || (Range.containsRange(range, last) && !Range.equalsRange(range, last))) {
				oneRanges.push(range);
				last = range;
			}
		}

		if (!options.selectLeadingAndTrailingWhitespace) {
			return oneRanges;
		}

		// add ranges that expand trivia at line starts and ends whenever a range
		// wraps onto the a new line
		let oneRangesWithTrivia: Range[] = [oneRanges[0]];
		for (let i = 1; i < oneRanges.length; i++) {
			const prev = oneRanges[i - 1];
			const cur = oneRanges[i];
			if (cur.startLineNumber !== prev.startLineNumber || cur.endLineNumber !== prev.endLineNumber) {
				// add line/block range without leading/failing whitespace
				const rangeNoWhitespace = new Range(prev.startLineNumber, model.getLineFirstNonWhitespaceColumn(prev.startLineNumber), prev.endLineNumber, model.getLineLastNonWhitespaceColumn(prev.endLineNumber));
				if (rangeNoWhitespace.containsRange(prev) && !rangeNoWhitespace.equalsRange(prev) && cur.containsRange(rangeNoWhitespace) && !cur.equalsRange(rangeNoWhitespace)) {
					oneRangesWithTrivia.push(rangeNoWhitespace);
				}
				// add line/block range
				const rangeFull = new Range(prev.startLineNumber, 1, prev.endLineNumber, model.getLineMaxColumn(prev.endLineNumber));
				if (rangeFull.containsRange(prev) && !rangeFull.equalsRange(rangeNoWhitespace) && cur.containsRange(rangeFull) && !cur.equalsRange(rangeFull)) {
					oneRangesWithTrivia.push(rangeFull);
				}
			}
			oneRangesWithTrivia.push(cur);
		}
		return oneRangesWithTrivia;
	});
}