diff --git a/src/vs/editor/contrib/gotoSymbol/goToCommands.ts b/src/vs/editor/contrib/gotoSymbol/goToCommands.ts index 587e4d4ec3ad3..4d0426f40f65a 100644 --- a/src/vs/editor/contrib/gotoSymbol/goToCommands.ts +++ b/src/vs/editor/contrib/gotoSymbol/goToCommands.ts @@ -8,7 +8,7 @@ import { createCancelablePromise, raceCancellation } from 'vs/base/common/async' import { CancellationToken } from 'vs/base/common/cancellation'; import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { isWeb } from 'vs/base/common/platform'; -import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, isCodeEditor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, IActionOptions, registerEditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import * as corePosition from 'vs/editor/common/core/position'; @@ -35,9 +35,9 @@ import { isStandalone } from 'vs/base/browser/browser'; import { URI } from 'vs/base/common/uri'; export interface SymbolNavigationActionConfig { - openToSide: boolean;// = false - openInPeek: boolean;// = false - muteMessage: boolean;// = true + openToSide: boolean; + openInPeek: boolean; + muteMessage: boolean; } abstract class SymbolNavigationAction extends EditorAction { @@ -69,8 +69,10 @@ abstract class SymbolNavigationAction extends EditorAction { return; } - const referenceUnderCusor = references.referenceAt(model.uri, pos); + alert(references.ariaMessage); + const referenceCount = references.references.length; + const altAction = references.referenceAt(model.uri, pos) && editor.getAction(this._getAlternativeCommand()); if (referenceCount === 0) { // no result -> show message @@ -78,12 +80,12 @@ abstract class SymbolNavigationAction extends EditorAction { const info = model.getWordAtPosition(pos); MessageController.get(editor).showMessage(this._getNoResultFoundMessage(info), pos); } - } else if (referenceCount === 1 && referenceUnderCusor) { - // only the position at which we are -> adjust selection - return this._openReference(editor, editorService, referenceUnderCusor, false).then(() => undefined); + } else if (referenceCount === 1 && altAction) { + // already at the only result, run alternative + altAction.run(); } else { - // handle multile results + // normal results handling return this._onResult(editorService, symbolNavService, editor, references); } @@ -104,20 +106,16 @@ abstract class SymbolNavigationAction extends EditorAction { protected abstract _getMetaTitle(model: ReferencesModel): string; - private async _onResult(editorService: ICodeEditorService, symbolNavService: ISymbolNavigationService, editor: ICodeEditor, model: ReferencesModel): Promise { + protected abstract _getAlternativeCommand(): string; - const msg = model.getAriaMessage(); - alert(msg); + private async _onResult(editorService: ICodeEditorService, symbolNavService: ISymbolNavigationService, editor: IActiveCodeEditor, model: ReferencesModel): Promise { const gotoLocation = editor.getOption(EditorOption.gotoLocation); if (this._configuration.openInPeek || (gotoLocation.multiple === 'peek' && model.references.length > 1)) { this._openInPeek(editorService, editor, model); - } else if (editor.hasModel()) { - const next = model.firstReference(); - if (!next) { - return; - } + } else { + const next = model.firstReference()!; const targetEditor = await this._openReference(editor, editorService, next, this._configuration.openToSide); if (targetEditor && model.references.length > 1 && gotoLocation.multiple === 'gotoAndPeek') { this._openInPeek(editorService, targetEditor, model); @@ -188,6 +186,10 @@ export class DefinitionAction extends SymbolNavigationAction { protected _getMetaTitle(model: ReferencesModel): string { return model.references.length > 1 ? nls.localize('meta.title', " – {0} definitions", model.references.length) : ''; } + + protected _getAlternativeCommand(): string { + return 'editor.action.referenceSearch.trigger'; + } } const goToDefinitionKb = isWeb && !isStandalone @@ -307,6 +309,10 @@ class DeclarationAction extends SymbolNavigationAction { protected _getMetaTitle(model: ReferencesModel): string { return model.references.length > 1 ? nls.localize('decl.meta.title', " – {0} declarations", model.references.length) : ''; } + + protected _getAlternativeCommand(): string { + return 'editor.action.referenceSearch.trigger'; + } } registerEditorAction(class GoToDeclarationAction extends DeclarationAction { @@ -367,28 +373,32 @@ registerEditorAction(class PeekDeclarationAction extends DeclarationAction { //#endregion -//#region --- IMPLEMENTATION +//#region --- TYPE DEFINITION -class ImplementationAction extends SymbolNavigationAction { +class TypeDefinitionAction extends SymbolNavigationAction { protected async _getLocationModel(model: ITextModel, position: corePosition.Position, token: CancellationToken): Promise { - return new ReferencesModel(await getImplementationsAtPosition(model, position, token)); + return new ReferencesModel(await getTypeDefinitionsAtPosition(model, position, token)); } protected _getNoResultFoundMessage(info: IWordAtPosition | null): string { return info && info.word - ? nls.localize('goToImplementation.noResultWord', "No implementation found for '{0}'", info.word) - : nls.localize('goToImplementation.generic.noResults', "No implementation found"); + ? nls.localize('goToTypeDefinition.noResultWord', "No type definition found for '{0}'", info.word) + : nls.localize('goToTypeDefinition.generic.noResults', "No type definition found"); } protected _getMetaTitle(model: ReferencesModel): string { - return model.references.length > 1 ? nls.localize('meta.implementations.title', " – {0} implementations", model.references.length) : ''; + return model.references.length > 1 ? nls.localize('meta.typeDefinitions.title', " – {0} type definitions", model.references.length) : ''; + } + + protected _getAlternativeCommand(): string { + return 'editor.action.referenceSearch.trigger'; } } -registerEditorAction(class GoToImplementationAction extends ImplementationAction { +registerEditorAction(class GoToTypeDefinitionAction extends TypeDefinitionAction { - public static readonly ID = 'editor.action.goToImplementation'; + public static readonly ID = 'editor.action.goToTypeDefinition'; constructor() { super({ @@ -396,29 +406,34 @@ registerEditorAction(class GoToImplementationAction extends ImplementationAction openInPeek: false, muteMessage: false }, { - id: GoToImplementationAction.ID, - label: nls.localize('actions.goToImplementation.label', "Go to Implementation"), - alias: 'Go to Implementation', + id: GoToTypeDefinitionAction.ID, + label: nls.localize('actions.goToTypeDefinition.label', "Go to Type Definition"), + alias: 'Go to Type Definition', precondition: ContextKeyExpr.and( - EditorContextKeys.hasImplementationProvider, + EditorContextKeys.hasTypeDefinitionProvider, EditorContextKeys.isInEmbeddedEditor.toNegated()), kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, - primary: KeyMod.CtrlCmd | KeyCode.F12, + primary: 0, weight: KeybindingWeight.EditorContrib }, + menuOpts: { + group: 'navigation', + order: 1.4 + }, menubarOpts: { menuId: MenuId.MenubarGoMenu, group: '4_symbol_nav', - order: 4, title: nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation") + order: 3, + title: nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition") } }); } }); -registerEditorAction(class PeekImplementationAction extends ImplementationAction { +registerEditorAction(class PeekTypeDefinitionAction extends TypeDefinitionAction { - public static readonly ID = 'editor.action.peekImplementation'; + public static readonly ID = 'editor.action.peekTypeDefinition'; constructor() { super({ @@ -426,15 +441,15 @@ registerEditorAction(class PeekImplementationAction extends ImplementationAction openInPeek: true, muteMessage: false }, { - id: PeekImplementationAction.ID, - label: nls.localize('actions.peekImplementation.label', "Peek Implementation"), - alias: 'Peek Implementation', + id: PeekTypeDefinitionAction.ID, + label: nls.localize('actions.peekTypeDefinition.label', "Peek Type Definition"), + alias: 'Peek Type Definition', precondition: ContextKeyExpr.and( - EditorContextKeys.hasImplementationProvider, + EditorContextKeys.hasTypeDefinitionProvider, EditorContextKeys.isInEmbeddedEditor.toNegated()), kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F12, + primary: 0, weight: KeybindingWeight.EditorContrib } }); @@ -443,28 +458,32 @@ registerEditorAction(class PeekImplementationAction extends ImplementationAction //#endregion -//#region --- TYPE DEFINITION +//#region --- IMPLEMENTATION -class TypeDefinitionAction extends SymbolNavigationAction { +class ImplementationAction extends SymbolNavigationAction { protected async _getLocationModel(model: ITextModel, position: corePosition.Position, token: CancellationToken): Promise { - return new ReferencesModel(await getTypeDefinitionsAtPosition(model, position, token)); + return new ReferencesModel(await getImplementationsAtPosition(model, position, token)); } protected _getNoResultFoundMessage(info: IWordAtPosition | null): string { return info && info.word - ? nls.localize('goToTypeDefinition.noResultWord', "No type definition found for '{0}'", info.word) - : nls.localize('goToTypeDefinition.generic.noResults', "No type definition found"); + ? nls.localize('goToImplementation.noResultWord', "No implementation found for '{0}'", info.word) + : nls.localize('goToImplementation.generic.noResults', "No implementation found"); } protected _getMetaTitle(model: ReferencesModel): string { - return model.references.length > 1 ? nls.localize('meta.typeDefinitions.title', " – {0} type definitions", model.references.length) : ''; + return model.references.length > 1 ? nls.localize('meta.implementations.title', " – {0} implementations", model.references.length) : ''; + } + + protected _getAlternativeCommand(): string { + return ''; } } -registerEditorAction(class GoToTypeDefinitionAction extends TypeDefinitionAction { +registerEditorAction(class GoToImplementationAction extends ImplementationAction { - public static readonly ID = 'editor.action.goToTypeDefinition'; + public static readonly ID = 'editor.action.goToImplementation'; constructor() { super({ @@ -472,34 +491,29 @@ registerEditorAction(class GoToTypeDefinitionAction extends TypeDefinitionAction openInPeek: false, muteMessage: false }, { - id: GoToTypeDefinitionAction.ID, - label: nls.localize('actions.goToTypeDefinition.label', "Go to Type Definition"), - alias: 'Go to Type Definition', + id: GoToImplementationAction.ID, + label: nls.localize('actions.goToImplementation.label', "Go to Implementation"), + alias: 'Go to Implementation', precondition: ContextKeyExpr.and( - EditorContextKeys.hasTypeDefinitionProvider, + EditorContextKeys.hasImplementationProvider, EditorContextKeys.isInEmbeddedEditor.toNegated()), kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, - primary: 0, + primary: KeyMod.CtrlCmd | KeyCode.F12, weight: KeybindingWeight.EditorContrib }, - menuOpts: { - group: 'navigation', - order: 1.4 - }, menubarOpts: { menuId: MenuId.MenubarGoMenu, group: '4_symbol_nav', - order: 3, - title: nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition") + order: 4, title: nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementation") } }); } }); -registerEditorAction(class PeekTypeDefinitionAction extends TypeDefinitionAction { +registerEditorAction(class PeekImplementationAction extends ImplementationAction { - public static readonly ID = 'editor.action.peekTypeDefinition'; + public static readonly ID = 'editor.action.peekImplementation'; constructor() { super({ @@ -507,15 +521,15 @@ registerEditorAction(class PeekTypeDefinitionAction extends TypeDefinitionAction openInPeek: true, muteMessage: false }, { - id: PeekTypeDefinitionAction.ID, - label: nls.localize('actions.peekTypeDefinition.label', "Peek Type Definition"), - alias: 'Peek Type Definition', + id: PeekImplementationAction.ID, + label: nls.localize('actions.peekImplementation.label', "Peek Implementation"), + alias: 'Peek Implementation', precondition: ContextKeyExpr.and( - EditorContextKeys.hasTypeDefinitionProvider, + EditorContextKeys.hasImplementationProvider, EditorContextKeys.isInEmbeddedEditor.toNegated()), kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, - primary: 0, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F12, weight: KeybindingWeight.EditorContrib } }); @@ -543,6 +557,10 @@ class ReferencesAction extends SymbolNavigationAction { ? nls.localize('meta.titleReference', " – {0} references", model.references.length) : ''; } + + protected _getAlternativeCommand(): string { + return ''; + } } registerEditorAction(class GoToReferencesAction extends ReferencesAction { @@ -596,7 +614,7 @@ registerEditorAction(class PeekReferencesAction extends ReferencesAction { //#endregion -//#region ---- REFERENCE search special commands +//#region --- REFERENCE search special commands const defaultReferenceSearchOptions: RequestOptions = { getMetaTitle(model) { diff --git a/src/vs/editor/contrib/gotoSymbol/referencesModel.ts b/src/vs/editor/contrib/gotoSymbol/referencesModel.ts index 3afea1c285a8c..480bdb7508f64 100644 --- a/src/vs/editor/contrib/gotoSymbol/referencesModel.ts +++ b/src/vs/editor/contrib/gotoSymbol/referencesModel.ts @@ -192,7 +192,7 @@ export class ReferencesModel implements IDisposable { return this.groups.length === 0; } - getAriaMessage(): string { + get ariaMessage(): string { if (this.isEmpty) { return localize('aria.result.0', "No results found"); } else if (this.references.length === 1) {