Skip to content

Commit c70f922

Browse files
authored
Add Suggestion Provider For TS Directives (microsoft#25806)
* Add Suggestion Provider For TS Directives Adds a new completion provider to suggest typescript comment directives, such as `@ts-check` or `@ts-ignore` Fixes microsoft#25413 * Add descriptions to snippets
1 parent de03033 commit c70f922

2 files changed

Lines changed: 76 additions & 2 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
'use strict';
7+
8+
import { Position, CompletionItemProvider, CompletionItemKind, TextDocument, CancellationToken, CompletionItem, ProviderResult, Range } from 'vscode';
9+
10+
import { ITypescriptServiceClient } from '../typescriptService';
11+
12+
import * as nls from 'vscode-nls';
13+
const localize = nls.loadMessageBundle();
14+
15+
interface Directive {
16+
value: string;
17+
description: string;
18+
}
19+
20+
const directives: Directive[] = [
21+
{
22+
value: '@ts-check',
23+
description: localize(
24+
'ts-check',
25+
'Enables semantic checking in a JavaScript file. Must be at the top of a file.')
26+
}, {
27+
value: '@ts-nocheck',
28+
description: localize(
29+
'ts-nocheck',
30+
'Disables semantic checking in a JavaScript file. Must be at the top of a file.')
31+
}, {
32+
value: '@ts-ignore',
33+
description: localize(
34+
'ts-ignore',
35+
'Suppresses @ts-check errors on the next line of a file.')
36+
}
37+
];
38+
39+
export class DirectiveCommentCompletionProvider implements CompletionItemProvider {
40+
constructor(
41+
private client: ITypescriptServiceClient,
42+
) { }
43+
44+
public provideCompletionItems(document: TextDocument, position: Position, _token: CancellationToken): ProviderResult<CompletionItem[]> {
45+
if (!this.client.apiVersion.has230Features()) {
46+
return [];
47+
}
48+
49+
const file = this.client.normalizePath(document.uri);
50+
if (!file) {
51+
return [];
52+
}
53+
54+
const line = document.lineAt(position.line).text;
55+
const prefix = line.slice(0, position.character);
56+
const match = prefix.match(/^\s*\/\/+\s?(@[a-zA-Z\-]*)?$/);
57+
if (match) {
58+
return directives.map(directive => {
59+
const item = new CompletionItem(directive.value, CompletionItemKind.Snippet);
60+
item.detail = directive.description;
61+
item.range = new Range(position.line, Math.max(0, position.character - match[1].length), position.line, position.character);
62+
return item;
63+
});
64+
}
65+
return [];
66+
}
67+
68+
public resolveCompletionItem(item: CompletionItem, _token: CancellationToken) {
69+
return item;
70+
}
71+
}

extensions/typescript/src/typescriptMain.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import WorkspaceSymbolProvider from './features/workspaceSymbolProvider';
4141
import CodeActionProvider from './features/codeActionProvider';
4242
import ReferenceCodeLensProvider from './features/referencesCodeLensProvider';
4343
import { JsDocCompletionProvider, TryCompleteJsDocCommand } from './features/jsDocCompletionProvider';
44+
import { DirectiveCommentCompletionProvider } from './features/directiveCommentCompletionProvider';
45+
4446
import ImplementationCodeLensProvider from './features/implementationsCodeLensProvider';
4547

4648
import * as BuildStatus from './utils/buildStatus';
@@ -215,6 +217,8 @@ class LanguageProvider {
215217
this.completionItemProvider.updateConfiguration();
216218
this.disposables.push(languages.registerCompletionItemProvider(selector, this.completionItemProvider, '.'));
217219

220+
this.disposables.push(languages.registerCompletionItemProvider(selector, new DirectiveCommentCompletionProvider(client), '@'));
221+
218222
this.formattingProvider = new FormattingProvider(client);
219223
this.formattingProvider.updateConfiguration(config);
220224
this.disposables.push(languages.registerOnTypeFormattingEditProvider(selector, this.formattingProvider, ';', '}', '\n'));
@@ -416,7 +420,7 @@ class LanguageProvider {
416420

417421
class TypeScriptServiceClientHost implements ITypescriptServiceClientHost {
418422
private client: TypeScriptServiceClient;
419-
private languages: LanguageProvider[];
423+
private languages: LanguageProvider[] = [];
420424
private languagePerId: ObjectMap<LanguageProvider>;
421425
private readonly disposables: Disposable[] = [];
422426

@@ -442,7 +446,6 @@ class TypeScriptServiceClientHost implements ITypescriptServiceClientHost {
442446
configFileWatcher.onDidChange(handleProjectChange, this, this.disposables);
443447

444448
this.client = new TypeScriptServiceClient(this, storagePath, globalState, workspaceState, this.disposables);
445-
this.languages = [];
446449
this.languagePerId = Object.create(null);
447450
for (const description of descriptions) {
448451
const manager = new LanguageProvider(this.client, description);

0 commit comments

Comments
 (0)