Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New completion service #3986

Merged
merged 7 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,11 @@
"scope": "machine",
"description": "Enables support for decompiling external references instead of viewing metadata."
},
"omnisharp.enableImportCompletion": {
"type": "boolean",
"default": false,
"description": "Enables support for showing unimported types and unimported extension methods in completion lists. When committed, the appropriate using directive will be added at the top of the current file. This option can have a negative impact on initial completion responsiveness, particularly for the first few completion sessions after opening a solution."
},
"razor.plugin.path": {
"type": [
"string",
Expand Down
137 changes: 0 additions & 137 deletions src/features/completionItemProvider.ts

This file was deleted.

93 changes: 93 additions & 0 deletions src/features/completionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { CompletionItemProvider, TextDocument, Position, CompletionContext, CompletionList, CompletionItem, MarkdownString, TextEdit, Range, SnippetString } from "vscode";
import AbstractProvider from "./abstractProvider";
import * as protocol from "../omnisharp/protocol";
import * as serverUtils from '../omnisharp/utils';
import { CancellationToken, CompletionTriggerKind as LspCompletionTriggerKind, InsertTextFormat } from "vscode-languageserver-protocol";
import { createRequest } from "../omnisharp/typeConversion";

export default class OmnisharpCompletionProvider extends AbstractProvider implements CompletionItemProvider {

#lastCompletions?: Map<CompletionItem, protocol.OmnisharpCompletionItem>;
333fred marked this conversation as resolved.
Show resolved Hide resolved

public async provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): Promise<CompletionList> {
let request = createRequest<protocol.CompletionRequest>(document, position);
request.CompletionTrigger = (context.triggerKind + 1) as LspCompletionTriggerKind;
request.TriggerCharacter = context.triggerCharacter;

try {
const response = await serverUtils.getCompletion(this._server, request, token);
const mappedItems = response.Items.map(this._convertToVscodeCompletionItem);

let lastCompletions = new Map();

for (let i = 0; i < mappedItems.length; i++) {
lastCompletions.set(mappedItems[i], response.Items[i]);
}

this.#lastCompletions = lastCompletions;

return { items: mappedItems };
}
catch (error) {
return;
}
}

public async resolveCompletionItem(item: CompletionItem, token: CancellationToken): Promise<CompletionItem> {
const lastCompletions = this.#lastCompletions;
if (!lastCompletions) {
return item;
}

const lspItem = lastCompletions.get(item);
if (!lspItem) {
return item;
}

const request: protocol.CompletionResolveRequest = { Item: lspItem };
try {
const response = await serverUtils.getCompletionResolve(this._server, request, token);
return this._convertToVscodeCompletionItem(response.Item);
}
catch (error) {
return;
}
}

private _convertToVscodeCompletionItem(omnisharpCompletion: protocol.OmnisharpCompletionItem): CompletionItem {
let docs: MarkdownString | undefined = omnisharpCompletion.Documentation ? new MarkdownString(omnisharpCompletion.Documentation, false) : undefined;

const mapTextEdit = function (edit: protocol.LinePositionSpanTextChange): TextEdit {
const newStart = new Position(edit.StartLine - 1, edit.StartColumn - 1);
const newEnd = new Position(edit.EndLine - 1, edit.EndColumn - 1);
const newRange = new Range(newStart, newEnd);
return new TextEdit(newRange, edit.NewText);
};

const additionalTextEdits = omnisharpCompletion.AdditionalTextEdits?.map(mapTextEdit);

const insertText = omnisharpCompletion.InsertTextFormat === InsertTextFormat.Snippet
? new SnippetString(omnisharpCompletion.InsertText)
: omnisharpCompletion.InsertText;

return {
label: omnisharpCompletion.Label,
kind: omnisharpCompletion.Kind - 1,
detail: omnisharpCompletion.Detail,
documentation: docs,
commitCharacters: omnisharpCompletion.CommitCharacters,
preselect: omnisharpCompletion.Preselect,
filterText: omnisharpCompletion.FilterText,
insertText: insertText,
tags: omnisharpCompletion.Tags,
sortText: omnisharpCompletion.SortText,
additionalTextEdits: additionalTextEdits,
keepWhitespace: true
};
}
}
3 changes: 2 additions & 1 deletion src/observers/OptionChangeObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const omniSharpOptions: ReadonlyArray<OptionsKey> = [
"waitForDebugger",
"loggingLevel",
"enableEditorConfigSupport",
"enableDecompilationSupport"
"enableDecompilationSupport",
"enableImportCompletion"
];

function OmniSharpOptionChangeObservable(optionObservable: Observable<Options>): Observable<Options> {
Expand Down
6 changes: 3 additions & 3 deletions src/omnisharp/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { safeLength, sum } from '../common';
import { CSharpConfigurationProvider } from '../configurationProvider';
import CodeActionProvider from '../features/codeActionProvider';
import CodeLensProvider from '../features/codeLensProvider';
import CompletionItemProvider from '../features/completionItemProvider';
import CompletionProvider from '../features/completionProvider';
import DefinitionMetadataDocumentProvider from '../features/definitionMetadataDocumentProvider';
import DefinitionProvider from '../features/definitionProvider';
import DocumentHighlightProvider from '../features/documentHighlightProvider';
Expand Down Expand Up @@ -90,7 +90,7 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an
localDisposables.add(vscode.languages.registerDocumentRangeFormattingEditProvider(documentSelector, new FormatProvider(server, languageMiddlewareFeature)));
localDisposables.add(vscode.languages.registerOnTypeFormattingEditProvider(documentSelector, new FormatProvider(server, languageMiddlewareFeature), '}', ';'));
}
localDisposables.add(vscode.languages.registerCompletionItemProvider(documentSelector, new CompletionItemProvider(server, languageMiddlewareFeature), '.', ' '));
localDisposables.add(vscode.languages.registerCompletionItemProvider(documentSelector, new CompletionProvider(server, languageMiddlewareFeature), '.', ' '));
localDisposables.add(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server, optionProvider, languageMiddlewareFeature)));
localDisposables.add(vscode.languages.registerSignatureHelpProvider(documentSelector, new SignatureHelpProvider(server, languageMiddlewareFeature), '(', ','));
// Since the CodeActionProvider registers its own commands, we must instantiate it and add it to the localDisposables
Expand Down Expand Up @@ -210,4 +210,4 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an
return new Promise<ActivationResult>(resolve =>
server.onServerStart(e =>
resolve({ server, advisor, testManager })));
}
}
5 changes: 4 additions & 1 deletion src/omnisharp/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class Options {
public enableRoslynAnalyzers: boolean,
public enableEditorConfigSupport: boolean,
public enableDecompilationSupport: boolean,
public enableImportCompletion: boolean,
public useSemanticHighlighting: boolean,
public razorPluginPath?: string,
public defaultLaunchSolution?: string,
Expand Down Expand Up @@ -70,6 +71,7 @@ export class Options {
const enableRoslynAnalyzers = omnisharpConfig.get<boolean>('enableRoslynAnalyzers', false);
const enableEditorConfigSupport = omnisharpConfig.get<boolean>('enableEditorConfigSupport', false);
const enableDecompilationSupport = omnisharpConfig.get<boolean>('enableDecompilationSupport', false);
const enableImportCompletion = omnisharpConfig.get<boolean>('enableImportCompletion', false);

const useFormatting = csharpConfig.get<boolean>('format.enable', true);

Expand Down Expand Up @@ -117,6 +119,7 @@ export class Options {
enableRoslynAnalyzers,
enableEditorConfigSupport,
enableDecompilationSupport,
enableImportCompletion,
useSemanticHighlighting,
razorPluginPath,
defaultLaunchSolution,
Expand Down Expand Up @@ -190,4 +193,4 @@ export class Options {
return "auto";
}
}
}
}
Loading