Skip to content

Commit

Permalink
#19733 Implement intellisense for language specific editor settings i…
Browse files Browse the repository at this point in the history
…n configuration defaults
  • Loading branch information
sandy081 committed Feb 9, 2017
1 parent b548527 commit 7656384
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
5 changes: 5 additions & 0 deletions extensions/extension-editing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@
"Other"
],
"activationEvents": [
"onLanguage:json",
"onLanguage:typescript"
],
"main": "./out/extension",
"scripts": {
"compile": "gulp compile-extension:extension-editing",
"watch": "gulp watch-extension:extension-editing"
},
"dependencies": {
"jsonc-parser": "^0.3.1",
"vscode-nls": "^2.0.1"
},
"contributes": {
"jsonValidation": [
{
Expand Down
12 changes: 12 additions & 0 deletions extensions/extension-editing/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@

import * as vscode from 'vscode';
import * as ts from 'typescript';
import { PackageDocument } from './packageDocumentHelper';

export function activate(context: vscode.ExtensionContext) {
const registration = vscode.languages.registerDocumentLinkProvider({ language: 'typescript', pattern: '**/vscode.d.ts' }, _linkProvider);
context.subscriptions.push(registration);

//package.json suggestions
context.subscriptions.push(registerPackageDocumentCompletions());
}

const _linkProvider = new class implements vscode.DocumentLinkProvider {
Expand Down Expand Up @@ -101,3 +105,11 @@ namespace ast {
};
}
}

function registerPackageDocumentCompletions(): vscode.Disposable {
return vscode.languages.registerCompletionItemProvider({ language: 'json', pattern: '**/**/package.json' }, {
provideCompletionItems(document, position, token) {
return new PackageDocument(document).provideCompletionItems(position, token);
}
});
}
84 changes: 84 additions & 0 deletions extensions/extension-editing/src/packageDocumentHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import { getLocation, Location } from 'jsonc-parser';
import * as nls from 'vscode-nls';

const localize = nls.loadMessageBundle();

export class PackageDocument {

constructor(private document: vscode.TextDocument) { }

public provideCompletionItems(position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CompletionItem[]> {
const location = getLocation(this.document.getText(), this.document.offsetAt(position));

if (location.path.length >= 2 && location.path[1] === 'configurationDefaults') {
return this.provideLanguageOverridesCompletionItems(location, position);
}

}

private provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): vscode.ProviderResult<vscode.CompletionItem[]> {
let range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
const text = this.document.getText(range);

if (location.path.length === 2) {

let snippet = '"[${1:language}]": {\n\t"$0"\n}';

// Suggestion model word matching includes quotes,
// hence exclude the starting quote from the snippet and the range
// ending quote gets replaced
if (text.startsWith('"')) {
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 1), range.end);
snippet = snippet.substring(1);
}

return Promise.resolve([this.newSnippetCompletionItem({
label: localize('languageSpecificEditorSettings', "Language specific editor settings"),
documentation: localize('languageSpecificEditorSettingsDescription', "Override editor settings for language"),
snippet,
range
})]);
}

if (location.path.length === 3 && location.previousNode && location.previousNode.value.startsWith('[')) {

// Suggestion model word matching includes starting quote and open sqaure bracket
// Hence exclude them from the proposal range
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 2), range.end);

return vscode.languages.getLanguages().then(languages => {
return languages.map(l => {

// Suggestion model word matching includes closed sqaure bracket and ending quote
// Hence include them in the proposal to replace
return this.newSimpleCompletionItem(l, range, '', l + ']"');
});
});
}
return Promise.resolve([]);
}

private newSimpleCompletionItem(text: string, range: vscode.Range, description?: string, insertText?: string): vscode.CompletionItem {
const item = new vscode.CompletionItem(text);
item.kind = vscode.CompletionItemKind.Value;
item.detail = description;
item.insertText = insertText ? insertText : text;
item.range = range;
return item;
}

private newSnippetCompletionItem(o: { label: string; documentation?: string; snippet: string; range: vscode.Range; }): vscode.CompletionItem {
const item = new vscode.CompletionItem(o.label);
item.kind = vscode.CompletionItemKind.Value;
item.documentation = o.documentation;
item.insertText = new vscode.SnippetString(o.snippet);
item.range = o.range;
return item;
}
}

0 comments on commit 7656384

Please sign in to comment.