diff --git a/src/vs/editor/contrib/quickAccess/editorNavigationQuickAccess.ts b/src/vs/editor/contrib/quickAccess/editorNavigationQuickAccess.ts index 5fcd0072247844731277757616c8f978ab9ffd68..d4756234321fc8553bac120ce5ae3f10905100c4 100644 --- a/src/vs/editor/contrib/quickAccess/editorNavigationQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/editorNavigationQuickAccess.ts @@ -22,6 +22,10 @@ interface IEditorLineDecoration { overviewRulerDecorationId: string; } +export interface IEditorNavigationQuickAccessOptions { + canAcceptInBackground?: boolean; +} + /** * A reusable quick access provider for the editor with support * for adding decorations for navigating in the currently active file @@ -29,11 +33,16 @@ interface IEditorLineDecoration { */ export abstract class AbstractEditorNavigationQuickAccessProvider implements IQuickAccessProvider { + constructor(protected options?: IEditorNavigationQuickAccessOptions) { } + //#region Provider methods provide(picker: IQuickPick, token: CancellationToken): IDisposable { const disposables = new DisposableStore(); + // Apply options if any + picker.canAcceptInBackground = !!this.options?.canAcceptInBackground; + // Disable filtering & sorting, we control the results picker.matchOnLabel = picker.matchOnDescription = picker.matchOnDetail = picker.sortByLabel = false; @@ -110,10 +119,12 @@ export abstract class AbstractEditorNavigationQuickAccessProvider implements IQu */ protected abstract provideWithoutTextEditor(picker: IQuickPick, token: CancellationToken): IDisposable; - protected gotoLocation(editor: IEditor, options: { range: IRange, keyMods: IKeyMods, forceSideBySide?: boolean }): void { + protected gotoLocation(editor: IEditor, options: { range: IRange, keyMods: IKeyMods, forceSideBySide?: boolean, preserveFocus?: boolean }): void { editor.setSelection(options.range); editor.revealRangeInCenter(options.range, ScrollType.Smooth); - editor.focus(); + if (!options.preserveFocus) { + editor.focus(); + } } protected getModel(editor: IEditor | IDiffEditor): ITextModel | undefined { diff --git a/src/vs/editor/contrib/quickAccess/gotoLineQuickAccess.ts b/src/vs/editor/contrib/quickAccess/gotoLineQuickAccess.ts index 835b99d634db37cdfbc8fc91e5451db190d0c269..555dd0192944b16805b22472a0887198f34a273c 100644 --- a/src/vs/editor/contrib/quickAccess/gotoLineQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/gotoLineQuickAccess.ts @@ -18,6 +18,10 @@ export abstract class AbstractGotoLineQuickAccessProvider extends AbstractEditor static PREFIX = ':'; + constructor() { + super({ canAcceptInBackground: true }); + } + protected provideWithoutTextEditor(picker: IQuickPick): IDisposable { const label = localize('cannotRunGotoLine', "Open a text editor first to go to a line."); @@ -31,16 +35,18 @@ export abstract class AbstractGotoLineQuickAccessProvider extends AbstractEditor const disposables = new DisposableStore(); // Goto line once picked - disposables.add(picker.onDidAccept(() => { + disposables.add(picker.onDidAccept(event => { const [item] = picker.selectedItems; if (item) { if (!this.isValidLineNumber(editor, item.lineNumber)) { return; } - this.gotoLocation(editor, { range: this.toRange(item.lineNumber, item.column), keyMods: picker.keyMods }); + this.gotoLocation(editor, { range: this.toRange(item.lineNumber, item.column), keyMods: picker.keyMods, preserveFocus: event.inBackground }); - picker.hide(); + if (!event.inBackground) { + picker.hide(); + } } })); diff --git a/src/vs/editor/contrib/quickAccess/gotoSymbolQuickAccess.ts b/src/vs/editor/contrib/quickAccess/gotoSymbolQuickAccess.ts index 60ac2ca94643eda505e8df21673c3c41f4bf6e83..3c7185513564eb16f0f73db072b796ea28711e4f 100644 --- a/src/vs/editor/contrib/quickAccess/gotoSymbolQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/gotoSymbolQuickAccess.ts @@ -10,12 +10,13 @@ import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecyc import { IEditor, ScrollType } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { IRange, Range } from 'vs/editor/common/core/range'; -import { AbstractEditorNavigationQuickAccessProvider } from 'vs/editor/contrib/quickAccess/editorNavigationQuickAccess'; +import { AbstractEditorNavigationQuickAccessProvider, IEditorNavigationQuickAccessOptions } from 'vs/editor/contrib/quickAccess/editorNavigationQuickAccess'; import { DocumentSymbol, SymbolKinds, SymbolTag, DocumentSymbolProviderRegistry, SymbolKind } from 'vs/editor/common/modes'; import { OutlineModel, OutlineElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { values } from 'vs/base/common/collections'; import { trim, format } from 'vs/base/common/strings'; import { fuzzyScore, FuzzyScore, createMatches } from 'vs/base/common/filters'; +import { assign } from 'vs/base/common/objects'; interface IGotoSymbolQuickPickItem extends IQuickPickItem { kind: SymbolKind, @@ -24,7 +25,7 @@ interface IGotoSymbolQuickPickItem extends IQuickPickItem { range?: { decoration: IRange, selection: IRange }, } -export interface IGotoSymbolQuickAccessProviderOptions { +export interface IGotoSymbolQuickAccessProviderOptions extends IEditorNavigationQuickAccessOptions { openSideBySideDirection: () => undefined | 'right' | 'down' } @@ -34,8 +35,8 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit static SCOPE_PREFIX = ':'; static PREFIX_BY_CATEGORY = `${AbstractGotoSymbolQuickAccessProvider.PREFIX}${AbstractGotoSymbolQuickAccessProvider.SCOPE_PREFIX}`; - constructor(private options?: IGotoSymbolQuickAccessProviderOptions) { - super(); + constructor(protected options?: IGotoSymbolQuickAccessProviderOptions) { + super(assign(options, { canAcceptInBackground: true })); } protected provideWithoutTextEditor(picker: IQuickPick): IDisposable { @@ -92,12 +93,14 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit const disposables = new DisposableStore(); // Goto symbol once picked - disposables.add(picker.onDidAccept(() => { + disposables.add(picker.onDidAccept(event => { const [item] = picker.selectedItems; if (item && item.range) { - this.gotoLocation(editor, { range: item.range.selection, keyMods: picker.keyMods }); + this.gotoLocation(editor, { range: item.range.selection, keyMods: picker.keyMods, preserveFocus: event.inBackground }); - picker.hide(); + if (!event.inBackground) { + picker.hide(); + } } })); diff --git a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts index 3087dfeb240243986a87aaa4b92f23abdcc8ad83..4b2a6cb01fe6cc2e3c705e689505ff205e35b1d2 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts @@ -37,13 +37,14 @@ export class GotoLineQuickAccessProvider extends AbstractGotoLineQuickAccessProv return this.editorService.activeTextEditorControl; } - protected gotoLocation(editor: IEditor, options: { range: IRange, keyMods: IKeyMods, forceSideBySide?: boolean }): void { + protected gotoLocation(editor: IEditor, options: { range: IRange, keyMods: IKeyMods, forceSideBySide?: boolean, preserveFocus?: boolean }): void { // Check for sideBySide use if ((options.keyMods.ctrlCmd || options.forceSideBySide) && this.editorService.activeEditor) { this.editorService.openEditor(this.editorService.activeEditor, { selection: options.range, - pinned: options.keyMods.alt || this.configuration.openEditorPinned + pinned: options.keyMods.alt || this.configuration.openEditorPinned, + preserveFocus: options.preserveFocus }, SIDE_GROUP); } diff --git a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts index acff6f07b5519e92a8ed5ac1fffd818e4e6d6fd0..f85d3f139c6db81ac2a529443927b6f5e3b4f9aa 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts @@ -40,13 +40,14 @@ export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccess return this.editorService.activeTextEditorControl; } - protected gotoLocation(editor: IEditor, options: { range: IRange, keyMods: IKeyMods, forceSideBySide?: boolean }): void { + protected gotoLocation(editor: IEditor, options: { range: IRange, keyMods: IKeyMods, forceSideBySide?: boolean, preserveFocus?: boolean }): void { // Check for sideBySide use if ((options.keyMods.ctrlCmd || options.forceSideBySide) && this.editorService.activeEditor) { this.editorService.openEditor(this.editorService.activeEditor, { selection: options.range, - pinned: options.keyMods.alt || this.configuration.openEditorPinned + pinned: options.keyMods.alt || this.configuration.openEditorPinned, + preserveFocus: options.preserveFocus }, SIDE_GROUP); }