diff --git a/package.json b/package.json index dacf285dc..a871960c0 100644 --- a/package.json +++ b/package.json @@ -587,6 +587,16 @@ "default": true, "description": "Specifes whether OmniSharp should use VS Code editor settings for C# code formatting (use of tabs, indentation size)." }, + "omnisharp.minFindSymbolsFilterLength": { + "type": "number", + "default": 0, + "description": "The minimum number of characters to enter before 'Go to Symbol in Workspace' operation shows any results." + }, + "omnisharp.maxFindSymbolsItems": { + "type": "number", + "default": 1000, + "description": "The maximum number of items that 'Go to Symbol in Workspace' operation can show. The limit is applied only when a positive number is specified here." + }, "omnisharp.disableMSBuildDiagnosticWarning": { "type": "boolean", "default": false, diff --git a/src/features/workspaceSymbolProvider.ts b/src/features/workspaceSymbolProvider.ts index 37ddb5aaf..d7e76ede6 100644 --- a/src/features/workspaceSymbolProvider.ts +++ b/src/features/workspaceSymbolProvider.ts @@ -1,56 +1,65 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import AbstractSupport from './abstractProvider'; -import * as protocol from '../omnisharp/protocol'; -import * as serverUtils from '../omnisharp/utils'; -import {toRange} from '../omnisharp/typeConvertion'; -import {CancellationToken, Uri, WorkspaceSymbolProvider, SymbolInformation, SymbolKind} from 'vscode'; - - -export default class OmnisharpWorkspaceSymbolProvider extends AbstractSupport implements WorkspaceSymbolProvider { - - public async provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { - - return serverUtils.findSymbols(this._server, { Filter: search, FileName: '' }, token).then(res => { - if (res && Array.isArray(res.QuickFixes)) { - return res.QuickFixes.map(OmnisharpWorkspaceSymbolProvider._asSymbolInformation); - } - }); - } - - private static _asSymbolInformation(symbolInfo: protocol.SymbolLocation): SymbolInformation { - - return new SymbolInformation(symbolInfo.Text, OmnisharpWorkspaceSymbolProvider._toKind(symbolInfo), - toRange(symbolInfo), - Uri.file(symbolInfo.FileName)); - } - - private static _toKind(symbolInfo: protocol.SymbolLocation): SymbolKind { - switch (symbolInfo.Kind) { - case 'Method': - return SymbolKind.Method; - case 'Field': - return SymbolKind.Field; - case 'Property': - return SymbolKind.Property; - case 'Interface': - return SymbolKind.Interface; - case 'Enum': - return SymbolKind.Enum; - case 'Struct': - return SymbolKind.Struct; - case 'Event': - return SymbolKind.Event; - case 'EnumMember': - return SymbolKind.EnumMember; - case 'Class': - return SymbolKind.Class; - default: - return SymbolKind.Class; - - } - } -} +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import AbstractSupport from './abstractProvider'; +import { OmniSharpServer } from '../omnisharp/server'; +import OptionProvider from '../observers/OptionProvider'; +import * as protocol from '../omnisharp/protocol'; +import * as serverUtils from '../omnisharp/utils'; +import {toRange} from '../omnisharp/typeConvertion'; +import {CancellationToken, Uri, WorkspaceSymbolProvider, SymbolInformation, SymbolKind} from 'vscode'; + + +export default class OmnisharpWorkspaceSymbolProvider extends AbstractSupport implements WorkspaceSymbolProvider { + + constructor(server: OmniSharpServer, private optionProvider: OptionProvider) { + super(server); + } + + public async provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { + + let options = this.optionProvider.GetLatestOptions(); + let minFilterLength = options.minFindSymbolsFilterLength > 0 ? options.minFindSymbolsFilterLength : undefined; + let maxItemsToReturn = options.maxFindSymbolsItems > 0 ? options.maxFindSymbolsItems : undefined; + return serverUtils.findSymbols(this._server, { Filter: search, MinFilterLength: minFilterLength, MaxItemsToReturn: maxItemsToReturn, FileName: '' }, token).then(res => { + if (res && Array.isArray(res.QuickFixes)) { + return res.QuickFixes.map(OmnisharpWorkspaceSymbolProvider._asSymbolInformation); + } + }); + } + + private static _asSymbolInformation(symbolInfo: protocol.SymbolLocation): SymbolInformation { + + return new SymbolInformation(symbolInfo.Text, OmnisharpWorkspaceSymbolProvider._toKind(symbolInfo), + toRange(symbolInfo), + Uri.file(symbolInfo.FileName)); + } + + private static _toKind(symbolInfo: protocol.SymbolLocation): SymbolKind { + switch (symbolInfo.Kind) { + case 'Method': + return SymbolKind.Method; + case 'Field': + return SymbolKind.Field; + case 'Property': + return SymbolKind.Property; + case 'Interface': + return SymbolKind.Interface; + case 'Enum': + return SymbolKind.Enum; + case 'Struct': + return SymbolKind.Struct; + case 'Event': + return SymbolKind.Event; + case 'EnumMember': + return SymbolKind.EnumMember; + case 'Class': + return SymbolKind.Class; + default: + return SymbolKind.Class; + + } + } +} diff --git a/src/omnisharp/extension.ts b/src/omnisharp/extension.ts index e59545141..dd823265b 100644 --- a/src/omnisharp/extension.ts +++ b/src/omnisharp/extension.ts @@ -77,7 +77,7 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an localDisposables.add(vscode.languages.registerOnTypeFormattingEditProvider(documentSelector, new FormatProvider(server), '}', ';')); } localDisposables.add(vscode.languages.registerCompletionItemProvider(documentSelector, new CompletionItemProvider(server), '.', ' ')); - localDisposables.add(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server))); + localDisposables.add(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server, optionProvider))); localDisposables.add(vscode.languages.registerSignatureHelpProvider(documentSelector, new SignatureHelpProvider(server), '(', ',')); const codeActionProvider = new CodeActionProvider(server, optionProvider); localDisposables.add(codeActionProvider); diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index f38816d56..0f9dd1199 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -20,6 +20,8 @@ export class Options { public showTestsCodeLens: boolean, public disableCodeActions: boolean, public disableMSBuildDiagnosticWarning: boolean, + public minFindSymbolsFilterLength: number, + public maxFindSymbolsItems: number, public defaultLaunchSolution?: string, public monoPath?: string) { } @@ -63,6 +65,9 @@ export class Options { const disableMSBuildDiagnosticWarning = omnisharpConfig.get('disableMSBuildDiagnosticWarning', false); + const minFindSymbolsFilterLength = omnisharpConfig.get('minFindSymbolsFilterLength', 0); + const maxFindSymbolsItems = omnisharpConfig.get('maxFindSymbolsItems', 1000); // The limit is applied only when this setting is set to a number greater than zero + return new Options( path, useGlobalMono, @@ -77,6 +82,8 @@ export class Options { showTestsCodeLens, disableCodeActions, disableMSBuildDiagnosticWarning, + minFindSymbolsFilterLength, + maxFindSymbolsItems, defaultLaunchSolution, monoPath, ); diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index d8f76da3f..fa2209db9 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -128,6 +128,8 @@ export interface FindUsagesRequest extends Request { export interface FindSymbolsRequest extends Request { Filter: string; + MinFilterLength?: number; + MaxItemsToReturn?: number; } export interface FormatRequest extends Request { diff --git a/test/unitTests/Fakes/FakeOptions.ts b/test/unitTests/Fakes/FakeOptions.ts index 4985f6b0b..961159379 100644 --- a/test/unitTests/Fakes/FakeOptions.ts +++ b/test/unitTests/Fakes/FakeOptions.ts @@ -6,5 +6,5 @@ import { Options } from "../../../src/omnisharp/options"; export function getEmptyOptions(): Options { - return new Options("", "", false, "", false, 0, 0, false, false, false, false, false, false, "", ""); + return new Options("", "", false, "", false, 0, 0, false, false, false, false, false, false, 0, 0, "", ""); } diff --git a/test/unitTests/optionStream.test.ts b/test/unitTests/optionStream.test.ts index 01478fccd..ea7b88569 100644 --- a/test/unitTests/optionStream.test.ts +++ b/test/unitTests/optionStream.test.ts @@ -49,7 +49,9 @@ suite('OptionStream', () => { options.showReferencesCodeLens.should.equal(true); options.showTestsCodeLens.should.equal(true); options.disableCodeActions.should.equal(false); - expect(options.defaultLaunchSolution).to.be.undefined; + options.minFindSymbolsFilterLength.should.equal(0); + options.maxFindSymbolsItems.should.equal(1000); + expect(options.defaultLaunchSolution).to.be.undefined; }); test('Gives the changed option when the omnisharp config changes', () => { diff --git a/test/unitTests/options.test.ts b/test/unitTests/options.test.ts index dd2166dca..f5e6c5c2a 100644 --- a/test/unitTests/options.test.ts +++ b/test/unitTests/options.test.ts @@ -28,6 +28,8 @@ suite("Options tests", () => { options.showTestsCodeLens.should.equal(true); options.disableCodeActions.should.equal(false); options.disableCodeActions.should.equal(false); + options.minFindSymbolsFilterLength.should.equal(0); + options.maxFindSymbolsItems.should.equal(1000); expect(options.defaultLaunchSolution).to.be.undefined; });