expose context key info command, add first version of completion item provider for package.json and keybindings.json files, https://github.com/microsoft/vscode/issues/9303

This commit is contained in:
Johannes Rieken 2021-02-17 11:52:11 +01:00
parent 44dbd18255
commit 13070015bd
3 changed files with 54 additions and 2 deletions

View file

@ -22,6 +22,9 @@ export function activate(context: vscode.ExtensionContext): void {
// task.json variable suggestions
context.subscriptions.push(registerVariableCompletions('**/tasks.json'));
// keybindings.json/package.json context key suggestions
context.subscriptions.push(registerContextKeyCompletions());
}
function registerSettingsCompletions(): vscode.Disposable {
@ -136,3 +139,40 @@ vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', lan
return result;
}
}, { label: 'Launch Targets' });
function registerContextKeyCompletions(): vscode.Disposable {
type ContextKeyInfo = { key: string, type?: string, description?: string };
return vscode.languages.registerCompletionItemProvider(
[{ language: 'json', pattern: '**/package.json' }, { language: 'jsonc', pattern: '**/keybindings.json' }],
{
async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
const replacing = document.getWordRangeAtPosition(position, /[\w.-\d]/);
const inserting = replacing?.with(undefined, position);
if (!replacing || !inserting) {
return;
}
const location = getLocation(document.getText(), document.offsetAt(position));
if (!location.matches(['*', 'when']) && !location.matches(['contributes', 'menus', '*', '*', 'when'])) {
return;
}
const data = await vscode.commands.executeCommand<ContextKeyInfo[]>('getContextKeyInfo');
if (token.isCancellationRequested || !data) {
return;
}
const result = new vscode.CompletionList();
for (const item of data) {
const completion = new vscode.CompletionItem(item.key, vscode.CompletionItemKind.Constant);
completion.detail = item.type;
completion.range = { replacing, inserting };
completion.documentation = item.description;
result.items.push(completion);
}
return result;
}
}
);
}

View file

@ -8,6 +8,7 @@ import { Iterable } from 'vs/base/common/iterator';
import { IDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
import { TernarySearchTree } from 'vs/base/common/map';
import { distinct } from 'vs/base/common/objects';
import { localize } from 'vs/nls';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContext, IContextKey, IContextKeyChangeEvent, IContextKeyService, IContextKeyServiceTarget, IReadableSet, SET_CONTEXT_COMMAND_ID, ContextKeyExpression, RawContextKey, ContextKeyInfo } from 'vs/platform/contextkey/common/contextkey';
@ -578,6 +579,17 @@ CommandsRegistry.registerCommand(SET_CONTEXT_COMMAND_ID, function (accessor, con
accessor.get(IContextKeyService).createKey(String(contextKey), contextValue);
});
CommandsRegistry.registerCommand({
id: 'getContextKeyInfo',
handler() {
return [...RawContextKey.all()].sort((a, b) => a.key.localeCompare(b.key));
},
description: {
description: localize('getContextKeyInfo', "A command that returns information about context keys"),
args: []
}
});
CommandsRegistry.registerCommand('_generateContextKeyInfo', function () {
const result: ContextKeyInfo[] = [];
const seen = new Set<string>();

View file

@ -1259,7 +1259,7 @@ export class ContextKeyOrExpr implements IContextKeyExpression {
export interface ContextKeyInfo {
readonly key: string;
readonly type: string;
readonly type?: string;
readonly description?: string;
}
@ -1281,7 +1281,7 @@ export class RawContextKey<T> extends ContextKeyDefinedExpr {
if (typeof metaOrHide === 'object') {
RawContextKey._info.push({ ...metaOrHide, key });
} else if (metaOrHide !== true) {
RawContextKey._info.push({ key, description: metaOrHide, type: typeof defaultValue });
RawContextKey._info.push({ key, description: metaOrHide, type: defaultValue !== null && defaultValue !== undefined ? typeof defaultValue : undefined });
}
}