Path: blob/main/src/vs/editor/contrib/indentation/test/browser/indentation.test.ts
4780 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { DisposableStore, IDisposable } from '../../../../../base/common/lifecycle.js';7import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';8import { ILanguageConfigurationService } from '../../../../common/languages/languageConfigurationRegistry.js';9import { createTextModel } from '../../../../test/common/testTextModel.js';10import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';11import { Range } from '../../../../common/core/range.js';12import { Selection } from '../../../../common/core/selection.js';13import { MetadataConsts, StandardTokenType } from '../../../../common/encodedTokenAttributes.js';14import { EncodedTokenizationResult, IState, ITokenizationSupport, TokenizationRegistry } from '../../../../common/languages.js';15import { ILanguageService } from '../../../../common/languages/language.js';16import { NullState } from '../../../../common/languages/nullTokenize.js';17import { AutoIndentOnPaste, IndentationToSpacesCommand, IndentationToTabsCommand } from '../../browser/indentation.js';18import { withTestCodeEditor } from '../../../../test/browser/testCodeEditor.js';19import { testCommand } from '../../../../test/browser/testCommand.js';20import { goIndentationRules, htmlIndentationRules, javascriptIndentationRules, latexIndentationRules, luaIndentationRules, phpIndentationRules, rubyIndentationRules, vbIndentationRules } from '../../../../test/common/modes/supports/indentationRules.js';21import { cppOnEnterRules, htmlOnEnterRules, javascriptOnEnterRules, phpOnEnterRules } from '../../../../test/common/modes/supports/onEnterRules.js';22import { TypeOperations } from '../../../../common/cursor/cursorTypeOperations.js';23import { cppBracketRules, goBracketRules, htmlBracketRules, latexBracketRules, luaBracketRules, phpBracketRules, rubyBracketRules, typescriptBracketRules, vbBracketRules } from '../../../../test/common/modes/supports/bracketRules.js';24import { javascriptAutoClosingPairsRules, latexAutoClosingPairsRules } from '../../../../test/common/modes/supports/autoClosingPairsRules.js';25import { LanguageService } from '../../../../common/services/languageService.js';26import { ServiceCollection } from '../../../../../platform/instantiation/common/serviceCollection.js';27import { TestLanguageConfigurationService } from '../../../../test/common/modes/testLanguageConfigurationService.js';2829export enum Language {30TypeScript = 'ts-test',31Ruby = 'ruby-test',32PHP = 'php-test',33Go = 'go-test',34CPP = 'cpp-test',35HTML = 'html-test',36VB = 'vb-test',37Latex = 'latex-test',38Lua = 'lua-test'39}4041function testIndentationToSpacesCommand(lines: string[], selection: Selection, tabSize: number, expectedLines: string[], expectedSelection: Selection): void {42testCommand(lines, null, selection, (accessor, sel) => new IndentationToSpacesCommand(sel, tabSize), expectedLines, expectedSelection);43}4445function testIndentationToTabsCommand(lines: string[], selection: Selection, tabSize: number, expectedLines: string[], expectedSelection: Selection): void {46testCommand(lines, null, selection, (accessor, sel) => new IndentationToTabsCommand(sel, tabSize), expectedLines, expectedSelection);47}4849export function registerLanguage(languageService: ILanguageService, language: Language): IDisposable {50return languageService.registerLanguage({ id: language });51}5253export function registerLanguageConfiguration(languageConfigurationService: ILanguageConfigurationService, language: Language): IDisposable {54switch (language) {55case Language.TypeScript:56return languageConfigurationService.register(language, {57brackets: typescriptBracketRules,58comments: {59lineComment: '//',60blockComment: ['/*', '*/']61},62autoClosingPairs: javascriptAutoClosingPairsRules,63indentationRules: javascriptIndentationRules,64onEnterRules: javascriptOnEnterRules65});66case Language.Ruby:67return languageConfigurationService.register(language, {68brackets: rubyBracketRules,69indentationRules: rubyIndentationRules,70});71case Language.PHP:72return languageConfigurationService.register(language, {73brackets: phpBracketRules,74indentationRules: phpIndentationRules,75onEnterRules: phpOnEnterRules76});77case Language.Go:78return languageConfigurationService.register(language, {79brackets: goBracketRules,80indentationRules: goIndentationRules81});82case Language.CPP:83return languageConfigurationService.register(language, {84brackets: cppBracketRules,85onEnterRules: cppOnEnterRules86});87case Language.HTML:88return languageConfigurationService.register(language, {89brackets: htmlBracketRules,90indentationRules: htmlIndentationRules,91onEnterRules: htmlOnEnterRules92});93case Language.VB:94return languageConfigurationService.register(language, {95brackets: vbBracketRules,96indentationRules: vbIndentationRules,97});98case Language.Latex:99return languageConfigurationService.register(language, {100brackets: latexBracketRules,101autoClosingPairs: latexAutoClosingPairsRules,102indentationRules: latexIndentationRules103});104case Language.Lua:105return languageConfigurationService.register(language, {106brackets: luaBracketRules,107indentationRules: luaIndentationRules108});109}110}111112export interface StandardTokenTypeData {113startIndex: number;114standardTokenType: StandardTokenType;115}116117export function registerTokenizationSupport(instantiationService: TestInstantiationService, tokens: StandardTokenTypeData[][], languageId: Language): IDisposable {118let lineIndex = 0;119const languageService = instantiationService.get(ILanguageService);120const tokenizationSupport: ITokenizationSupport = {121getInitialState: () => NullState,122tokenize: undefined!,123tokenizeEncoded: (line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult => {124const tokensOnLine = tokens[lineIndex++];125const encodedLanguageId = languageService.languageIdCodec.encodeLanguageId(languageId);126const result = new Uint32Array(2 * tokensOnLine.length);127for (let i = 0; i < tokensOnLine.length; i++) {128result[2 * i] = tokensOnLine[i].startIndex;129result[2 * i + 1] =130(131(encodedLanguageId << MetadataConsts.LANGUAGEID_OFFSET)132| (tokensOnLine[i].standardTokenType << MetadataConsts.TOKEN_TYPE_OFFSET)133);134}135return new EncodedTokenizationResult(result, [], state);136}137};138return TokenizationRegistry.register(languageId, tokenizationSupport);139}140141suite('Change Indentation to Spaces - TypeScript/Javascript', () => {142143ensureNoDisposablesAreLeakedInTestSuite();144145test('single tabs only at start of line', function () {146testIndentationToSpacesCommand(147[148'first',149'second line',150'third line',151'\tfourth line',152'\tfifth'153],154new Selection(2, 3, 2, 3),1554,156[157'first',158'second line',159'third line',160' fourth line',161' fifth'162],163new Selection(2, 3, 2, 3)164);165});166167test('multiple tabs at start of line', function () {168testIndentationToSpacesCommand(169[170'\t\tfirst',171'\tsecond line',172'\t\t\t third line',173'fourth line',174'fifth'175],176new Selection(1, 5, 1, 5),1773,178[179' first',180' second line',181' third line',182'fourth line',183'fifth'184],185new Selection(1, 9, 1, 9)186);187});188189test('multiple tabs', function () {190testIndentationToSpacesCommand(191[192'\t\tfirst\t',193'\tsecond \t line \t',194'\t\t\t third line',195' \tfourth line',196'fifth'197],198new Selection(1, 5, 1, 5),1992,200[201' first\t',202' second \t line \t',203' third line',204' fourth line',205'fifth'206],207new Selection(1, 7, 1, 7)208);209});210211test('empty lines', function () {212testIndentationToSpacesCommand(213[214'\t\t\t',215'\t',216'\t\t'217],218new Selection(1, 4, 1, 4),2192,220[221' ',222' ',223' '224],225new Selection(1, 4, 1, 4)226);227});228});229230suite('Change Indentation to Tabs - TypeScript/Javascript', () => {231232ensureNoDisposablesAreLeakedInTestSuite();233234test('spaces only at start of line', function () {235testIndentationToTabsCommand(236[237' first',238'second line',239' third line',240'fourth line',241'fifth'242],243new Selection(2, 3, 2, 3),2444,245[246'\tfirst',247'second line',248'\tthird line',249'fourth line',250'fifth'251],252new Selection(2, 3, 2, 3)253);254});255256test('multiple spaces at start of line', function () {257testIndentationToTabsCommand(258[259'first',260' second line',261' third line',262'fourth line',263' fifth'264],265new Selection(1, 5, 1, 5),2663,267[268'first',269'\tsecond line',270'\t\t\t third line',271'fourth line',272'\t fifth'273],274new Selection(1, 5, 1, 5)275);276});277278test('multiple spaces', function () {279testIndentationToTabsCommand(280[281' first ',282' second line \t',283' third line',284' fourth line',285'fifth'286],287new Selection(1, 8, 1, 8),2882,289[290'\t\t\tfirst ',291'\tsecond line \t',292'\t\t\t third line',293'\t fourth line',294'fifth'295],296new Selection(1, 5, 1, 5)297);298});299300test('issue #45996', function () {301testIndentationToSpacesCommand(302[303'\tabc',304],305new Selection(1, 3, 1, 3),3064,307[308' abc',309],310new Selection(1, 6, 1, 6)311);312});313});314315suite('Indent With Tab - TypeScript/JavaScript', () => {316317const languageId = Language.TypeScript;318let disposables: DisposableStore;319let serviceCollection: ServiceCollection;320321setup(() => {322disposables = new DisposableStore();323const languageService = new LanguageService();324const languageConfigurationService = new TestLanguageConfigurationService();325disposables.add(languageService);326disposables.add(languageConfigurationService);327disposables.add(registerLanguage(languageService, languageId));328disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));329serviceCollection = new ServiceCollection(330[ILanguageService, languageService],331[ILanguageConfigurationService, languageConfigurationService]332);333});334335teardown(() => {336disposables.dispose();337});338339ensureNoDisposablesAreLeakedInTestSuite();340341test('temp issue because there should be at least one passing test in a suite', () => {342assert.ok(true);343});344345test.skip('issue #63388: perserve correct indentation on tab 1', () => {346347// https://github.com/microsoft/vscode/issues/63388348349const model = createTextModel([350'/*',351' * Comment',352' * /',353].join('\n'), languageId, {});354disposables.add(model);355356withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {357editor.setSelection(new Selection(1, 1, 3, 5));358editor.executeCommands('editor.action.indentLines', TypeOperations.indent(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));359assert.strictEqual(model.getValue(), [360' /*',361' * Comment',362' * /',363].join('\n'));364});365});366367test.skip('issue #63388: perserve correct indentation on tab 2', () => {368369// https://github.com/microsoft/vscode/issues/63388370371const model = createTextModel([372'switch (something) {',373' case 1:',374' whatever();',375' break;',376'}',377].join('\n'), languageId, {});378disposables.add(model);379380withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {381editor.setSelection(new Selection(1, 1, 5, 2));382editor.executeCommands('editor.action.indentLines', TypeOperations.indent(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));383assert.strictEqual(model.getValue(), [384' switch (something) {',385' case 1:',386' whatever();',387' break;',388' }',389].join('\n'));390});391});392});393394suite('Auto Indent On Paste - TypeScript/JavaScript', () => {395396const languageId = Language.TypeScript;397let disposables: DisposableStore;398let serviceCollection: ServiceCollection;399400setup(() => {401disposables = new DisposableStore();402const languageService = new LanguageService();403const languageConfigurationService = new TestLanguageConfigurationService();404disposables.add(languageService);405disposables.add(languageConfigurationService);406disposables.add(registerLanguage(languageService, languageId));407disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));408serviceCollection = new ServiceCollection(409[ILanguageService, languageService],410[ILanguageConfigurationService, languageConfigurationService]411);412});413414teardown(() => {415disposables.dispose();416});417418ensureNoDisposablesAreLeakedInTestSuite();419420test('issue #119225: Do not add extra leading space when pasting JSDoc', () => {421422const model = createTextModel('', languageId, {});423disposables.add(model);424425withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {426const pasteText = [427'/**',428' * JSDoc',429' */',430'function a() {}'431].join('\n');432const tokens: StandardTokenTypeData[][] = [433[434{ startIndex: 0, standardTokenType: StandardTokenType.Comment },435{ startIndex: 3, standardTokenType: StandardTokenType.Comment },436],437[438{ startIndex: 0, standardTokenType: StandardTokenType.Comment },439{ startIndex: 2, standardTokenType: StandardTokenType.Comment },440{ startIndex: 8, standardTokenType: StandardTokenType.Comment },441],442[443{ startIndex: 0, standardTokenType: StandardTokenType.Comment },444{ startIndex: 1, standardTokenType: StandardTokenType.Comment },445{ startIndex: 3, standardTokenType: StandardTokenType.Other },446],447[448{ startIndex: 0, standardTokenType: StandardTokenType.Other },449{ startIndex: 8, standardTokenType: StandardTokenType.Other },450{ startIndex: 9, standardTokenType: StandardTokenType.Other },451{ startIndex: 10, standardTokenType: StandardTokenType.Other },452{ startIndex: 11, standardTokenType: StandardTokenType.Other },453{ startIndex: 12, standardTokenType: StandardTokenType.Other },454{ startIndex: 13, standardTokenType: StandardTokenType.Other },455{ startIndex: 14, standardTokenType: StandardTokenType.Other },456{ startIndex: 15, standardTokenType: StandardTokenType.Other },457]458];459disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));460const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);461viewModel.paste(pasteText, true, undefined, 'keyboard');462autoIndentOnPasteController.trigger(new Range(1, 1, 4, 16));463assert.strictEqual(model.getValue(), pasteText);464});465});466467test('issue #167299: Blank line removes indent', () => {468469const model = createTextModel('', languageId, {});470disposables.add(model);471472withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {473474// no need for tokenization because there are no comments475const pasteText = [476'',477'export type IncludeReference =',478' | BaseReference',479' | SelfReference',480' | RelativeReference;',481'',482'export const enum IncludeReferenceKind {',483' Base,',484' Self,',485' RelativeReference,',486'}'487].join('\n');488489const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);490viewModel.paste(pasteText, true, undefined, 'keyboard');491autoIndentOnPasteController.trigger(new Range(1, 1, 11, 2));492assert.strictEqual(model.getValue(), pasteText);493});494});495496test('issue #29803: do not indent when pasting text with only one line', () => {497498// https://github.com/microsoft/vscode/issues/29803499500const model = createTextModel([501'const linkHandler = new Class(a, b, c,',502' d)'503].join('\n'), languageId, {});504disposables.add(model);505506withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {507editor.setSelection(new Selection(2, 6, 2, 6));508const text = ', null';509viewModel.paste(text, true, undefined, 'keyboard');510const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);511autoIndentOnPasteController.trigger(new Range(2, 6, 2, 11));512assert.strictEqual(model.getValue(), [513'const linkHandler = new Class(a, b, c,',514' d, null)'515].join('\n'));516});517});518519test('issue #29753: incorrect indentation after comment', () => {520521// https://github.com/microsoft/vscode/issues/29753522523const model = createTextModel([524'class A {',525' /**',526' * used only for debug purposes.',527' */',528' private _codeInfo: KeyMapping[];',529'}',530].join('\n'), languageId, {});531disposables.add(model);532533withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {534editor.setSelection(new Selection(5, 24, 5, 34));535const text = 'IMacLinuxKeyMapping';536viewModel.paste(text, true, undefined, 'keyboard');537const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);538autoIndentOnPasteController.trigger(new Range(5, 24, 5, 43));539assert.strictEqual(model.getValue(), [540'class A {',541' /**',542' * used only for debug purposes.',543' */',544' private _codeInfo: IMacLinuxKeyMapping[];',545'}',546].join('\n'));547});548});549550test('issue #29753: incorrect indentation of header comment', () => {551552// https://github.com/microsoft/vscode/issues/29753553554const model = createTextModel('', languageId, {});555disposables.add(model);556557withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {558const text = [559'/*----------------',560' * Copyright (c) ',561' * Licensed under ...',562' *-----------------*/',563].join('\n');564viewModel.paste(text, true, undefined, 'keyboard');565const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);566autoIndentOnPasteController.trigger(new Range(1, 1, 4, 22));567assert.strictEqual(model.getValue(), text);568});569});570571test('issue #209859: do not do change indentation when pasted inside of a string', () => {572573// issue: https://github.com/microsoft/vscode/issues/209859574// issue: https://github.com/microsoft/vscode/issues/209418575576const initialText = [577'const foo = "some text',578' which is strangely',579' indented"'580].join('\n');581const model = createTextModel(initialText, languageId, {});582disposables.add(model);583584withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {585const tokens: StandardTokenTypeData[][] = [586[587{ startIndex: 0, standardTokenType: StandardTokenType.Other },588{ startIndex: 12, standardTokenType: StandardTokenType.String },589],590[591{ startIndex: 0, standardTokenType: StandardTokenType.String },592],593[594{ startIndex: 0, standardTokenType: StandardTokenType.String },595]596];597disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));598599editor.setSelection(new Selection(2, 10, 2, 15));600viewModel.paste('which', true, undefined, 'keyboard');601const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);602autoIndentOnPasteController.trigger(new Range(2, 1, 2, 28));603assert.strictEqual(model.getValue(), initialText);604});605});606607// Failing tests found in issues...608609test.skip('issue #181065: Incorrect paste of object within comment', () => {610611// https://github.com/microsoft/vscode/issues/181065612613const model = createTextModel('', languageId, {});614disposables.add(model);615616withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {617const text = [618'/**',619' * @typedef {',620' * }',621' */'622].join('\n');623const tokens: StandardTokenTypeData[][] = [624[625{ startIndex: 0, standardTokenType: StandardTokenType.Comment },626{ startIndex: 3, standardTokenType: StandardTokenType.Comment },627],628[629{ startIndex: 0, standardTokenType: StandardTokenType.Comment },630{ startIndex: 2, standardTokenType: StandardTokenType.Comment },631{ startIndex: 3, standardTokenType: StandardTokenType.Comment },632{ startIndex: 11, standardTokenType: StandardTokenType.Comment },633{ startIndex: 12, standardTokenType: StandardTokenType.Other },634{ startIndex: 13, standardTokenType: StandardTokenType.Other },635],636[637{ startIndex: 0, standardTokenType: StandardTokenType.Comment },638{ startIndex: 2, standardTokenType: StandardTokenType.Other },639{ startIndex: 3, standardTokenType: StandardTokenType.Other },640{ startIndex: 4, standardTokenType: StandardTokenType.Other },641],642[643{ startIndex: 0, standardTokenType: StandardTokenType.Comment },644{ startIndex: 1, standardTokenType: StandardTokenType.Comment },645{ startIndex: 3, standardTokenType: StandardTokenType.Other },646]647];648disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));649const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);650viewModel.paste(text, true, undefined, 'keyboard');651autoIndentOnPasteController.trigger(new Range(1, 1, 4, 4));652assert.strictEqual(model.getValue(), text);653});654});655656test.skip('issue #86301: preserve cursor at inserted indentation level', () => {657658// https://github.com/microsoft/vscode/issues/86301659660const model = createTextModel([661'() => {',662'',663'}',664].join('\n'), languageId, {});665disposables.add(model);666667withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {668editor.setSelection(new Selection(2, 1, 2, 1));669const text = [670'() => {',671'',672'}',673''674].join('\n');675const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);676viewModel.paste(text, true, undefined, 'keyboard');677autoIndentOnPasteController.trigger(new Range(2, 1, 5, 1));678679// notes:680// why is line 3 not indented to the same level as line 2?681// looks like the indentation is inserted correctly at line 5, but the cursor does not appear at the maximum indentation level?682assert.strictEqual(model.getValue(), [683'() => {',684' () => {',685' ', // <- should also be indented686' }',687' ', // <- cursor should be at the end of the indentation688'}',689].join('\n'));690691const selection = viewModel.getSelection();692assert.deepStrictEqual(selection, new Selection(5, 5, 5, 5));693});694});695696test.skip('issue #85781: indent line with extra white space', () => {697698// https://github.com/microsoft/vscode/issues/85781699// note: still to determine whether this is a bug or not700701const model = createTextModel([702'() => {',703' console.log("a");',704'}',705].join('\n'), languageId, {});706disposables.add(model);707708withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {709editor.setSelection(new Selection(2, 5, 2, 5));710const text = [711'() => {',712' console.log("b")',713'}',714' '715].join('\n');716const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);717viewModel.paste(text, true, undefined, 'keyboard');718// todo@aiday-mar, make sure range is correct, and make test work as in real life719autoIndentOnPasteController.trigger(new Range(2, 5, 5, 6));720assert.strictEqual(model.getValue(), [721'() => {',722' () => {',723' console.log("b")',724' }',725' console.log("a");',726'}',727].join('\n'));728});729});730731test.skip('issue #29589: incorrect indentation of closing brace on paste', () => {732733// https://github.com/microsoft/vscode/issues/29589734735const model = createTextModel('', languageId, {});736disposables.add(model);737738withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {739editor.setSelection(new Selection(2, 5, 2, 5));740const text = [741'function makeSub(a,b) {',742'subsent = sent.substring(a,b);',743'return subsent;',744'}',745].join('\n');746const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);747viewModel.paste(text, true, undefined, 'keyboard');748// todo@aiday-mar, make sure range is correct, and make test work as in real life749autoIndentOnPasteController.trigger(new Range(1, 1, 4, 2));750assert.strictEqual(model.getValue(), [751'function makeSub(a,b) {',752'subsent = sent.substring(a,b);',753'return subsent;',754'}',755].join('\n'));756});757});758759test.skip('issue #201420: incorrect indentation when first line is comment', () => {760761// https://github.com/microsoft/vscode/issues/201420762763const model = createTextModel([764'function bar() {',765'',766'}',767].join('\n'), languageId, {});768disposables.add(model);769770withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {771const tokens: StandardTokenTypeData[][] = [772[773{ startIndex: 0, standardTokenType: StandardTokenType.Other },774{ startIndex: 8, standardTokenType: StandardTokenType.Other },775{ startIndex: 9, standardTokenType: StandardTokenType.Other },776{ startIndex: 12, standardTokenType: StandardTokenType.Other },777{ startIndex: 13, standardTokenType: StandardTokenType.Other },778{ startIndex: 14, standardTokenType: StandardTokenType.Other },779{ startIndex: 15, standardTokenType: StandardTokenType.Other },780{ startIndex: 16, standardTokenType: StandardTokenType.Other }781],782[783{ startIndex: 0, standardTokenType: StandardTokenType.Comment },784{ startIndex: 2, standardTokenType: StandardTokenType.Comment },785{ startIndex: 3, standardTokenType: StandardTokenType.Comment },786{ startIndex: 10, standardTokenType: StandardTokenType.Comment }787],788[789{ startIndex: 0, standardTokenType: StandardTokenType.Other },790{ startIndex: 5, standardTokenType: StandardTokenType.Other },791{ startIndex: 6, standardTokenType: StandardTokenType.Other },792{ startIndex: 9, standardTokenType: StandardTokenType.Other },793{ startIndex: 10, standardTokenType: StandardTokenType.Other },794{ startIndex: 11, standardTokenType: StandardTokenType.Other },795{ startIndex: 12, standardTokenType: StandardTokenType.Other },796{ startIndex: 14, standardTokenType: StandardTokenType.Other }],797[798{ startIndex: 0, standardTokenType: StandardTokenType.Other },799{ startIndex: 1, standardTokenType: StandardTokenType.Other }]800];801disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));802803editor.setSelection(new Selection(2, 1, 2, 1));804const text = [805'// comment',806'const foo = 42',807].join('\n');808const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);809viewModel.paste(text, true, undefined, 'keyboard');810autoIndentOnPasteController.trigger(new Range(2, 1, 3, 15));811assert.strictEqual(model.getValue(), [812'function bar() {',813' // comment',814' const foo = 42',815'}',816].join('\n'));817});818});819});820821suite('Auto Indent On Type - TypeScript/JavaScript', () => {822823const languageId = Language.TypeScript;824let disposables: DisposableStore;825let serviceCollection: ServiceCollection;826827setup(() => {828disposables = new DisposableStore();829const languageService = new LanguageService();830const languageConfigurationService = new TestLanguageConfigurationService();831disposables.add(languageService);832disposables.add(languageConfigurationService);833disposables.add(registerLanguage(languageService, languageId));834disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));835serviceCollection = new ServiceCollection(836[ILanguageService, languageService],837[ILanguageConfigurationService, languageConfigurationService]838);839});840841teardown(() => {842disposables.dispose();843});844845ensureNoDisposablesAreLeakedInTestSuite();846847// Failing tests from issues...848849test('issue #208215: indent after arrow function', () => {850851// https://github.com/microsoft/vscode/issues/208215852853const model = createTextModel('', languageId, {});854disposables.add(model);855856withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {857viewModel.type('const add1 = (n) =>');858viewModel.type('\n', 'keyboard');859assert.strictEqual(model.getValue(), [860'const add1 = (n) =>',861' ',862].join('\n'));863});864});865866test('issue #208215: indent after arrow function 2', () => {867868// https://github.com/microsoft/vscode/issues/208215869870const model = createTextModel([871'const array = [1, 2, 3, 4, 5];',872'array.map(',873' v =>',874].join('\n'), languageId, {});875disposables.add(model);876877withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {878editor.setSelection(new Selection(3, 9, 3, 9));879viewModel.type('\n', 'keyboard');880assert.strictEqual(model.getValue(), [881'const array = [1, 2, 3, 4, 5];',882'array.map(',883' v =>',884' '885].join('\n'));886});887});888889test('issue #116843: indent after arrow function', () => {890891// https://github.com/microsoft/vscode/issues/116843892893const model = createTextModel('', languageId, {});894disposables.add(model);895896withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {897viewModel.type([898'const add1 = (n) =>',899' n + 1;',900].join('\n'));901viewModel.type('\n', 'keyboard');902assert.strictEqual(model.getValue(), [903'const add1 = (n) =>',904' n + 1;',905'',906].join('\n'));907});908});909910test('issue #29755: do not add indentation on enter if indentation is already valid', () => {911912//https://github.com/microsoft/vscode/issues/29755913914const model = createTextModel([915'function f() {',916' const one = 1;',917' const two = 2;',918'}',919].join('\n'), languageId, {});920disposables.add(model);921922withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {923editor.setSelection(new Selection(3, 1, 3, 1));924viewModel.type('\n', 'keyboard');925assert.strictEqual(model.getValue(), [926'function f() {',927' const one = 1;',928'',929' const two = 2;',930'}',931].join('\n'));932});933});934935test('issue #36090', () => {936937// https://github.com/microsoft/vscode/issues/36090938939const model = createTextModel([940'class ItemCtrl {',941' getPropertiesByItemId(id) {',942' return this.fetchItem(id)',943' .then(item => {',944' return this.getPropertiesOfItem(item);',945' });',946' }',947'}',948].join('\n'), languageId, {});949disposables.add(model);950951withTestCodeEditor(model, { autoIndent: 'advanced', serviceCollection }, (editor, viewModel) => {952editor.setSelection(new Selection(7, 6, 7, 6));953viewModel.type('\n', 'keyboard');954assert.strictEqual(model.getValue(),955[956'class ItemCtrl {',957' getPropertiesByItemId(id) {',958' return this.fetchItem(id)',959' .then(item => {',960' return this.getPropertiesOfItem(item);',961' });',962' }',963' ',964'}',965].join('\n')966);967assert.deepStrictEqual(editor.getSelection(), new Selection(8, 5, 8, 5));968});969});970971test('issue #115304: indent block comment onEnter', () => {972973// https://github.com/microsoft/vscode/issues/115304974975const model = createTextModel([976'/** */',977'function f() {}',978].join('\n'), languageId, {});979disposables.add(model);980981withTestCodeEditor(model, { autoIndent: 'advanced', serviceCollection }, (editor, viewModel) => {982editor.setSelection(new Selection(1, 4, 1, 4));983viewModel.type('\n', 'keyboard');984assert.strictEqual(model.getValue(),985[986'/**',987' * ',988' */',989'function f() {}',990].join('\n')991);992assert.deepStrictEqual(editor.getSelection(), new Selection(2, 4, 2, 4));993});994});995996test('issue #43244: indent when lambda arrow function is detected, outdent when end is reached', () => {997998// https://github.com/microsoft/vscode/issues/432449991000const model = createTextModel([1001'const array = [1, 2, 3, 4, 5];',1002'array.map(_)'1003].join('\n'), languageId, {});1004disposables.add(model);10051006withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1007editor.setSelection(new Selection(2, 12, 2, 12));1008viewModel.type('\n', 'keyboard');1009assert.strictEqual(model.getValue(), [1010'const array = [1, 2, 3, 4, 5];',1011'array.map(_',1012' ',1013')'1014].join('\n'));1015});1016});10171018test('issue #43244: incorrect indentation after if/for/while without braces', () => {10191020// https://github.com/microsoft/vscode/issues/4324410211022const model = createTextModel([1023'function f() {',1024' if (condition)',1025'}'1026].join('\n'), languageId, {});1027disposables.add(model);10281029withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1030editor.setSelection(new Selection(2, 19, 2, 19));1031viewModel.type('\n', 'keyboard');1032assert.strictEqual(model.getValue(), [1033'function f() {',1034' if (condition)',1035' ',1036'}',1037].join('\n'));10381039viewModel.type('return;');1040viewModel.type('\n', 'keyboard');1041assert.strictEqual(model.getValue(), [1042'function f() {',1043' if (condition)',1044' return;',1045' ',1046'}',1047].join('\n'));1048});1049});10501051test('issue #208232: incorrect indentation inside of comments', () => {10521053// https://github.com/microsoft/vscode/issues/20823210541055const model = createTextModel([1056'/**',1057'indentation done for {',1058'*/'1059].join('\n'), languageId, {});1060disposables.add(model);10611062withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {1063const tokens: StandardTokenTypeData[][] = [1064[{ startIndex: 0, standardTokenType: StandardTokenType.Comment }],1065[{ startIndex: 0, standardTokenType: StandardTokenType.Comment }],1066[{ startIndex: 0, standardTokenType: StandardTokenType.Comment }]1067];1068disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));1069editor.setSelection(new Selection(2, 23, 2, 23));1070viewModel.type('\n', 'keyboard');1071assert.strictEqual(model.getValue(), [1072'/**',1073'indentation done for {',1074'',1075'*/'1076].join('\n'));1077});1078});10791080test('issue #209802: allman style braces in JavaScript', () => {10811082// https://github.com/microsoft/vscode/issues/20980210831084const model = createTextModel([1085'if (/*condition*/)',1086].join('\n'), languageId, {});1087disposables.add(model);10881089withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1090editor.setSelection(new Selection(1, 19, 1, 19));1091viewModel.type('\n', 'keyboard');1092assert.strictEqual(model.getValue(), [1093'if (/*condition*/)',1094' '1095].join('\n'));1096viewModel.type('{', 'keyboard');1097assert.strictEqual(model.getValue(), [1098'if (/*condition*/)',1099'{}'1100].join('\n'));1101editor.setSelection(new Selection(2, 2, 2, 2));1102viewModel.type('\n', 'keyboard');1103assert.strictEqual(model.getValue(), [1104'if (/*condition*/)',1105'{',1106' ',1107'}'1108].join('\n'));1109});1110});11111112// Failing tests...11131114test.skip('issue #43244: indent after equal sign is detected', () => {11151116// https://github.com/microsoft/vscode/issues/432441117// issue: Should indent after an equal sign is detected followed by whitespace characters.1118// This should be outdented when a semi-colon is detected indicating the end of the assignment.11191120// TODO: requires exploring indent/outdent pairs instead11211122const model = createTextModel([1123'const array ='1124].join('\n'), languageId, {});1125disposables.add(model);11261127withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1128editor.setSelection(new Selection(1, 14, 1, 14));1129viewModel.type('\n', 'keyboard');1130assert.strictEqual(model.getValue(), [1131'const array =',1132' '1133].join('\n'));1134});1135});11361137test.skip('issue #43244: indent after dot detected after object/array signifying a method call', () => {11381139// https://github.com/microsoft/vscode/issues/432441140// issue: When a dot is written, we should detect that this is a method call and indent accordingly11411142// TODO: requires exploring indent/outdent pairs instead11431144const model = createTextModel([1145'const array = [1, 2, 3];',1146'array.'1147].join('\n'), languageId, {});1148disposables.add(model);11491150withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1151editor.setSelection(new Selection(2, 7, 2, 7));1152viewModel.type('\n', 'keyboard');1153assert.strictEqual(model.getValue(), [1154'const array = [1, 2, 3];',1155'array.',1156' '1157].join('\n'));1158});1159});11601161test.skip('issue #43244: indent after dot detected on a subsequent line after object/array signifying a method call', () => {11621163// https://github.com/microsoft/vscode/issues/432441164// issue: When a dot is written, we should detect that this is a method call and indent accordingly11651166// TODO: requires exploring indent/outdent pairs instead11671168const model = createTextModel([1169'const array = [1, 2, 3]',1170].join('\n'), languageId, {});1171disposables.add(model);11721173withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1174editor.setSelection(new Selection(2, 7, 2, 7));1175viewModel.type('\n', 'keyboard');1176viewModel.type('.');1177assert.strictEqual(model.getValue(), [1178'const array = [1, 2, 3]',1179' .'1180].join('\n'));1181});1182});11831184test.skip('issue #43244: keep indentation when methods called on object/array', () => {11851186// https://github.com/microsoft/vscode/issues/432441187// Currently passes, but should pass with all the tests above too11881189// TODO: requires exploring indent/outdent pairs instead11901191const model = createTextModel([1192'const array = [1, 2, 3]',1193' .filter(() => true)'1194].join('\n'), languageId, {});1195disposables.add(model);11961197withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1198editor.setSelection(new Selection(2, 24, 2, 24));1199viewModel.type('\n', 'keyboard');1200assert.strictEqual(model.getValue(), [1201'const array = [1, 2, 3]',1202' .filter(() => true)',1203' '1204].join('\n'));1205});1206});12071208test.skip('issue #43244: keep indentation when chained methods called on object/array', () => {12091210// https://github.com/microsoft/vscode/issues/432441211// When the call chain is not finished yet, and we type a dot, we do not want to change the indentation12121213// TODO: requires exploring indent/outdent pairs instead12141215const model = createTextModel([1216'const array = [1, 2, 3]',1217' .filter(() => true)',1218' '1219].join('\n'), languageId, {});1220disposables.add(model);12211222withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1223editor.setSelection(new Selection(3, 5, 3, 5));1224viewModel.type('.');1225assert.strictEqual(model.getValue(), [1226'const array = [1, 2, 3]',1227' .filter(() => true)',1228' .' // here we don't want to increase the indentation because we have chained methods1229].join('\n'));1230});1231});12321233test.skip('issue #43244: outdent when a semi-color is detected indicating the end of the assignment', () => {12341235// https://github.com/microsoft/vscode/issues/4324412361237// TODO: requires exploring indent/outdent pairs instead12381239const model = createTextModel([1240'const array = [1, 2, 3]',1241' .filter(() => true);'1242].join('\n'), languageId, {});1243disposables.add(model);12441245withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1246editor.setSelection(new Selection(2, 25, 2, 25));1247viewModel.type('\n', 'keyboard');1248assert.strictEqual(model.getValue(), [1249'const array = [1, 2, 3]',1250' .filter(() => true);',1251''1252].join('\n'));1253});1254});125512561257test.skip('issue #40115: keep indentation when added', () => {12581259// https://github.com/microsoft/vscode/issues/4011512601261const model = createTextModel('function foo() {}', languageId, {});1262disposables.add(model);12631264withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1265editor.setSelection(new Selection(1, 17, 1, 17));1266viewModel.type('\n', 'keyboard');1267assert.strictEqual(model.getValue(), [1268'function foo() {',1269' ',1270'}',1271].join('\n'));1272editor.setSelection(new Selection(2, 5, 2, 5));1273viewModel.type('\n', 'keyboard');1274assert.strictEqual(model.getValue(), [1275'function foo() {',1276' ',1277' ',1278'}',1279].join('\n'));1280});1281});12821283test.skip('issue #193875: incorrect indentation on enter', () => {12841285// https://github.com/microsoft/vscode/issues/19387512861287const model = createTextModel([1288'{',1289' for(;;)',1290' for(;;) {}',1291'}',1292].join('\n'), languageId, {});1293disposables.add(model);12941295withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1296editor.setSelection(new Selection(3, 14, 3, 14));1297viewModel.type('\n', 'keyboard');1298assert.strictEqual(model.getValue(), [1299'{',1300' for(;;)',1301' for(;;) {',1302' ',1303' }',1304'}',1305].join('\n'));1306});1307});13081309test.skip('issue #67678: indent on typing curly brace', () => {13101311// https://github.com/microsoft/vscode/issues/6767813121313const model = createTextModel([1314'if (true) {',1315'console.log("a")',1316'console.log("b")',1317'',1318].join('\n'), languageId, {});1319disposables.add(model);13201321withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1322editor.setSelection(new Selection(4, 1, 4, 1));1323viewModel.type('}', 'keyboard');1324assert.strictEqual(model.getValue(), [1325'if (true) {',1326' console.log("a")',1327' console.log("b")',1328'}',1329].join('\n'));1330});1331});13321333test.skip('issue #46401: outdent when encountering bracket on line - allman style indentation', () => {13341335// https://github.com/microsoft/vscode/issues/4640113361337const model = createTextModel([1338'if (true)',1339' ',1340].join('\n'), languageId, {});1341disposables.add(model);13421343withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1344editor.setSelection(new Selection(2, 5, 2, 5));1345viewModel.type('{}', 'keyboard');1346assert.strictEqual(model.getValue(), [1347'if (true)',1348'{}',1349].join('\n'));1350editor.setSelection(new Selection(2, 2, 2, 2));1351viewModel.type('\n', 'keyboard');1352assert.strictEqual(model.getValue(), [1353'if (true)',1354'{',1355' ',1356'}'1357].join('\n'));1358});1359});13601361test.skip('issue #125261: typing closing brace does not keep the current indentation', () => {13621363// https://github.com/microsoft/vscode/issues/12526113641365const model = createTextModel([1366'foo {',1367' ',1368].join('\n'), languageId, {});1369disposables.add(model);13701371withTestCodeEditor(model, { autoIndent: 'keep', serviceCollection }, (editor, viewModel) => {1372editor.setSelection(new Selection(2, 5, 2, 5));1373viewModel.type('}', 'keyboard');1374assert.strictEqual(model.getValue(), [1375'foo {',1376'}',1377].join('\n'));1378});1379});1380});13811382suite('Auto Indent On Type - Ruby', () => {13831384const languageId = Language.Ruby;1385let disposables: DisposableStore;1386let serviceCollection: ServiceCollection;13871388setup(() => {1389disposables = new DisposableStore();1390const languageService = new LanguageService();1391const languageConfigurationService = new TestLanguageConfigurationService();1392disposables.add(languageService);1393disposables.add(languageConfigurationService);1394disposables.add(registerLanguage(languageService, languageId));1395disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1396serviceCollection = new ServiceCollection(1397[ILanguageService, languageService],1398[ILanguageConfigurationService, languageConfigurationService]1399);1400});14011402teardown(() => {1403disposables.dispose();1404});14051406ensureNoDisposablesAreLeakedInTestSuite();14071408test('issue #198350: in or when incorrectly match non keywords for Ruby', () => {14091410// https://github.com/microsoft/vscode/issues/19835014111412const model = createTextModel('', languageId, {});1413disposables.add(model);14141415withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1416viewModel.type('def foo\n i');1417viewModel.type('n', 'keyboard');1418assert.strictEqual(model.getValue(), 'def foo\n in');1419viewModel.type(' ', 'keyboard');1420assert.strictEqual(model.getValue(), 'def foo\nin ');14211422viewModel.model.setValue('');1423viewModel.type(' # in');1424assert.strictEqual(model.getValue(), ' # in');1425viewModel.type(' ', 'keyboard');1426assert.strictEqual(model.getValue(), ' # in ');1427});1428});14291430// Failing tests...14311432test.skip('issue #199846: in or when incorrectly match non keywords for Ruby', () => {14331434// https://github.com/microsoft/vscode/issues/1998461435// explanation: happening because the # is detected probably as a comment14361437const model = createTextModel('', languageId, {});1438disposables.add(model);14391440withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1441viewModel.type(`method('#foo') do`);1442viewModel.type('\n', 'keyboard');1443assert.strictEqual(model.getValue(), [1444`method('#foo') do`,1445' '1446].join('\n'));1447});1448});1449});14501451suite('Auto Indent On Type - PHP', () => {14521453const languageId = Language.PHP;1454let disposables: DisposableStore;1455let serviceCollection: ServiceCollection;14561457setup(() => {1458disposables = new DisposableStore();1459const languageService = new LanguageService();1460const languageConfigurationService = new TestLanguageConfigurationService();1461disposables.add(languageService);1462disposables.add(languageConfigurationService);1463disposables.add(registerLanguage(languageService, languageId));1464disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1465serviceCollection = new ServiceCollection(1466[ILanguageService, languageService],1467[ILanguageConfigurationService, languageConfigurationService]1468);1469});14701471teardown(() => {1472disposables.dispose();1473});14741475ensureNoDisposablesAreLeakedInTestSuite();14761477test('issue #199050: should not indent after { detected in a string', () => {14781479// https://github.com/microsoft/vscode/issues/19905014801481const model = createTextModel(`preg_replace('{');`, languageId, {});1482disposables.add(model);14831484withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {1485const tokens: StandardTokenTypeData[][] = [1486[1487{ startIndex: 0, standardTokenType: StandardTokenType.Other },1488{ startIndex: 13, standardTokenType: StandardTokenType.String },1489{ startIndex: 16, standardTokenType: StandardTokenType.Other },1490]1491];1492disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));1493editor.setSelection(new Selection(1, 54, 1, 54));1494viewModel.type('\n', 'keyboard');1495assert.strictEqual(model.getValue(), [1496`preg_replace('{');`,1497''1498].join('\n'));1499});1500});1501});15021503suite('Auto Indent On Paste - Go', () => {15041505const languageId = Language.Go;1506let disposables: DisposableStore;1507let serviceCollection: ServiceCollection;15081509setup(() => {1510disposables = new DisposableStore();1511const languageService = new LanguageService();1512const languageConfigurationService = new TestLanguageConfigurationService();1513disposables.add(languageService);1514disposables.add(languageConfigurationService);1515disposables.add(registerLanguage(languageService, languageId));1516disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1517serviceCollection = new ServiceCollection(1518[ILanguageService, languageService],1519[ILanguageConfigurationService, languageConfigurationService]1520);1521});15221523teardown(() => {1524disposables.dispose();1525});15261527ensureNoDisposablesAreLeakedInTestSuite();15281529test('temp issue because there should be at least one passing test in a suite', () => {1530assert.ok(true);1531});15321533test.skip('issue #199050: should not indent after { detected in a string', () => {15341535// https://github.com/microsoft/vscode/issues/19905015361537const model = createTextModel([1538'var s = `',1539'quick brown',1540'fox',1541'`',1542].join('\n'), languageId, {});1543disposables.add(model);15441545withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1546editor.setSelection(new Selection(3, 1, 3, 1));1547const text = ' ';1548const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);1549viewModel.paste(text, true, undefined, 'keyboard');1550autoIndentOnPasteController.trigger(new Range(3, 1, 3, 3));1551assert.strictEqual(model.getValue(), [1552'var s = `',1553'quick brown',1554' fox',1555'`',1556].join('\n'));1557});1558});1559});15601561suite('Auto Indent On Type - CPP', () => {15621563const languageId = Language.CPP;1564let disposables: DisposableStore;1565let serviceCollection: ServiceCollection;15661567setup(() => {1568disposables = new DisposableStore();1569const languageService = new LanguageService();1570const languageConfigurationService = new TestLanguageConfigurationService();1571disposables.add(languageService);1572disposables.add(languageConfigurationService);1573disposables.add(registerLanguage(languageService, languageId));1574disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1575serviceCollection = new ServiceCollection(1576[ILanguageService, languageService],1577[ILanguageConfigurationService, languageConfigurationService]1578);1579});15801581teardown(() => {1582disposables.dispose();1583});15841585ensureNoDisposablesAreLeakedInTestSuite();15861587test('temp issue because there should be at least one passing test in a suite', () => {1588assert.ok(true);1589});15901591test.skip('issue #178334: incorrect outdent of } when signature spans multiple lines', () => {15921593// https://github.com/microsoft/vscode/issues/17833415941595const model = createTextModel([1596'int WINAPI WinMain(bool instance,',1597' int nshowcmd) {}',1598].join('\n'), languageId, {});1599disposables.add(model);16001601withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1602editor.setSelection(new Selection(2, 20, 2, 20));1603viewModel.type('\n', 'keyboard');1604assert.strictEqual(model.getValue(), [1605'int WINAPI WinMain(bool instance,',1606' int nshowcmd) {',1607' ',1608'}'1609].join('\n'));1610});1611});16121613test.skip('issue #118929: incorrect indent when // follows curly brace', () => {16141615// https://github.com/microsoft/vscode/issues/11892916161617const model = createTextModel([1618'if (true) { // jaja',1619'}',1620].join('\n'), languageId, {});1621disposables.add(model);16221623withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1624editor.setSelection(new Selection(1, 20, 1, 20));1625viewModel.type('\n', 'keyboard');1626assert.strictEqual(model.getValue(), [1627'if (true) { // jaja',1628' ',1629'}',1630].join('\n'));1631});1632});16331634test.skip('issue #111265: auto indentation set to "none" still changes the indentation', () => {16351636// https://github.com/microsoft/vscode/issues/11126516371638const model = createTextModel([1639'int func() {',1640' ',1641].join('\n'), languageId, {});1642disposables.add(model);16431644withTestCodeEditor(model, { autoIndent: 'none', serviceCollection }, (editor, viewModel) => {1645editor.setSelection(new Selection(2, 3, 2, 3));1646viewModel.type('}', 'keyboard');1647assert.strictEqual(model.getValue(), [1648'int func() {',1649' }',1650].join('\n'));1651});1652});16531654});16551656suite('Auto Indent On Type - HTML', () => {16571658const languageId = Language.HTML;1659let disposables: DisposableStore;1660let serviceCollection: ServiceCollection;16611662setup(() => {1663disposables = new DisposableStore();1664const languageService = new LanguageService();1665const languageConfigurationService = new TestLanguageConfigurationService();1666disposables.add(languageService);1667disposables.add(languageConfigurationService);1668disposables.add(registerLanguage(languageService, languageId));1669disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1670serviceCollection = new ServiceCollection(1671[ILanguageService, languageService],1672[ILanguageConfigurationService, languageConfigurationService]1673);1674});16751676teardown(() => {1677disposables.dispose();1678});16791680ensureNoDisposablesAreLeakedInTestSuite();16811682test('temp issue because there should be at least one passing test in a suite', () => {1683assert.ok(true);1684});16851686test.skip('issue #61510: incorrect indentation after // in html file', () => {16871688// https://github.com/microsoft/vscode/issues/17833416891690const model = createTextModel([1691'<pre>',1692' foo //I press <Enter> at the end of this line',1693'</pre>',1694].join('\n'), languageId, {});1695disposables.add(model);16961697withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1698editor.setSelection(new Selection(2, 48, 2, 48));1699viewModel.type('\n', 'keyboard');1700assert.strictEqual(model.getValue(), [1701'<pre>',1702' foo //I press <Enter> at the end of this line',1703' ',1704'</pre>',1705].join('\n'));1706});1707});1708});17091710suite('Auto Indent On Type - Visual Basic', () => {17111712const languageId = Language.VB;1713let disposables: DisposableStore;1714let serviceCollection: ServiceCollection;17151716setup(() => {1717disposables = new DisposableStore();1718const languageService = new LanguageService();1719const languageConfigurationService = new TestLanguageConfigurationService();1720disposables.add(languageService);1721disposables.add(languageConfigurationService);1722disposables.add(registerLanguage(languageService, languageId));1723disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1724serviceCollection = new ServiceCollection(1725[ILanguageService, languageService],1726[ILanguageConfigurationService, languageConfigurationService]1727);1728});17291730teardown(() => {1731disposables.dispose();1732});17331734ensureNoDisposablesAreLeakedInTestSuite();17351736test('temp issue because there should be at least one passing test in a suite', () => {1737assert.ok(true);1738});17391740test('issue #118932: no indentation in visual basic files', () => {17411742// https://github.com/microsoft/vscode/issues/11893217431744const model = createTextModel([1745'If True Then',1746' Some code',1747' End I',1748].join('\n'), languageId, {});1749disposables.add(model);17501751withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {1752editor.setSelection(new Selection(3, 10, 3, 10));1753viewModel.type('f', 'keyboard');1754assert.strictEqual(model.getValue(), [1755'If True Then',1756' Some code',1757'End If',1758].join('\n'));1759});1760});1761});176217631764suite('Auto Indent On Type - Latex', () => {17651766const languageId = Language.Latex;1767let disposables: DisposableStore;1768let serviceCollection: ServiceCollection;17691770setup(() => {1771disposables = new DisposableStore();1772const languageService = new LanguageService();1773const languageConfigurationService = new TestLanguageConfigurationService();1774disposables.add(languageService);1775disposables.add(languageConfigurationService);1776disposables.add(registerLanguage(languageService, languageId));1777disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1778serviceCollection = new ServiceCollection(1779[ILanguageService, languageService],1780[ILanguageConfigurationService, languageConfigurationService]1781);1782});17831784teardown(() => {1785disposables.dispose();1786});17871788ensureNoDisposablesAreLeakedInTestSuite();17891790test('temp issue because there should be at least one passing test in a suite', () => {1791assert.ok(true);1792});17931794test.skip('issue #178075: no auto closing pair when indentation done', () => {17951796// https://github.com/microsoft/vscode/issues/17807517971798const model = createTextModel([1799'\\begin{theorem}',1800' \\end',1801].join('\n'), languageId, {});1802disposables.add(model);18031804withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1805editor.setSelection(new Selection(2, 9, 2, 9));1806viewModel.type('{', 'keyboard');1807assert.strictEqual(model.getValue(), [1808'\\begin{theorem}',1809'\\end{}',1810].join('\n'));1811});1812});1813});18141815suite('Auto Indent On Type - Lua', () => {18161817const languageId = Language.Lua;1818let disposables: DisposableStore;1819let serviceCollection: ServiceCollection;18201821setup(() => {1822disposables = new DisposableStore();1823const languageService = new LanguageService();1824const languageConfigurationService = new TestLanguageConfigurationService();1825disposables.add(languageService);1826disposables.add(languageConfigurationService);1827disposables.add(registerLanguage(languageService, languageId));1828disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));1829serviceCollection = new ServiceCollection(1830[ILanguageService, languageService],1831[ILanguageConfigurationService, languageConfigurationService]1832);1833});18341835teardown(() => {1836disposables.dispose();1837});18381839ensureNoDisposablesAreLeakedInTestSuite();18401841test('temp issue because there should be at least one passing test in a suite', () => {1842assert.ok(true);1843});18441845test.skip('issue #178075: no auto closing pair when indentation done', () => {18461847// https://github.com/microsoft/vscode/issues/17807518481849const model = createTextModel([1850'print("asdf function asdf")',1851].join('\n'), languageId, {});1852disposables.add(model);18531854withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {1855editor.setSelection(new Selection(1, 28, 1, 28));1856viewModel.type('\n', 'keyboard');1857assert.strictEqual(model.getValue(), [1858'print("asdf function asdf")',1859''1860].join('\n'));1861});1862});1863});186418651866