Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/indentation/test/browser/indentation.test.ts
5311 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { DisposableStore, IDisposable } from '../../../../../base/common/lifecycle.js';
8
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
9
import { ILanguageConfigurationService } from '../../../../common/languages/languageConfigurationRegistry.js';
10
import { createTextModel } from '../../../../test/common/testTextModel.js';
11
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
12
import { Range } from '../../../../common/core/range.js';
13
import { Selection } from '../../../../common/core/selection.js';
14
import { MetadataConsts, StandardTokenType } from '../../../../common/encodedTokenAttributes.js';
15
import { EncodedTokenizationResult, IState, ITokenizationSupport, TokenizationRegistry } from '../../../../common/languages.js';
16
import { ILanguageService } from '../../../../common/languages/language.js';
17
import { NullState } from '../../../../common/languages/nullTokenize.js';
18
import { AutoIndentOnPaste, IndentationToSpacesCommand, IndentationToTabsCommand } from '../../browser/indentation.js';
19
import { withTestCodeEditor } from '../../../../test/browser/testCodeEditor.js';
20
import { testCommand } from '../../../../test/browser/testCommand.js';
21
import { goIndentationRules, htmlIndentationRules, javascriptIndentationRules, latexIndentationRules, luaIndentationRules, phpIndentationRules, rubyIndentationRules, vbIndentationRules } from '../../../../test/common/modes/supports/indentationRules.js';
22
import { cppOnEnterRules, htmlOnEnterRules, javascriptOnEnterRules, phpOnEnterRules, vbOnEnterRules } from '../../../../test/common/modes/supports/onEnterRules.js';
23
import { TypeOperations } from '../../../../common/cursor/cursorTypeOperations.js';
24
import { cppBracketRules, goBracketRules, htmlBracketRules, latexBracketRules, luaBracketRules, phpBracketRules, rubyBracketRules, typescriptBracketRules, vbBracketRules } from '../../../../test/common/modes/supports/bracketRules.js';
25
import { javascriptAutoClosingPairsRules, latexAutoClosingPairsRules } from '../../../../test/common/modes/supports/autoClosingPairsRules.js';
26
import { LanguageService } from '../../../../common/services/languageService.js';
27
import { ServiceCollection } from '../../../../../platform/instantiation/common/serviceCollection.js';
28
import { TestLanguageConfigurationService } from '../../../../test/common/modes/testLanguageConfigurationService.js';
29
30
export enum Language {
31
TypeScript = 'ts-test',
32
Ruby = 'ruby-test',
33
PHP = 'php-test',
34
Go = 'go-test',
35
CPP = 'cpp-test',
36
HTML = 'html-test',
37
VB = 'vb-test',
38
Latex = 'latex-test',
39
Lua = 'lua-test'
40
}
41
42
function testIndentationToSpacesCommand(lines: string[], selection: Selection, tabSize: number, expectedLines: string[], expectedSelection: Selection): void {
43
testCommand(lines, null, selection, (accessor, sel) => new IndentationToSpacesCommand(sel, tabSize), expectedLines, expectedSelection);
44
}
45
46
function testIndentationToTabsCommand(lines: string[], selection: Selection, tabSize: number, expectedLines: string[], expectedSelection: Selection): void {
47
testCommand(lines, null, selection, (accessor, sel) => new IndentationToTabsCommand(sel, tabSize), expectedLines, expectedSelection);
48
}
49
50
export function registerLanguage(languageService: ILanguageService, language: Language): IDisposable {
51
return languageService.registerLanguage({ id: language });
52
}
53
54
export function registerLanguageConfiguration(languageConfigurationService: ILanguageConfigurationService, language: Language): IDisposable {
55
switch (language) {
56
case Language.TypeScript:
57
return languageConfigurationService.register(language, {
58
brackets: typescriptBracketRules,
59
comments: {
60
lineComment: '//',
61
blockComment: ['/*', '*/']
62
},
63
autoClosingPairs: javascriptAutoClosingPairsRules,
64
indentationRules: javascriptIndentationRules,
65
onEnterRules: javascriptOnEnterRules
66
});
67
case Language.Ruby:
68
return languageConfigurationService.register(language, {
69
brackets: rubyBracketRules,
70
indentationRules: rubyIndentationRules,
71
});
72
case Language.PHP:
73
return languageConfigurationService.register(language, {
74
brackets: phpBracketRules,
75
indentationRules: phpIndentationRules,
76
onEnterRules: phpOnEnterRules
77
});
78
case Language.Go:
79
return languageConfigurationService.register(language, {
80
brackets: goBracketRules,
81
indentationRules: goIndentationRules
82
});
83
case Language.CPP:
84
return languageConfigurationService.register(language, {
85
brackets: cppBracketRules,
86
onEnterRules: cppOnEnterRules
87
});
88
case Language.HTML:
89
return languageConfigurationService.register(language, {
90
brackets: htmlBracketRules,
91
indentationRules: htmlIndentationRules,
92
onEnterRules: htmlOnEnterRules
93
});
94
case Language.VB:
95
return languageConfigurationService.register(language, {
96
brackets: vbBracketRules,
97
indentationRules: vbIndentationRules,
98
onEnterRules: vbOnEnterRules,
99
});
100
case Language.Latex:
101
return languageConfigurationService.register(language, {
102
brackets: latexBracketRules,
103
autoClosingPairs: latexAutoClosingPairsRules,
104
indentationRules: latexIndentationRules
105
});
106
case Language.Lua:
107
return languageConfigurationService.register(language, {
108
brackets: luaBracketRules,
109
indentationRules: luaIndentationRules
110
});
111
}
112
}
113
114
export interface StandardTokenTypeData {
115
startIndex: number;
116
standardTokenType: StandardTokenType;
117
}
118
119
export function registerTokenizationSupport(instantiationService: TestInstantiationService, tokens: StandardTokenTypeData[][], languageId: Language): IDisposable {
120
let lineIndex = 0;
121
const languageService = instantiationService.get(ILanguageService);
122
const tokenizationSupport: ITokenizationSupport = {
123
getInitialState: () => NullState,
124
tokenize: undefined!,
125
tokenizeEncoded: (line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult => {
126
const tokensOnLine = tokens[lineIndex++];
127
const encodedLanguageId = languageService.languageIdCodec.encodeLanguageId(languageId);
128
const result = new Uint32Array(2 * tokensOnLine.length);
129
for (let i = 0; i < tokensOnLine.length; i++) {
130
result[2 * i] = tokensOnLine[i].startIndex;
131
result[2 * i + 1] =
132
(
133
(encodedLanguageId << MetadataConsts.LANGUAGEID_OFFSET)
134
| (tokensOnLine[i].standardTokenType << MetadataConsts.TOKEN_TYPE_OFFSET)
135
);
136
}
137
return new EncodedTokenizationResult(result, [], state);
138
}
139
};
140
return TokenizationRegistry.register(languageId, tokenizationSupport);
141
}
142
143
suite('Change Indentation to Spaces - TypeScript/Javascript', () => {
144
145
ensureNoDisposablesAreLeakedInTestSuite();
146
147
test('single tabs only at start of line', function () {
148
testIndentationToSpacesCommand(
149
[
150
'first',
151
'second line',
152
'third line',
153
'\tfourth line',
154
'\tfifth'
155
],
156
new Selection(2, 3, 2, 3),
157
4,
158
[
159
'first',
160
'second line',
161
'third line',
162
' fourth line',
163
' fifth'
164
],
165
new Selection(2, 3, 2, 3)
166
);
167
});
168
169
test('multiple tabs at start of line', function () {
170
testIndentationToSpacesCommand(
171
[
172
'\t\tfirst',
173
'\tsecond line',
174
'\t\t\t third line',
175
'fourth line',
176
'fifth'
177
],
178
new Selection(1, 5, 1, 5),
179
3,
180
[
181
' first',
182
' second line',
183
' third line',
184
'fourth line',
185
'fifth'
186
],
187
new Selection(1, 9, 1, 9)
188
);
189
});
190
191
test('multiple tabs', function () {
192
testIndentationToSpacesCommand(
193
[
194
'\t\tfirst\t',
195
'\tsecond \t line \t',
196
'\t\t\t third line',
197
' \tfourth line',
198
'fifth'
199
],
200
new Selection(1, 5, 1, 5),
201
2,
202
[
203
' first\t',
204
' second \t line \t',
205
' third line',
206
' fourth line',
207
'fifth'
208
],
209
new Selection(1, 7, 1, 7)
210
);
211
});
212
213
test('empty lines', function () {
214
testIndentationToSpacesCommand(
215
[
216
'\t\t\t',
217
'\t',
218
'\t\t'
219
],
220
new Selection(1, 4, 1, 4),
221
2,
222
[
223
' ',
224
' ',
225
' '
226
],
227
new Selection(1, 4, 1, 4)
228
);
229
});
230
});
231
232
suite('Change Indentation to Tabs - TypeScript/Javascript', () => {
233
234
ensureNoDisposablesAreLeakedInTestSuite();
235
236
test('spaces only at start of line', function () {
237
testIndentationToTabsCommand(
238
[
239
' first',
240
'second line',
241
' third line',
242
'fourth line',
243
'fifth'
244
],
245
new Selection(2, 3, 2, 3),
246
4,
247
[
248
'\tfirst',
249
'second line',
250
'\tthird line',
251
'fourth line',
252
'fifth'
253
],
254
new Selection(2, 3, 2, 3)
255
);
256
});
257
258
test('multiple spaces at start of line', function () {
259
testIndentationToTabsCommand(
260
[
261
'first',
262
' second line',
263
' third line',
264
'fourth line',
265
' fifth'
266
],
267
new Selection(1, 5, 1, 5),
268
3,
269
[
270
'first',
271
'\tsecond line',
272
'\t\t\t third line',
273
'fourth line',
274
'\t fifth'
275
],
276
new Selection(1, 5, 1, 5)
277
);
278
});
279
280
test('multiple spaces', function () {
281
testIndentationToTabsCommand(
282
[
283
' first ',
284
' second line \t',
285
' third line',
286
' fourth line',
287
'fifth'
288
],
289
new Selection(1, 8, 1, 8),
290
2,
291
[
292
'\t\t\tfirst ',
293
'\tsecond line \t',
294
'\t\t\t third line',
295
'\t fourth line',
296
'fifth'
297
],
298
new Selection(1, 5, 1, 5)
299
);
300
});
301
302
test('issue #45996', function () {
303
testIndentationToSpacesCommand(
304
[
305
'\tabc',
306
],
307
new Selection(1, 3, 1, 3),
308
4,
309
[
310
' abc',
311
],
312
new Selection(1, 6, 1, 6)
313
);
314
});
315
});
316
317
suite('Indent With Tab - TypeScript/JavaScript', () => {
318
319
const languageId = Language.TypeScript;
320
let disposables: DisposableStore;
321
let serviceCollection: ServiceCollection;
322
323
setup(() => {
324
disposables = new DisposableStore();
325
const languageService = new LanguageService();
326
const languageConfigurationService = new TestLanguageConfigurationService();
327
disposables.add(languageService);
328
disposables.add(languageConfigurationService);
329
disposables.add(registerLanguage(languageService, languageId));
330
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
331
serviceCollection = new ServiceCollection(
332
[ILanguageService, languageService],
333
[ILanguageConfigurationService, languageConfigurationService]
334
);
335
});
336
337
teardown(() => {
338
disposables.dispose();
339
});
340
341
ensureNoDisposablesAreLeakedInTestSuite();
342
343
test('temp issue because there should be at least one passing test in a suite', () => {
344
assert.ok(true);
345
});
346
347
test.skip('issue #63388: perserve correct indentation on tab 1', () => {
348
349
// https://github.com/microsoft/vscode/issues/63388
350
351
const model = createTextModel([
352
'/*',
353
' * Comment',
354
' * /',
355
].join('\n'), languageId, {});
356
disposables.add(model);
357
358
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
359
editor.setSelection(new Selection(1, 1, 3, 5));
360
editor.executeCommands('editor.action.indentLines', TypeOperations.indent(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));
361
assert.strictEqual(model.getValue(), [
362
' /*',
363
' * Comment',
364
' * /',
365
].join('\n'));
366
});
367
});
368
369
test.skip('issue #63388: perserve correct indentation on tab 2', () => {
370
371
// https://github.com/microsoft/vscode/issues/63388
372
373
const model = createTextModel([
374
'switch (something) {',
375
' case 1:',
376
' whatever();',
377
' break;',
378
'}',
379
].join('\n'), languageId, {});
380
disposables.add(model);
381
382
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
383
editor.setSelection(new Selection(1, 1, 5, 2));
384
editor.executeCommands('editor.action.indentLines', TypeOperations.indent(viewModel.cursorConfig, editor.getModel(), editor.getSelections()));
385
assert.strictEqual(model.getValue(), [
386
' switch (something) {',
387
' case 1:',
388
' whatever();',
389
' break;',
390
' }',
391
].join('\n'));
392
});
393
});
394
});
395
396
suite('Auto Indent On Paste - TypeScript/JavaScript', () => {
397
398
const languageId = Language.TypeScript;
399
let disposables: DisposableStore;
400
let serviceCollection: ServiceCollection;
401
402
setup(() => {
403
disposables = new DisposableStore();
404
const languageService = new LanguageService();
405
const languageConfigurationService = new TestLanguageConfigurationService();
406
disposables.add(languageService);
407
disposables.add(languageConfigurationService);
408
disposables.add(registerLanguage(languageService, languageId));
409
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
410
serviceCollection = new ServiceCollection(
411
[ILanguageService, languageService],
412
[ILanguageConfigurationService, languageConfigurationService]
413
);
414
});
415
416
teardown(() => {
417
disposables.dispose();
418
});
419
420
ensureNoDisposablesAreLeakedInTestSuite();
421
422
test('issue #119225: Do not add extra leading space when pasting JSDoc', () => {
423
424
const model = createTextModel('', languageId, {});
425
disposables.add(model);
426
427
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
428
const pasteText = [
429
'/**',
430
' * JSDoc',
431
' */',
432
'function a() {}'
433
].join('\n');
434
const tokens: StandardTokenTypeData[][] = [
435
[
436
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
437
{ startIndex: 3, standardTokenType: StandardTokenType.Comment },
438
],
439
[
440
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
441
{ startIndex: 2, standardTokenType: StandardTokenType.Comment },
442
{ startIndex: 8, standardTokenType: StandardTokenType.Comment },
443
],
444
[
445
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
446
{ startIndex: 1, standardTokenType: StandardTokenType.Comment },
447
{ startIndex: 3, standardTokenType: StandardTokenType.Other },
448
],
449
[
450
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
451
{ startIndex: 8, standardTokenType: StandardTokenType.Other },
452
{ startIndex: 9, standardTokenType: StandardTokenType.Other },
453
{ startIndex: 10, standardTokenType: StandardTokenType.Other },
454
{ startIndex: 11, standardTokenType: StandardTokenType.Other },
455
{ startIndex: 12, standardTokenType: StandardTokenType.Other },
456
{ startIndex: 13, standardTokenType: StandardTokenType.Other },
457
{ startIndex: 14, standardTokenType: StandardTokenType.Other },
458
{ startIndex: 15, standardTokenType: StandardTokenType.Other },
459
]
460
];
461
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
462
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
463
viewModel.paste(pasteText, true, undefined, 'keyboard');
464
autoIndentOnPasteController.trigger(new Range(1, 1, 4, 16));
465
assert.strictEqual(model.getValue(), pasteText);
466
});
467
});
468
469
test('issue #167299: Blank line removes indent', () => {
470
471
const model = createTextModel('', languageId, {});
472
disposables.add(model);
473
474
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
475
476
// no need for tokenization because there are no comments
477
const pasteText = [
478
'',
479
'export type IncludeReference =',
480
' | BaseReference',
481
' | SelfReference',
482
' | RelativeReference;',
483
'',
484
'export const enum IncludeReferenceKind {',
485
' Base,',
486
' Self,',
487
' RelativeReference,',
488
'}'
489
].join('\n');
490
491
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
492
viewModel.paste(pasteText, true, undefined, 'keyboard');
493
autoIndentOnPasteController.trigger(new Range(1, 1, 11, 2));
494
assert.strictEqual(model.getValue(), pasteText);
495
});
496
});
497
498
test('issue #29803: do not indent when pasting text with only one line', () => {
499
500
// https://github.com/microsoft/vscode/issues/29803
501
502
const model = createTextModel([
503
'const linkHandler = new Class(a, b, c,',
504
' d)'
505
].join('\n'), languageId, {});
506
disposables.add(model);
507
508
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
509
editor.setSelection(new Selection(2, 6, 2, 6));
510
const text = ', null';
511
viewModel.paste(text, true, undefined, 'keyboard');
512
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
513
autoIndentOnPasteController.trigger(new Range(2, 6, 2, 11));
514
assert.strictEqual(model.getValue(), [
515
'const linkHandler = new Class(a, b, c,',
516
' d, null)'
517
].join('\n'));
518
});
519
});
520
521
test('issue #29753: incorrect indentation after comment', () => {
522
523
// https://github.com/microsoft/vscode/issues/29753
524
525
const model = createTextModel([
526
'class A {',
527
' /**',
528
' * used only for debug purposes.',
529
' */',
530
' private _codeInfo: KeyMapping[];',
531
'}',
532
].join('\n'), languageId, {});
533
disposables.add(model);
534
535
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
536
editor.setSelection(new Selection(5, 24, 5, 34));
537
const text = 'IMacLinuxKeyMapping';
538
viewModel.paste(text, true, undefined, 'keyboard');
539
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
540
autoIndentOnPasteController.trigger(new Range(5, 24, 5, 43));
541
assert.strictEqual(model.getValue(), [
542
'class A {',
543
' /**',
544
' * used only for debug purposes.',
545
' */',
546
' private _codeInfo: IMacLinuxKeyMapping[];',
547
'}',
548
].join('\n'));
549
});
550
});
551
552
test('issue #29753: incorrect indentation of header comment', () => {
553
554
// https://github.com/microsoft/vscode/issues/29753
555
556
const model = createTextModel('', languageId, {});
557
disposables.add(model);
558
559
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
560
const text = [
561
'/*----------------',
562
' * Copyright (c) ',
563
' * Licensed under ...',
564
' *-----------------*/',
565
].join('\n');
566
viewModel.paste(text, true, undefined, 'keyboard');
567
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
568
autoIndentOnPasteController.trigger(new Range(1, 1, 4, 22));
569
assert.strictEqual(model.getValue(), text);
570
});
571
});
572
573
test('issue #209859: do not do change indentation when pasted inside of a string', () => {
574
575
// issue: https://github.com/microsoft/vscode/issues/209859
576
// issue: https://github.com/microsoft/vscode/issues/209418
577
578
const initialText = [
579
'const foo = "some text',
580
' which is strangely',
581
' indented"'
582
].join('\n');
583
const model = createTextModel(initialText, languageId, {});
584
disposables.add(model);
585
586
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
587
const tokens: StandardTokenTypeData[][] = [
588
[
589
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
590
{ startIndex: 12, standardTokenType: StandardTokenType.String },
591
],
592
[
593
{ startIndex: 0, standardTokenType: StandardTokenType.String },
594
],
595
[
596
{ startIndex: 0, standardTokenType: StandardTokenType.String },
597
]
598
];
599
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
600
601
editor.setSelection(new Selection(2, 10, 2, 15));
602
viewModel.paste('which', true, undefined, 'keyboard');
603
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
604
autoIndentOnPasteController.trigger(new Range(2, 1, 2, 28));
605
assert.strictEqual(model.getValue(), initialText);
606
});
607
});
608
609
// Failing tests found in issues...
610
611
test.skip('issue #181065: Incorrect paste of object within comment', () => {
612
613
// https://github.com/microsoft/vscode/issues/181065
614
615
const model = createTextModel('', languageId, {});
616
disposables.add(model);
617
618
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
619
const text = [
620
'/**',
621
' * @typedef {',
622
' * }',
623
' */'
624
].join('\n');
625
const tokens: StandardTokenTypeData[][] = [
626
[
627
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
628
{ startIndex: 3, standardTokenType: StandardTokenType.Comment },
629
],
630
[
631
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
632
{ startIndex: 2, standardTokenType: StandardTokenType.Comment },
633
{ startIndex: 3, standardTokenType: StandardTokenType.Comment },
634
{ startIndex: 11, standardTokenType: StandardTokenType.Comment },
635
{ startIndex: 12, standardTokenType: StandardTokenType.Other },
636
{ startIndex: 13, standardTokenType: StandardTokenType.Other },
637
],
638
[
639
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
640
{ startIndex: 2, standardTokenType: StandardTokenType.Other },
641
{ startIndex: 3, standardTokenType: StandardTokenType.Other },
642
{ startIndex: 4, standardTokenType: StandardTokenType.Other },
643
],
644
[
645
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
646
{ startIndex: 1, standardTokenType: StandardTokenType.Comment },
647
{ startIndex: 3, standardTokenType: StandardTokenType.Other },
648
]
649
];
650
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
651
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
652
viewModel.paste(text, true, undefined, 'keyboard');
653
autoIndentOnPasteController.trigger(new Range(1, 1, 4, 4));
654
assert.strictEqual(model.getValue(), text);
655
});
656
});
657
658
test.skip('issue #86301: preserve cursor at inserted indentation level', () => {
659
660
// https://github.com/microsoft/vscode/issues/86301
661
662
const model = createTextModel([
663
'() => {',
664
'',
665
'}',
666
].join('\n'), languageId, {});
667
disposables.add(model);
668
669
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
670
editor.setSelection(new Selection(2, 1, 2, 1));
671
const text = [
672
'() => {',
673
'',
674
'}',
675
''
676
].join('\n');
677
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
678
viewModel.paste(text, true, undefined, 'keyboard');
679
autoIndentOnPasteController.trigger(new Range(2, 1, 5, 1));
680
681
// notes:
682
// why is line 3 not indented to the same level as line 2?
683
// looks like the indentation is inserted correctly at line 5, but the cursor does not appear at the maximum indentation level?
684
assert.strictEqual(model.getValue(), [
685
'() => {',
686
' () => {',
687
' ', // <- should also be indented
688
' }',
689
' ', // <- cursor should be at the end of the indentation
690
'}',
691
].join('\n'));
692
693
const selection = viewModel.getSelection();
694
assert.deepStrictEqual(selection, new Selection(5, 5, 5, 5));
695
});
696
});
697
698
test.skip('issue #85781: indent line with extra white space', () => {
699
700
// https://github.com/microsoft/vscode/issues/85781
701
// note: still to determine whether this is a bug or not
702
703
const model = createTextModel([
704
'() => {',
705
' console.log("a");',
706
'}',
707
].join('\n'), languageId, {});
708
disposables.add(model);
709
710
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
711
editor.setSelection(new Selection(2, 5, 2, 5));
712
const text = [
713
'() => {',
714
' console.log("b")',
715
'}',
716
' '
717
].join('\n');
718
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
719
viewModel.paste(text, true, undefined, 'keyboard');
720
// todo@aiday-mar, make sure range is correct, and make test work as in real life
721
autoIndentOnPasteController.trigger(new Range(2, 5, 5, 6));
722
assert.strictEqual(model.getValue(), [
723
'() => {',
724
' () => {',
725
' console.log("b")',
726
' }',
727
' console.log("a");',
728
'}',
729
].join('\n'));
730
});
731
});
732
733
test.skip('issue #29589: incorrect indentation of closing brace on paste', () => {
734
735
// https://github.com/microsoft/vscode/issues/29589
736
737
const model = createTextModel('', languageId, {});
738
disposables.add(model);
739
740
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
741
editor.setSelection(new Selection(2, 5, 2, 5));
742
const text = [
743
'function makeSub(a,b) {',
744
'subsent = sent.substring(a,b);',
745
'return subsent;',
746
'}',
747
].join('\n');
748
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
749
viewModel.paste(text, true, undefined, 'keyboard');
750
// todo@aiday-mar, make sure range is correct, and make test work as in real life
751
autoIndentOnPasteController.trigger(new Range(1, 1, 4, 2));
752
assert.strictEqual(model.getValue(), [
753
'function makeSub(a,b) {',
754
'subsent = sent.substring(a,b);',
755
'return subsent;',
756
'}',
757
].join('\n'));
758
});
759
});
760
761
test.skip('issue #201420: incorrect indentation when first line is comment', () => {
762
763
// https://github.com/microsoft/vscode/issues/201420
764
765
const model = createTextModel([
766
'function bar() {',
767
'',
768
'}',
769
].join('\n'), languageId, {});
770
disposables.add(model);
771
772
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
773
const tokens: StandardTokenTypeData[][] = [
774
[
775
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
776
{ startIndex: 8, standardTokenType: StandardTokenType.Other },
777
{ startIndex: 9, standardTokenType: StandardTokenType.Other },
778
{ startIndex: 12, standardTokenType: StandardTokenType.Other },
779
{ startIndex: 13, standardTokenType: StandardTokenType.Other },
780
{ startIndex: 14, standardTokenType: StandardTokenType.Other },
781
{ startIndex: 15, standardTokenType: StandardTokenType.Other },
782
{ startIndex: 16, standardTokenType: StandardTokenType.Other }
783
],
784
[
785
{ startIndex: 0, standardTokenType: StandardTokenType.Comment },
786
{ startIndex: 2, standardTokenType: StandardTokenType.Comment },
787
{ startIndex: 3, standardTokenType: StandardTokenType.Comment },
788
{ startIndex: 10, standardTokenType: StandardTokenType.Comment }
789
],
790
[
791
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
792
{ startIndex: 5, standardTokenType: StandardTokenType.Other },
793
{ startIndex: 6, standardTokenType: StandardTokenType.Other },
794
{ startIndex: 9, standardTokenType: StandardTokenType.Other },
795
{ startIndex: 10, standardTokenType: StandardTokenType.Other },
796
{ startIndex: 11, standardTokenType: StandardTokenType.Other },
797
{ startIndex: 12, standardTokenType: StandardTokenType.Other },
798
{ startIndex: 14, standardTokenType: StandardTokenType.Other }],
799
[
800
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
801
{ startIndex: 1, standardTokenType: StandardTokenType.Other }]
802
];
803
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
804
805
editor.setSelection(new Selection(2, 1, 2, 1));
806
const text = [
807
'// comment',
808
'const foo = 42',
809
].join('\n');
810
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
811
viewModel.paste(text, true, undefined, 'keyboard');
812
autoIndentOnPasteController.trigger(new Range(2, 1, 3, 15));
813
assert.strictEqual(model.getValue(), [
814
'function bar() {',
815
' // comment',
816
' const foo = 42',
817
'}',
818
].join('\n'));
819
});
820
});
821
});
822
823
suite('Auto Indent On Type - TypeScript/JavaScript', () => {
824
825
const languageId = Language.TypeScript;
826
let disposables: DisposableStore;
827
let serviceCollection: ServiceCollection;
828
829
setup(() => {
830
disposables = new DisposableStore();
831
const languageService = new LanguageService();
832
const languageConfigurationService = new TestLanguageConfigurationService();
833
disposables.add(languageService);
834
disposables.add(languageConfigurationService);
835
disposables.add(registerLanguage(languageService, languageId));
836
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
837
serviceCollection = new ServiceCollection(
838
[ILanguageService, languageService],
839
[ILanguageConfigurationService, languageConfigurationService]
840
);
841
});
842
843
teardown(() => {
844
disposables.dispose();
845
});
846
847
ensureNoDisposablesAreLeakedInTestSuite();
848
849
// Failing tests from issues...
850
851
test('issue #208215: indent after arrow function', () => {
852
853
// https://github.com/microsoft/vscode/issues/208215
854
855
const model = createTextModel('', languageId, {});
856
disposables.add(model);
857
858
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
859
viewModel.type('const add1 = (n) =>');
860
viewModel.type('\n', 'keyboard');
861
assert.strictEqual(model.getValue(), [
862
'const add1 = (n) =>',
863
' ',
864
].join('\n'));
865
});
866
});
867
868
test('issue #208215: indent after arrow function 2', () => {
869
870
// https://github.com/microsoft/vscode/issues/208215
871
872
const model = createTextModel([
873
'const array = [1, 2, 3, 4, 5];',
874
'array.map(',
875
' v =>',
876
].join('\n'), languageId, {});
877
disposables.add(model);
878
879
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
880
editor.setSelection(new Selection(3, 9, 3, 9));
881
viewModel.type('\n', 'keyboard');
882
assert.strictEqual(model.getValue(), [
883
'const array = [1, 2, 3, 4, 5];',
884
'array.map(',
885
' v =>',
886
' '
887
].join('\n'));
888
});
889
});
890
891
test('issue #116843: indent after arrow function', () => {
892
893
// https://github.com/microsoft/vscode/issues/116843
894
895
const model = createTextModel('', languageId, {});
896
disposables.add(model);
897
898
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
899
viewModel.type([
900
'const add1 = (n) =>',
901
' n + 1;',
902
].join('\n'));
903
viewModel.type('\n', 'keyboard');
904
assert.strictEqual(model.getValue(), [
905
'const add1 = (n) =>',
906
' n + 1;',
907
'',
908
].join('\n'));
909
});
910
});
911
912
test('issue #29755: do not add indentation on enter if indentation is already valid', () => {
913
914
//https://github.com/microsoft/vscode/issues/29755
915
916
const model = createTextModel([
917
'function f() {',
918
' const one = 1;',
919
' const two = 2;',
920
'}',
921
].join('\n'), languageId, {});
922
disposables.add(model);
923
924
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
925
editor.setSelection(new Selection(3, 1, 3, 1));
926
viewModel.type('\n', 'keyboard');
927
assert.strictEqual(model.getValue(), [
928
'function f() {',
929
' const one = 1;',
930
'',
931
' const two = 2;',
932
'}',
933
].join('\n'));
934
});
935
});
936
937
test('issue #36090', () => {
938
939
// https://github.com/microsoft/vscode/issues/36090
940
941
const model = createTextModel([
942
'class ItemCtrl {',
943
' getPropertiesByItemId(id) {',
944
' return this.fetchItem(id)',
945
' .then(item => {',
946
' return this.getPropertiesOfItem(item);',
947
' });',
948
' }',
949
'}',
950
].join('\n'), languageId, {});
951
disposables.add(model);
952
953
withTestCodeEditor(model, { autoIndent: 'advanced', serviceCollection }, (editor, viewModel) => {
954
editor.setSelection(new Selection(7, 6, 7, 6));
955
viewModel.type('\n', 'keyboard');
956
assert.strictEqual(model.getValue(),
957
[
958
'class ItemCtrl {',
959
' getPropertiesByItemId(id) {',
960
' return this.fetchItem(id)',
961
' .then(item => {',
962
' return this.getPropertiesOfItem(item);',
963
' });',
964
' }',
965
' ',
966
'}',
967
].join('\n')
968
);
969
assert.deepStrictEqual(editor.getSelection(), new Selection(8, 5, 8, 5));
970
});
971
});
972
973
test('issue #115304: indent block comment onEnter', () => {
974
975
// https://github.com/microsoft/vscode/issues/115304
976
977
const model = createTextModel([
978
'/** */',
979
'function f() {}',
980
].join('\n'), languageId, {});
981
disposables.add(model);
982
983
withTestCodeEditor(model, { autoIndent: 'advanced', serviceCollection }, (editor, viewModel) => {
984
editor.setSelection(new Selection(1, 4, 1, 4));
985
viewModel.type('\n', 'keyboard');
986
assert.strictEqual(model.getValue(),
987
[
988
'/**',
989
' * ',
990
' */',
991
'function f() {}',
992
].join('\n')
993
);
994
assert.deepStrictEqual(editor.getSelection(), new Selection(2, 4, 2, 4));
995
});
996
});
997
998
test('issue #43244: indent when lambda arrow function is detected, outdent when end is reached', () => {
999
1000
// https://github.com/microsoft/vscode/issues/43244
1001
1002
const model = createTextModel([
1003
'const array = [1, 2, 3, 4, 5];',
1004
'array.map(_)'
1005
].join('\n'), languageId, {});
1006
disposables.add(model);
1007
1008
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1009
editor.setSelection(new Selection(2, 12, 2, 12));
1010
viewModel.type('\n', 'keyboard');
1011
assert.strictEqual(model.getValue(), [
1012
'const array = [1, 2, 3, 4, 5];',
1013
'array.map(_',
1014
' ',
1015
')'
1016
].join('\n'));
1017
});
1018
});
1019
1020
test('issue #43244: incorrect indentation after if/for/while without braces', () => {
1021
1022
// https://github.com/microsoft/vscode/issues/43244
1023
1024
const model = createTextModel([
1025
'function f() {',
1026
' if (condition)',
1027
'}'
1028
].join('\n'), languageId, {});
1029
disposables.add(model);
1030
1031
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1032
editor.setSelection(new Selection(2, 19, 2, 19));
1033
viewModel.type('\n', 'keyboard');
1034
assert.strictEqual(model.getValue(), [
1035
'function f() {',
1036
' if (condition)',
1037
' ',
1038
'}',
1039
].join('\n'));
1040
1041
viewModel.type('return;');
1042
viewModel.type('\n', 'keyboard');
1043
assert.strictEqual(model.getValue(), [
1044
'function f() {',
1045
' if (condition)',
1046
' return;',
1047
' ',
1048
'}',
1049
].join('\n'));
1050
});
1051
});
1052
1053
test('issue #208232: incorrect indentation inside of comments', () => {
1054
1055
// https://github.com/microsoft/vscode/issues/208232
1056
1057
const model = createTextModel([
1058
'/**',
1059
'indentation done for {',
1060
'*/'
1061
].join('\n'), languageId, {});
1062
disposables.add(model);
1063
1064
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
1065
const tokens: StandardTokenTypeData[][] = [
1066
[{ startIndex: 0, standardTokenType: StandardTokenType.Comment }],
1067
[{ startIndex: 0, standardTokenType: StandardTokenType.Comment }],
1068
[{ startIndex: 0, standardTokenType: StandardTokenType.Comment }]
1069
];
1070
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
1071
editor.setSelection(new Selection(2, 23, 2, 23));
1072
viewModel.type('\n', 'keyboard');
1073
assert.strictEqual(model.getValue(), [
1074
'/**',
1075
'indentation done for {',
1076
'',
1077
'*/'
1078
].join('\n'));
1079
});
1080
});
1081
1082
test('issue #209802: allman style braces in JavaScript', () => {
1083
1084
// https://github.com/microsoft/vscode/issues/209802
1085
1086
const model = createTextModel([
1087
'if (/*condition*/)',
1088
].join('\n'), languageId, {});
1089
disposables.add(model);
1090
1091
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1092
editor.setSelection(new Selection(1, 19, 1, 19));
1093
viewModel.type('\n', 'keyboard');
1094
assert.strictEqual(model.getValue(), [
1095
'if (/*condition*/)',
1096
' '
1097
].join('\n'));
1098
viewModel.type('{', 'keyboard');
1099
assert.strictEqual(model.getValue(), [
1100
'if (/*condition*/)',
1101
'{}'
1102
].join('\n'));
1103
editor.setSelection(new Selection(2, 2, 2, 2));
1104
viewModel.type('\n', 'keyboard');
1105
assert.strictEqual(model.getValue(), [
1106
'if (/*condition*/)',
1107
'{',
1108
' ',
1109
'}'
1110
].join('\n'));
1111
});
1112
});
1113
1114
// Failing tests...
1115
1116
test.skip('issue #43244: indent after equal sign is detected', () => {
1117
1118
// https://github.com/microsoft/vscode/issues/43244
1119
// issue: Should indent after an equal sign is detected followed by whitespace characters.
1120
// This should be outdented when a semi-colon is detected indicating the end of the assignment.
1121
1122
// TODO: requires exploring indent/outdent pairs instead
1123
1124
const model = createTextModel([
1125
'const array ='
1126
].join('\n'), languageId, {});
1127
disposables.add(model);
1128
1129
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1130
editor.setSelection(new Selection(1, 14, 1, 14));
1131
viewModel.type('\n', 'keyboard');
1132
assert.strictEqual(model.getValue(), [
1133
'const array =',
1134
' '
1135
].join('\n'));
1136
});
1137
});
1138
1139
test.skip('issue #43244: indent after dot detected after object/array signifying a method call', () => {
1140
1141
// https://github.com/microsoft/vscode/issues/43244
1142
// issue: When a dot is written, we should detect that this is a method call and indent accordingly
1143
1144
// TODO: requires exploring indent/outdent pairs instead
1145
1146
const model = createTextModel([
1147
'const array = [1, 2, 3];',
1148
'array.'
1149
].join('\n'), languageId, {});
1150
disposables.add(model);
1151
1152
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1153
editor.setSelection(new Selection(2, 7, 2, 7));
1154
viewModel.type('\n', 'keyboard');
1155
assert.strictEqual(model.getValue(), [
1156
'const array = [1, 2, 3];',
1157
'array.',
1158
' '
1159
].join('\n'));
1160
});
1161
});
1162
1163
test.skip('issue #43244: indent after dot detected on a subsequent line after object/array signifying a method call', () => {
1164
1165
// https://github.com/microsoft/vscode/issues/43244
1166
// issue: When a dot is written, we should detect that this is a method call and indent accordingly
1167
1168
// TODO: requires exploring indent/outdent pairs instead
1169
1170
const model = createTextModel([
1171
'const array = [1, 2, 3]',
1172
].join('\n'), languageId, {});
1173
disposables.add(model);
1174
1175
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1176
editor.setSelection(new Selection(2, 7, 2, 7));
1177
viewModel.type('\n', 'keyboard');
1178
viewModel.type('.');
1179
assert.strictEqual(model.getValue(), [
1180
'const array = [1, 2, 3]',
1181
' .'
1182
].join('\n'));
1183
});
1184
});
1185
1186
test.skip('issue #43244: keep indentation when methods called on object/array', () => {
1187
1188
// https://github.com/microsoft/vscode/issues/43244
1189
// Currently passes, but should pass with all the tests above too
1190
1191
// TODO: requires exploring indent/outdent pairs instead
1192
1193
const model = createTextModel([
1194
'const array = [1, 2, 3]',
1195
' .filter(() => true)'
1196
].join('\n'), languageId, {});
1197
disposables.add(model);
1198
1199
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1200
editor.setSelection(new Selection(2, 24, 2, 24));
1201
viewModel.type('\n', 'keyboard');
1202
assert.strictEqual(model.getValue(), [
1203
'const array = [1, 2, 3]',
1204
' .filter(() => true)',
1205
' '
1206
].join('\n'));
1207
});
1208
});
1209
1210
test.skip('issue #43244: keep indentation when chained methods called on object/array', () => {
1211
1212
// https://github.com/microsoft/vscode/issues/43244
1213
// When the call chain is not finished yet, and we type a dot, we do not want to change the indentation
1214
1215
// TODO: requires exploring indent/outdent pairs instead
1216
1217
const model = createTextModel([
1218
'const array = [1, 2, 3]',
1219
' .filter(() => true)',
1220
' '
1221
].join('\n'), languageId, {});
1222
disposables.add(model);
1223
1224
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1225
editor.setSelection(new Selection(3, 5, 3, 5));
1226
viewModel.type('.');
1227
assert.strictEqual(model.getValue(), [
1228
'const array = [1, 2, 3]',
1229
' .filter(() => true)',
1230
' .' // here we don't want to increase the indentation because we have chained methods
1231
].join('\n'));
1232
});
1233
});
1234
1235
test.skip('issue #43244: outdent when a semi-color is detected indicating the end of the assignment', () => {
1236
1237
// https://github.com/microsoft/vscode/issues/43244
1238
1239
// TODO: requires exploring indent/outdent pairs instead
1240
1241
const model = createTextModel([
1242
'const array = [1, 2, 3]',
1243
' .filter(() => true);'
1244
].join('\n'), languageId, {});
1245
disposables.add(model);
1246
1247
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1248
editor.setSelection(new Selection(2, 25, 2, 25));
1249
viewModel.type('\n', 'keyboard');
1250
assert.strictEqual(model.getValue(), [
1251
'const array = [1, 2, 3]',
1252
' .filter(() => true);',
1253
''
1254
].join('\n'));
1255
});
1256
});
1257
1258
1259
test.skip('issue #40115: keep indentation when added', () => {
1260
1261
// https://github.com/microsoft/vscode/issues/40115
1262
1263
const model = createTextModel('function foo() {}', languageId, {});
1264
disposables.add(model);
1265
1266
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1267
editor.setSelection(new Selection(1, 17, 1, 17));
1268
viewModel.type('\n', 'keyboard');
1269
assert.strictEqual(model.getValue(), [
1270
'function foo() {',
1271
' ',
1272
'}',
1273
].join('\n'));
1274
editor.setSelection(new Selection(2, 5, 2, 5));
1275
viewModel.type('\n', 'keyboard');
1276
assert.strictEqual(model.getValue(), [
1277
'function foo() {',
1278
' ',
1279
' ',
1280
'}',
1281
].join('\n'));
1282
});
1283
});
1284
1285
test.skip('issue #193875: incorrect indentation on enter', () => {
1286
1287
// https://github.com/microsoft/vscode/issues/193875
1288
1289
const model = createTextModel([
1290
'{',
1291
' for(;;)',
1292
' for(;;) {}',
1293
'}',
1294
].join('\n'), languageId, {});
1295
disposables.add(model);
1296
1297
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1298
editor.setSelection(new Selection(3, 14, 3, 14));
1299
viewModel.type('\n', 'keyboard');
1300
assert.strictEqual(model.getValue(), [
1301
'{',
1302
' for(;;)',
1303
' for(;;) {',
1304
' ',
1305
' }',
1306
'}',
1307
].join('\n'));
1308
});
1309
});
1310
1311
test.skip('issue #67678: indent on typing curly brace', () => {
1312
1313
// https://github.com/microsoft/vscode/issues/67678
1314
1315
const model = createTextModel([
1316
'if (true) {',
1317
'console.log("a")',
1318
'console.log("b")',
1319
'',
1320
].join('\n'), languageId, {});
1321
disposables.add(model);
1322
1323
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1324
editor.setSelection(new Selection(4, 1, 4, 1));
1325
viewModel.type('}', 'keyboard');
1326
assert.strictEqual(model.getValue(), [
1327
'if (true) {',
1328
' console.log("a")',
1329
' console.log("b")',
1330
'}',
1331
].join('\n'));
1332
});
1333
});
1334
1335
test.skip('issue #46401: outdent when encountering bracket on line - allman style indentation', () => {
1336
1337
// https://github.com/microsoft/vscode/issues/46401
1338
1339
const model = createTextModel([
1340
'if (true)',
1341
' ',
1342
].join('\n'), languageId, {});
1343
disposables.add(model);
1344
1345
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1346
editor.setSelection(new Selection(2, 5, 2, 5));
1347
viewModel.type('{}', 'keyboard');
1348
assert.strictEqual(model.getValue(), [
1349
'if (true)',
1350
'{}',
1351
].join('\n'));
1352
editor.setSelection(new Selection(2, 2, 2, 2));
1353
viewModel.type('\n', 'keyboard');
1354
assert.strictEqual(model.getValue(), [
1355
'if (true)',
1356
'{',
1357
' ',
1358
'}'
1359
].join('\n'));
1360
});
1361
});
1362
1363
test.skip('issue #125261: typing closing brace does not keep the current indentation', () => {
1364
1365
// https://github.com/microsoft/vscode/issues/125261
1366
1367
const model = createTextModel([
1368
'foo {',
1369
' ',
1370
].join('\n'), languageId, {});
1371
disposables.add(model);
1372
1373
withTestCodeEditor(model, { autoIndent: 'keep', serviceCollection }, (editor, viewModel) => {
1374
editor.setSelection(new Selection(2, 5, 2, 5));
1375
viewModel.type('}', 'keyboard');
1376
assert.strictEqual(model.getValue(), [
1377
'foo {',
1378
'}',
1379
].join('\n'));
1380
});
1381
});
1382
});
1383
1384
suite('Auto Indent On Type - Ruby', () => {
1385
1386
const languageId = Language.Ruby;
1387
let disposables: DisposableStore;
1388
let serviceCollection: ServiceCollection;
1389
1390
setup(() => {
1391
disposables = new DisposableStore();
1392
const languageService = new LanguageService();
1393
const languageConfigurationService = new TestLanguageConfigurationService();
1394
disposables.add(languageService);
1395
disposables.add(languageConfigurationService);
1396
disposables.add(registerLanguage(languageService, languageId));
1397
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
1398
serviceCollection = new ServiceCollection(
1399
[ILanguageService, languageService],
1400
[ILanguageConfigurationService, languageConfigurationService]
1401
);
1402
});
1403
1404
teardown(() => {
1405
disposables.dispose();
1406
});
1407
1408
ensureNoDisposablesAreLeakedInTestSuite();
1409
1410
test('issue #198350: in or when incorrectly match non keywords for Ruby', () => {
1411
1412
// https://github.com/microsoft/vscode/issues/198350
1413
1414
const model = createTextModel('', languageId, {});
1415
disposables.add(model);
1416
1417
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1418
viewModel.type('def foo\n i');
1419
viewModel.type('n', 'keyboard');
1420
assert.strictEqual(model.getValue(), 'def foo\n in');
1421
viewModel.type(' ', 'keyboard');
1422
assert.strictEqual(model.getValue(), 'def foo\nin ');
1423
1424
viewModel.model.setValue('');
1425
viewModel.type(' # in');
1426
assert.strictEqual(model.getValue(), ' # in');
1427
viewModel.type(' ', 'keyboard');
1428
assert.strictEqual(model.getValue(), ' # in ');
1429
});
1430
});
1431
1432
// Failing tests...
1433
1434
test.skip('issue #199846: in or when incorrectly match non keywords for Ruby', () => {
1435
1436
// https://github.com/microsoft/vscode/issues/199846
1437
// explanation: happening because the # is detected probably as a comment
1438
1439
const model = createTextModel('', languageId, {});
1440
disposables.add(model);
1441
1442
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1443
viewModel.type(`method('#foo') do`);
1444
viewModel.type('\n', 'keyboard');
1445
assert.strictEqual(model.getValue(), [
1446
`method('#foo') do`,
1447
' '
1448
].join('\n'));
1449
});
1450
});
1451
});
1452
1453
suite('Auto Indent On Type - PHP', () => {
1454
1455
const languageId = Language.PHP;
1456
let disposables: DisposableStore;
1457
let serviceCollection: ServiceCollection;
1458
1459
setup(() => {
1460
disposables = new DisposableStore();
1461
const languageService = new LanguageService();
1462
const languageConfigurationService = new TestLanguageConfigurationService();
1463
disposables.add(languageService);
1464
disposables.add(languageConfigurationService);
1465
disposables.add(registerLanguage(languageService, languageId));
1466
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
1467
serviceCollection = new ServiceCollection(
1468
[ILanguageService, languageService],
1469
[ILanguageConfigurationService, languageConfigurationService]
1470
);
1471
});
1472
1473
teardown(() => {
1474
disposables.dispose();
1475
});
1476
1477
ensureNoDisposablesAreLeakedInTestSuite();
1478
1479
test('issue #199050: should not indent after { detected in a string', () => {
1480
1481
// https://github.com/microsoft/vscode/issues/199050
1482
1483
const model = createTextModel(`preg_replace('{');`, languageId, {});
1484
disposables.add(model);
1485
1486
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
1487
const tokens: StandardTokenTypeData[][] = [
1488
[
1489
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
1490
{ startIndex: 13, standardTokenType: StandardTokenType.String },
1491
{ startIndex: 16, standardTokenType: StandardTokenType.Other },
1492
]
1493
];
1494
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
1495
editor.setSelection(new Selection(1, 54, 1, 54));
1496
viewModel.type('\n', 'keyboard');
1497
assert.strictEqual(model.getValue(), [
1498
`preg_replace('{');`,
1499
''
1500
].join('\n'));
1501
});
1502
});
1503
});
1504
1505
suite('Auto Indent On Paste - Go', () => {
1506
1507
const languageId = Language.Go;
1508
let disposables: DisposableStore;
1509
let serviceCollection: ServiceCollection;
1510
1511
setup(() => {
1512
disposables = new DisposableStore();
1513
const languageService = new LanguageService();
1514
const languageConfigurationService = new TestLanguageConfigurationService();
1515
disposables.add(languageService);
1516
disposables.add(languageConfigurationService);
1517
disposables.add(registerLanguage(languageService, languageId));
1518
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
1519
serviceCollection = new ServiceCollection(
1520
[ILanguageService, languageService],
1521
[ILanguageConfigurationService, languageConfigurationService]
1522
);
1523
});
1524
1525
teardown(() => {
1526
disposables.dispose();
1527
});
1528
1529
ensureNoDisposablesAreLeakedInTestSuite();
1530
1531
test('temp issue because there should be at least one passing test in a suite', () => {
1532
assert.ok(true);
1533
});
1534
1535
test.skip('issue #199050: should not indent after { detected in a string', () => {
1536
1537
// https://github.com/microsoft/vscode/issues/199050
1538
1539
const model = createTextModel([
1540
'var s = `',
1541
'quick brown',
1542
'fox',
1543
'`',
1544
].join('\n'), languageId, {});
1545
disposables.add(model);
1546
1547
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1548
editor.setSelection(new Selection(3, 1, 3, 1));
1549
const text = ' ';
1550
const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste);
1551
viewModel.paste(text, true, undefined, 'keyboard');
1552
autoIndentOnPasteController.trigger(new Range(3, 1, 3, 3));
1553
assert.strictEqual(model.getValue(), [
1554
'var s = `',
1555
'quick brown',
1556
' fox',
1557
'`',
1558
].join('\n'));
1559
});
1560
});
1561
});
1562
1563
suite('Auto Indent On Type - CPP', () => {
1564
1565
const languageId = Language.CPP;
1566
let disposables: DisposableStore;
1567
let serviceCollection: ServiceCollection;
1568
1569
setup(() => {
1570
disposables = new DisposableStore();
1571
const languageService = new LanguageService();
1572
const languageConfigurationService = new TestLanguageConfigurationService();
1573
disposables.add(languageService);
1574
disposables.add(languageConfigurationService);
1575
disposables.add(registerLanguage(languageService, languageId));
1576
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
1577
serviceCollection = new ServiceCollection(
1578
[ILanguageService, languageService],
1579
[ILanguageConfigurationService, languageConfigurationService]
1580
);
1581
});
1582
1583
teardown(() => {
1584
disposables.dispose();
1585
});
1586
1587
ensureNoDisposablesAreLeakedInTestSuite();
1588
1589
test('temp issue because there should be at least one passing test in a suite', () => {
1590
assert.ok(true);
1591
});
1592
1593
test.skip('issue #178334: incorrect outdent of } when signature spans multiple lines', () => {
1594
1595
// https://github.com/microsoft/vscode/issues/178334
1596
1597
const model = createTextModel([
1598
'int WINAPI WinMain(bool instance,',
1599
' int nshowcmd) {}',
1600
].join('\n'), languageId, {});
1601
disposables.add(model);
1602
1603
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1604
editor.setSelection(new Selection(2, 20, 2, 20));
1605
viewModel.type('\n', 'keyboard');
1606
assert.strictEqual(model.getValue(), [
1607
'int WINAPI WinMain(bool instance,',
1608
' int nshowcmd) {',
1609
' ',
1610
'}'
1611
].join('\n'));
1612
});
1613
});
1614
1615
test.skip('issue #118929: incorrect indent when // follows curly brace', () => {
1616
1617
// https://github.com/microsoft/vscode/issues/118929
1618
1619
const model = createTextModel([
1620
'if (true) { // jaja',
1621
'}',
1622
].join('\n'), languageId, {});
1623
disposables.add(model);
1624
1625
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1626
editor.setSelection(new Selection(1, 20, 1, 20));
1627
viewModel.type('\n', 'keyboard');
1628
assert.strictEqual(model.getValue(), [
1629
'if (true) { // jaja',
1630
' ',
1631
'}',
1632
].join('\n'));
1633
});
1634
});
1635
1636
test.skip('issue #111265: auto indentation set to "none" still changes the indentation', () => {
1637
1638
// https://github.com/microsoft/vscode/issues/111265
1639
1640
const model = createTextModel([
1641
'int func() {',
1642
' ',
1643
].join('\n'), languageId, {});
1644
disposables.add(model);
1645
1646
withTestCodeEditor(model, { autoIndent: 'none', serviceCollection }, (editor, viewModel) => {
1647
editor.setSelection(new Selection(2, 3, 2, 3));
1648
viewModel.type('}', 'keyboard');
1649
assert.strictEqual(model.getValue(), [
1650
'int func() {',
1651
' }',
1652
].join('\n'));
1653
});
1654
});
1655
1656
});
1657
1658
suite('Auto Indent On Type - HTML', () => {
1659
1660
const languageId = Language.HTML;
1661
let disposables: DisposableStore;
1662
let serviceCollection: ServiceCollection;
1663
1664
setup(() => {
1665
disposables = new DisposableStore();
1666
const languageService = new LanguageService();
1667
const languageConfigurationService = new TestLanguageConfigurationService();
1668
disposables.add(languageService);
1669
disposables.add(languageConfigurationService);
1670
disposables.add(registerLanguage(languageService, languageId));
1671
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
1672
serviceCollection = new ServiceCollection(
1673
[ILanguageService, languageService],
1674
[ILanguageConfigurationService, languageConfigurationService]
1675
);
1676
});
1677
1678
teardown(() => {
1679
disposables.dispose();
1680
});
1681
1682
ensureNoDisposablesAreLeakedInTestSuite();
1683
1684
test('temp issue because there should be at least one passing test in a suite', () => {
1685
assert.ok(true);
1686
});
1687
1688
test.skip('issue #61510: incorrect indentation after // in html file', () => {
1689
1690
// https://github.com/microsoft/vscode/issues/178334
1691
1692
const model = createTextModel([
1693
'<pre>',
1694
' foo //I press <Enter> at the end of this line',
1695
'</pre>',
1696
].join('\n'), languageId, {});
1697
disposables.add(model);
1698
1699
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1700
editor.setSelection(new Selection(2, 48, 2, 48));
1701
viewModel.type('\n', 'keyboard');
1702
assert.strictEqual(model.getValue(), [
1703
'<pre>',
1704
' foo //I press <Enter> at the end of this line',
1705
' ',
1706
'</pre>',
1707
].join('\n'));
1708
});
1709
});
1710
});
1711
1712
suite('Auto Indent On Type - Visual Basic', () => {
1713
1714
const languageId = Language.VB;
1715
let disposables: DisposableStore;
1716
let serviceCollection: ServiceCollection;
1717
1718
setup(() => {
1719
disposables = new DisposableStore();
1720
const languageService = new LanguageService();
1721
const languageConfigurationService = new TestLanguageConfigurationService();
1722
disposables.add(languageService);
1723
disposables.add(languageConfigurationService);
1724
disposables.add(registerLanguage(languageService, languageId));
1725
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
1726
serviceCollection = new ServiceCollection(
1727
[ILanguageService, languageService],
1728
[ILanguageConfigurationService, languageConfigurationService]
1729
);
1730
});
1731
1732
teardown(() => {
1733
disposables.dispose();
1734
});
1735
1736
ensureNoDisposablesAreLeakedInTestSuite();
1737
1738
test('temp issue because there should be at least one passing test in a suite', () => {
1739
assert.ok(true);
1740
});
1741
1742
test('issue #118932: no indentation in visual basic files', () => {
1743
1744
// https://github.com/microsoft/vscode/issues/118932
1745
1746
const model = createTextModel([
1747
'If True Then',
1748
' Some code',
1749
' End I',
1750
].join('\n'), languageId, {});
1751
disposables.add(model);
1752
1753
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel, instantiationService) => {
1754
editor.setSelection(new Selection(3, 10, 3, 10));
1755
viewModel.type('f', 'keyboard');
1756
assert.strictEqual(model.getValue(), [
1757
'If True Then',
1758
' Some code',
1759
'End If',
1760
].join('\n'));
1761
});
1762
});
1763
1764
test('issue #118932: indent after Module declaration', () => {
1765
1766
// https://github.com/microsoft/vscode/issues/118932
1767
1768
const model = createTextModel('', languageId, {});
1769
disposables.add(model);
1770
1771
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1772
viewModel.type('Module Test');
1773
viewModel.type('\n', 'keyboard');
1774
assert.strictEqual(model.getValue(), [
1775
'Module Test',
1776
' ',
1777
].join('\n'));
1778
});
1779
});
1780
1781
test('issue #118932: indent after Sub declaration', () => {
1782
1783
// https://github.com/microsoft/vscode/issues/118932
1784
1785
const model = createTextModel([
1786
'Module Test',
1787
' ',
1788
].join('\n'), languageId, {});
1789
disposables.add(model);
1790
1791
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1792
editor.setSelection(new Selection(2, 5, 2, 5));
1793
viewModel.type('Sub Main()');
1794
viewModel.type('\n', 'keyboard');
1795
assert.strictEqual(model.getValue(), [
1796
'Module Test',
1797
' Sub Main()',
1798
' ',
1799
].join('\n'));
1800
});
1801
});
1802
1803
test('issue #118932: dedent on End Sub', () => {
1804
1805
// https://github.com/microsoft/vscode/issues/118932
1806
1807
const model = createTextModel([
1808
'Module Test',
1809
' Sub Main()',
1810
' Console.WriteLine("Hello")',
1811
' End Su',
1812
].join('\n'), languageId, {});
1813
disposables.add(model);
1814
1815
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1816
editor.setSelection(new Selection(4, 15, 4, 15));
1817
viewModel.type('b', 'keyboard');
1818
assert.strictEqual(model.getValue(), [
1819
'Module Test',
1820
' Sub Main()',
1821
' Console.WriteLine("Hello")',
1822
' End Sub',
1823
].join('\n'));
1824
});
1825
});
1826
1827
test('issue #118932: dedent on End Module', () => {
1828
1829
// https://github.com/microsoft/vscode/issues/118932
1830
// When End Module is typed right after Module (no nested blocks), it dedents correctly
1831
1832
const model = createTextModel([
1833
'Module Test',
1834
' Private x As Integer',
1835
' End Modul',
1836
].join('\n'), languageId, {});
1837
disposables.add(model);
1838
1839
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1840
editor.setSelection(new Selection(3, 14, 3, 14));
1841
viewModel.type('e', 'keyboard');
1842
assert.strictEqual(model.getValue(), [
1843
'Module Test',
1844
' Private x As Integer',
1845
'End Module',
1846
].join('\n'));
1847
});
1848
});
1849
1850
test('issue #118932: indent after Function declaration', () => {
1851
1852
// https://github.com/microsoft/vscode/issues/118932
1853
1854
const model = createTextModel([
1855
'Module Test',
1856
' ',
1857
].join('\n'), languageId, {});
1858
disposables.add(model);
1859
1860
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1861
editor.setSelection(new Selection(2, 5, 2, 5));
1862
viewModel.type('Function Add(a As Integer, b As Integer) As Integer');
1863
viewModel.type('\n', 'keyboard');
1864
assert.strictEqual(model.getValue(), [
1865
'Module Test',
1866
' Function Add(a As Integer, b As Integer) As Integer',
1867
' ',
1868
].join('\n'));
1869
});
1870
});
1871
1872
test('issue #118932: dedent on End Function', () => {
1873
1874
// https://github.com/microsoft/vscode/issues/118932
1875
1876
const model = createTextModel([
1877
'Module Test',
1878
' Function Add(a, b)',
1879
' Return a + b',
1880
' End Functio',
1881
].join('\n'), languageId, {});
1882
disposables.add(model);
1883
1884
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1885
editor.setSelection(new Selection(4, 20, 4, 20));
1886
viewModel.type('n', 'keyboard');
1887
assert.strictEqual(model.getValue(), [
1888
'Module Test',
1889
' Function Add(a, b)',
1890
' Return a + b',
1891
' End Function',
1892
].join('\n'));
1893
});
1894
});
1895
1896
test('issue #118932: indent after If Then', () => {
1897
1898
// https://github.com/microsoft/vscode/issues/118932
1899
1900
const model = createTextModel([
1901
'Sub Test()',
1902
' ',
1903
].join('\n'), languageId, {});
1904
disposables.add(model);
1905
1906
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1907
editor.setSelection(new Selection(2, 5, 2, 5));
1908
viewModel.type('If x > 0 Then');
1909
viewModel.type('\n', 'keyboard');
1910
assert.strictEqual(model.getValue(), [
1911
'Sub Test()',
1912
' If x > 0 Then',
1913
' ',
1914
].join('\n'));
1915
});
1916
});
1917
1918
test('issue #118932: indent after ElseIf Then', () => {
1919
1920
// https://github.com/microsoft/vscode/issues/118932
1921
1922
const model = createTextModel([
1923
'Sub Test()',
1924
' If x > 0 Then',
1925
' DoSomething()',
1926
' ElseIf x < 0 Then',
1927
].join('\n'), languageId, {});
1928
disposables.add(model);
1929
1930
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1931
editor.setSelection(new Selection(4, 22, 4, 22));
1932
viewModel.type('\n', 'keyboard');
1933
assert.strictEqual(model.getValue(), [
1934
'Sub Test()',
1935
' If x > 0 Then',
1936
' DoSomething()',
1937
' ElseIf x < 0 Then',
1938
' ',
1939
].join('\n'));
1940
});
1941
});
1942
1943
test('issue #118932: dedent and indent on Else', () => {
1944
1945
// https://github.com/microsoft/vscode/issues/118932
1946
1947
const model = createTextModel([
1948
'Sub Test()',
1949
' If x > 0 Then',
1950
' DoSomething()',
1951
' Els',
1952
].join('\n'), languageId, {});
1953
disposables.add(model);
1954
1955
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1956
editor.setSelection(new Selection(4, 12, 4, 12));
1957
viewModel.type('e', 'keyboard');
1958
assert.strictEqual(model.getValue(), [
1959
'Sub Test()',
1960
' If x > 0 Then',
1961
' DoSomething()',
1962
' Else',
1963
].join('\n'));
1964
});
1965
});
1966
1967
test('issue #118932: indent after While', () => {
1968
1969
// https://github.com/microsoft/vscode/issues/118932
1970
1971
const model = createTextModel([
1972
'Sub Test()',
1973
' ',
1974
].join('\n'), languageId, {});
1975
disposables.add(model);
1976
1977
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
1978
editor.setSelection(new Selection(2, 5, 2, 5));
1979
viewModel.type('While x > 0');
1980
viewModel.type('\n', 'keyboard');
1981
assert.strictEqual(model.getValue(), [
1982
'Sub Test()',
1983
' While x > 0',
1984
' ',
1985
].join('\n'));
1986
});
1987
});
1988
1989
test('issue #118932: dedent on End While', () => {
1990
1991
// https://github.com/microsoft/vscode/issues/118932
1992
1993
const model = createTextModel([
1994
'Sub Test()',
1995
' While x > 0',
1996
' x = x - 1',
1997
' End Whil',
1998
].join('\n'), languageId, {});
1999
disposables.add(model);
2000
2001
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2002
editor.setSelection(new Selection(4, 17, 4, 17));
2003
viewModel.type('e', 'keyboard');
2004
assert.strictEqual(model.getValue(), [
2005
'Sub Test()',
2006
' While x > 0',
2007
' x = x - 1',
2008
' End While',
2009
].join('\n'));
2010
});
2011
});
2012
2013
test('issue #118932: indent after For', () => {
2014
2015
// https://github.com/microsoft/vscode/issues/118932
2016
2017
const model = createTextModel([
2018
'Sub Test()',
2019
' ',
2020
].join('\n'), languageId, {});
2021
disposables.add(model);
2022
2023
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2024
editor.setSelection(new Selection(2, 5, 2, 5));
2025
viewModel.type('For i = 1 To 10');
2026
viewModel.type('\n', 'keyboard');
2027
assert.strictEqual(model.getValue(), [
2028
'Sub Test()',
2029
' For i = 1 To 10',
2030
' ',
2031
].join('\n'));
2032
});
2033
});
2034
2035
test('issue #118932: dedent on Next', () => {
2036
2037
// https://github.com/microsoft/vscode/issues/118932
2038
2039
const model = createTextModel([
2040
'Sub Test()',
2041
' For i = 1 To 10',
2042
' DoSomething(i)',
2043
' Nex',
2044
].join('\n'), languageId, {});
2045
disposables.add(model);
2046
2047
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2048
editor.setSelection(new Selection(4, 12, 4, 12));
2049
viewModel.type('t', 'keyboard');
2050
assert.strictEqual(model.getValue(), [
2051
'Sub Test()',
2052
' For i = 1 To 10',
2053
' DoSomething(i)',
2054
' Next',
2055
].join('\n'));
2056
});
2057
});
2058
2059
test('issue #118932: indent after Do', () => {
2060
2061
// https://github.com/microsoft/vscode/issues/118932
2062
2063
const model = createTextModel([
2064
'Sub Test()',
2065
' ',
2066
].join('\n'), languageId, {});
2067
disposables.add(model);
2068
2069
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2070
editor.setSelection(new Selection(2, 5, 2, 5));
2071
viewModel.type('Do');
2072
viewModel.type('\n', 'keyboard');
2073
assert.strictEqual(model.getValue(), [
2074
'Sub Test()',
2075
' Do',
2076
' ',
2077
].join('\n'));
2078
});
2079
});
2080
2081
test('issue #118932: dedent on Loop', () => {
2082
2083
// https://github.com/microsoft/vscode/issues/118932
2084
2085
const model = createTextModel([
2086
'Sub Test()',
2087
' Do',
2088
' x = x + 1',
2089
' Loo',
2090
].join('\n'), languageId, {});
2091
disposables.add(model);
2092
2093
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2094
editor.setSelection(new Selection(4, 12, 4, 12));
2095
viewModel.type('p', 'keyboard');
2096
assert.strictEqual(model.getValue(), [
2097
'Sub Test()',
2098
' Do',
2099
' x = x + 1',
2100
' Loop',
2101
].join('\n'));
2102
});
2103
});
2104
2105
test('issue #118932: indent after Select Case', () => {
2106
2107
// https://github.com/microsoft/vscode/issues/118932
2108
2109
const model = createTextModel([
2110
'Sub Test()',
2111
' ',
2112
].join('\n'), languageId, {});
2113
disposables.add(model);
2114
2115
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2116
editor.setSelection(new Selection(2, 5, 2, 5));
2117
viewModel.type('Select Case x');
2118
viewModel.type('\n', 'keyboard');
2119
assert.strictEqual(model.getValue(), [
2120
'Sub Test()',
2121
' Select Case x',
2122
' ',
2123
].join('\n'));
2124
});
2125
});
2126
2127
test('issue #118932: dedent on End Select', () => {
2128
2129
// https://github.com/microsoft/vscode/issues/118932
2130
// When End Select is typed, it dedents to match Select Case level
2131
2132
const model = createTextModel([
2133
'Sub Test()',
2134
' Select Case x',
2135
' End Selec',
2136
].join('\n'), languageId, {});
2137
disposables.add(model);
2138
2139
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2140
editor.setSelection(new Selection(3, 18, 3, 18));
2141
viewModel.type('t', 'keyboard');
2142
assert.strictEqual(model.getValue(), [
2143
'Sub Test()',
2144
' Select Case x',
2145
' End Select',
2146
].join('\n'));
2147
});
2148
});
2149
2150
test('issue #118932: indent after Try', () => {
2151
2152
// https://github.com/microsoft/vscode/issues/118932
2153
2154
const model = createTextModel([
2155
'Sub Test()',
2156
' ',
2157
].join('\n'), languageId, {});
2158
disposables.add(model);
2159
2160
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2161
editor.setSelection(new Selection(2, 5, 2, 5));
2162
viewModel.type('Try');
2163
viewModel.type('\n', 'keyboard');
2164
assert.strictEqual(model.getValue(), [
2165
'Sub Test()',
2166
' Try',
2167
' ',
2168
].join('\n'));
2169
});
2170
});
2171
2172
test('issue #118932: dedent and indent on Catch', () => {
2173
2174
// https://github.com/microsoft/vscode/issues/118932
2175
2176
const model = createTextModel([
2177
'Sub Test()',
2178
' Try',
2179
' DoSomething()',
2180
' Catc',
2181
].join('\n'), languageId, {});
2182
disposables.add(model);
2183
2184
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2185
editor.setSelection(new Selection(4, 13, 4, 13));
2186
viewModel.type('h', 'keyboard');
2187
assert.strictEqual(model.getValue(), [
2188
'Sub Test()',
2189
' Try',
2190
' DoSomething()',
2191
' Catch',
2192
].join('\n'));
2193
});
2194
});
2195
2196
test('issue #118932: dedent and indent on Finally', () => {
2197
2198
// https://github.com/microsoft/vscode/issues/118932
2199
2200
const model = createTextModel([
2201
'Sub Test()',
2202
' Try',
2203
' DoSomething()',
2204
' Catch',
2205
' HandleError()',
2206
' Finall',
2207
].join('\n'), languageId, {});
2208
disposables.add(model);
2209
2210
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2211
editor.setSelection(new Selection(6, 15, 6, 15));
2212
viewModel.type('y', 'keyboard');
2213
assert.strictEqual(model.getValue(), [
2214
'Sub Test()',
2215
' Try',
2216
' DoSomething()',
2217
' Catch',
2218
' HandleError()',
2219
' Finally',
2220
].join('\n'));
2221
});
2222
});
2223
2224
test('issue #118932: dedent on End Try', () => {
2225
2226
// https://github.com/microsoft/vscode/issues/118932
2227
2228
const model = createTextModel([
2229
'Sub Test()',
2230
' Try',
2231
' DoSomething()',
2232
' Catch',
2233
' HandleError()',
2234
' Finally',
2235
' Cleanup()',
2236
' End Tr',
2237
].join('\n'), languageId, {});
2238
disposables.add(model);
2239
2240
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2241
editor.setSelection(new Selection(8, 15, 8, 15));
2242
viewModel.type('y', 'keyboard');
2243
assert.strictEqual(model.getValue(), [
2244
'Sub Test()',
2245
' Try',
2246
' DoSomething()',
2247
' Catch',
2248
' HandleError()',
2249
' Finally',
2250
' Cleanup()',
2251
' End Try',
2252
].join('\n'));
2253
});
2254
});
2255
2256
test('issue #118932: indent after Class', () => {
2257
2258
// https://github.com/microsoft/vscode/issues/118932
2259
2260
const model = createTextModel('', languageId, {});
2261
disposables.add(model);
2262
2263
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2264
viewModel.type('Class MyClass');
2265
viewModel.type('\n', 'keyboard');
2266
assert.strictEqual(model.getValue(), [
2267
'Class MyClass',
2268
' ',
2269
].join('\n'));
2270
});
2271
});
2272
2273
test('issue #118932: dedent on End Class', () => {
2274
2275
// https://github.com/microsoft/vscode/issues/118932
2276
2277
const model = createTextModel([
2278
'Class MyClass',
2279
' Private x As Integer',
2280
' End Clas',
2281
].join('\n'), languageId, {});
2282
disposables.add(model);
2283
2284
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2285
editor.setSelection(new Selection(3, 14, 3, 14));
2286
viewModel.type('s', 'keyboard');
2287
assert.strictEqual(model.getValue(), [
2288
'Class MyClass',
2289
' Private x As Integer',
2290
'End Class',
2291
].join('\n'));
2292
});
2293
});
2294
2295
test('issue #118932: full program indentation flow', () => {
2296
2297
// https://github.com/microsoft/vscode/issues/118932
2298
// Verify the complete flow as described in the verification comment
2299
// Note: Auto-indent only triggers on typing the last character that completes a keyword
2300
// and only decreases by one indentation level per keyword completion
2301
2302
const model = createTextModel('', languageId, {});
2303
disposables.add(model);
2304
2305
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2306
// Type Module Test and press Enter
2307
viewModel.type('Module Test');
2308
viewModel.type('\n', 'keyboard');
2309
assert.strictEqual(model.getValue(), [
2310
'Module Test',
2311
' ',
2312
].join('\n'), 'After Module Test');
2313
2314
// Type Sub Main() and press Enter
2315
viewModel.type('Sub Main()');
2316
viewModel.type('\n', 'keyboard');
2317
assert.strictEqual(model.getValue(), [
2318
'Module Test',
2319
' Sub Main()',
2320
' ',
2321
].join('\n'), 'After Sub Main()');
2322
2323
// Type Console.WriteLine and press Enter
2324
viewModel.type('Console.WriteLine("Hello, World!")');
2325
viewModel.type('\n', 'keyboard');
2326
assert.strictEqual(model.getValue(), [
2327
'Module Test',
2328
' Sub Main()',
2329
' Console.WriteLine("Hello, World!")',
2330
' ',
2331
].join('\n'), 'After Console.WriteLine');
2332
2333
// Type End Su then 'b' to complete End Sub (auto-indent triggers on last char)
2334
viewModel.type('End Su');
2335
viewModel.type('b', 'keyboard');
2336
assert.strictEqual(model.getValue(), [
2337
'Module Test',
2338
' Sub Main()',
2339
' Console.WriteLine("Hello, World!")',
2340
' End Sub',
2341
].join('\n'), 'After End Sub');
2342
2343
// Press Enter - should maintain same indent level after End Sub
2344
viewModel.type('\n', 'keyboard');
2345
assert.strictEqual(model.getValue(), [
2346
'Module Test',
2347
' Sub Main()',
2348
' Console.WriteLine("Hello, World!")',
2349
' End Sub',
2350
' ',
2351
].join('\n'), 'After Enter after End Sub');
2352
});
2353
});
2354
});
2355
2356
2357
suite('Auto Indent On Type - Latex', () => {
2358
2359
const languageId = Language.Latex;
2360
let disposables: DisposableStore;
2361
let serviceCollection: ServiceCollection;
2362
2363
setup(() => {
2364
disposables = new DisposableStore();
2365
const languageService = new LanguageService();
2366
const languageConfigurationService = new TestLanguageConfigurationService();
2367
disposables.add(languageService);
2368
disposables.add(languageConfigurationService);
2369
disposables.add(registerLanguage(languageService, languageId));
2370
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
2371
serviceCollection = new ServiceCollection(
2372
[ILanguageService, languageService],
2373
[ILanguageConfigurationService, languageConfigurationService]
2374
);
2375
});
2376
2377
teardown(() => {
2378
disposables.dispose();
2379
});
2380
2381
ensureNoDisposablesAreLeakedInTestSuite();
2382
2383
test('temp issue because there should be at least one passing test in a suite', () => {
2384
assert.ok(true);
2385
});
2386
2387
test.skip('issue #178075: no auto closing pair when indentation done', () => {
2388
2389
// https://github.com/microsoft/vscode/issues/178075
2390
2391
const model = createTextModel([
2392
'\\begin{theorem}',
2393
' \\end',
2394
].join('\n'), languageId, {});
2395
disposables.add(model);
2396
2397
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2398
editor.setSelection(new Selection(2, 9, 2, 9));
2399
viewModel.type('{', 'keyboard');
2400
assert.strictEqual(model.getValue(), [
2401
'\\begin{theorem}',
2402
'\\end{}',
2403
].join('\n'));
2404
});
2405
});
2406
});
2407
2408
suite('Auto Indent On Type - Lua', () => {
2409
2410
const languageId = Language.Lua;
2411
let disposables: DisposableStore;
2412
let serviceCollection: ServiceCollection;
2413
2414
setup(() => {
2415
disposables = new DisposableStore();
2416
const languageService = new LanguageService();
2417
const languageConfigurationService = new TestLanguageConfigurationService();
2418
disposables.add(languageService);
2419
disposables.add(languageConfigurationService);
2420
disposables.add(registerLanguage(languageService, languageId));
2421
disposables.add(registerLanguageConfiguration(languageConfigurationService, languageId));
2422
serviceCollection = new ServiceCollection(
2423
[ILanguageService, languageService],
2424
[ILanguageConfigurationService, languageConfigurationService]
2425
);
2426
});
2427
2428
teardown(() => {
2429
disposables.dispose();
2430
});
2431
2432
ensureNoDisposablesAreLeakedInTestSuite();
2433
2434
test('temp issue because there should be at least one passing test in a suite', () => {
2435
assert.ok(true);
2436
});
2437
2438
test.skip('issue #178075: no auto closing pair when indentation done', () => {
2439
2440
// https://github.com/microsoft/vscode/issues/178075
2441
2442
const model = createTextModel([
2443
'print("asdf function asdf")',
2444
].join('\n'), languageId, {});
2445
disposables.add(model);
2446
2447
withTestCodeEditor(model, { autoIndent: 'full', serviceCollection }, (editor, viewModel) => {
2448
editor.setSelection(new Selection(1, 28, 1, 28));
2449
viewModel.type('\n', 'keyboard');
2450
assert.strictEqual(model.getValue(), [
2451
'print("asdf function asdf")',
2452
''
2453
].join('\n'));
2454
});
2455
});
2456
});
2457
2458