<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import { illegalArgument, onUnexpectedExternalError } from 'vs/base/common/errors';
import URI from 'vs/base/common/uri';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { TPromise } from 'vs/base/common/winjs.base';
import { Range } from 'vs/editor/common/core/range';
import { ITextModel } from 'vs/editor/common/model';
import { registerDefaultLanguageCommand, registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry, FormattingOptions, TextEdit } from 'vs/editor/common/modes';
import { IModelService } from 'vs/editor/common/services/modelService';
import { asWinJsPromise, sequence } from 'vs/base/common/async';
import { Position } from 'vs/editor/common/core/position';

export class NoProviderError extends Error {

	static readonly Name = 'NOPRO';

	constructor(message?: string) {
		super();
		this.name = NoProviderError.Name;
		this.message = message;
	}
}

export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions): TPromise<TextEdit[], NoProviderError> {

	const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model);

	if (providers.length === 0) {
		return TPromise.wrapError(new NoProviderError());
	}

	let result: TextEdit[];
	return sequence(providers.map(provider => {
		return () => {
			if (!isFalsyOrEmpty(result)) {
				return undefined;
			}
			return asWinJsPromise(token => provider.provideDocumentRangeFormattingEdits(model, range, options, token)).then(value => {
				result = value;
			}, onUnexpectedExternalError);
		};
	})).then(() => result);
}

export function getDocumentFormattingEdits(model: ITextModel, options: FormattingOptions): TPromise<TextEdit[]> {
	const providers = DocumentFormattingEditProviderRegistry.ordered(model);

	// try range formatters when no document formatter is registered
	if (providers.length === 0) {
		return getDocumentRangeFormattingEdits(model, model.getFullModelRange(), options);
	}

	let result: TextEdit[];
	return sequence(providers.map(provider => {
		return () => {
			if (!isFalsyOrEmpty(result)) {
				return undefined;
			}
			return asWinJsPromise(token => provider.provideDocumentFormattingEdits(model, options, token)).then(value => {
				result = value;
			}, onUnexpectedExternalError);
		};
	})).then(() => result);
}

export function getOnTypeFormattingEdits(model: ITextModel, position: Position, ch: string, options: FormattingOptions): TPromise<TextEdit[]> {
	const [support] = OnTypeFormattingEditProviderRegistry.ordered(model);
	if (!support) {
		return TPromise.as(undefined);<commit_msg>Use first instead of sequence to pick first result<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { illegalArgument, onUnexpectedExternalError } from 'vs/base/common/errors';
import URI from 'vs/base/common/uri';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { TPromise } from 'vs/base/common/winjs.base';
import { Range } from 'vs/editor/common/core/range';
import { ITextModel } from 'vs/editor/common/model';
import { registerDefaultLanguageCommand, registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry, FormattingOptions, TextEdit } from 'vs/editor/common/modes';
import { IModelService } from 'vs/editor/common/services/modelService';
import { asWinJsPromise, first } from 'vs/base/common/async';
import { Position } from 'vs/editor/common/core/position';

export class NoProviderError extends Error {

	static readonly Name = 'NOPRO';

	constructor(message?: string) {
		super();
		this.name = NoProviderError.Name;
		this.message = message;
	}
}

export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions): TPromise<TextEdit[], NoProviderError> {

	const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model);

	if (providers.length === 0) {
		return TPromise.wrapError(new NoProviderError());
	}

	return first(providers.map(provider => () => {
		return asWinJsPromise(token => provider.provideDocumentRangeFormattingEdits(model, range, options, token))
			.then(undefined, onUnexpectedExternalError);
	}), result => !isFalsyOrEmpty(result));
}

export function getDocumentFormattingEdits(model: ITextModel, options: FormattingOptions): TPromise<TextEdit[]> {
	const providers = DocumentFormattingEditProviderRegistry.ordered(model);

	// try range formatters when no document formatter is registered
	if (providers.length === 0) {
		return getDocumentRangeFormattingEdits(model, model.getFullModelRange(), options);
	}

	return first(providers.map(provider => () => {
		return asWinJsPromise(token => provider.provideDocumentFormattingEdits(model, options, token))
			.then(undefined, onUnexpectedExternalError);
	}), result => !isFalsyOrEmpty(result));
}

export function getOnTypeFormattingEdits(model: ITextModel, position: Position, ch: string, options: FormattingOptions): TPromise<TextEdit[]> {
	const [support] = OnTypeFormattingEditProviderRegistry.ordered(model);
	if (!support) {
		return TPromise.as(undefined);
{'fraction_non_alphanumeric': 0.17137602407624142, 'fraction_numerical': 0.0006687844841999665, 'mean_word_length': 4.156896551724138, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3938757', 'n_tokens_mistral': 1643, 'n_tokens_neox': 1574, 'n_words': 377}