diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index debb1a0468589..e777dabba9e04 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -690,6 +690,8 @@ export class AsyncDataTree implements IDisposable } openFind(): void { + // Until #212077, set to filter so behavior is consistent with filter widget + this.tree.findMode = TreeFindMode.Filter; this.tree.openFind(); } diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index e76870f5b7181..2085ef43cf330 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -56,7 +56,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { editorForeground, resolveColorValue } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { FilterViewPane, IViewPaneOptions, ViewAction } from 'vs/workbench/browser/parts/views/viewPane'; +import { IViewPaneOptions, ViewAction, ViewPane } from 'vs/workbench/browser/parts/views/viewPane'; import { IViewDescriptorService } from 'vs/workbench/common/views'; import { IViewsService } from 'vs/workbench/services/views/common/viewsService'; import { getSimpleCodeEditorWidgetOptions, getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; @@ -74,11 +74,11 @@ import { AccessibilitySignal, IAccessibilitySignalService } from 'vs/platform/ac import { IHoverService } from 'vs/platform/hover/browser/hover'; import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; +import { Codicon } from 'vs/base/common/codicons'; const $ = dom.$; const HISTORY_STORAGE_KEY = 'debug.repl.history'; -const FILTER_HISTORY_STORAGE_KEY = 'debug.repl.filterHistory'; const FILTER_VALUE_STORAGE_KEY = 'debug.repl.filterValue'; const DECORATION_KEY = 'replinputdecoration'; @@ -90,7 +90,7 @@ function revealLastElement(tree: WorkbenchAsyncDataTree) { const sessionsToIgnore = new Set(); const identityProvider = { getId: (element: IReplElement) => element.getId() }; -export class Repl extends FilterViewPane implements IHistoryNavigationWidget { +export class Repl extends ViewPane implements IHistoryNavigationWidget { declare readonly _serviceBrand: undefined; private static readonly REFRESH_DELAY = 50; // delay in ms to refresh the repl for new elements to show @@ -119,6 +119,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { private multiSessionRepl: IContextKey; private menu: IMenu; private replDataSource: IAsyncDataSource | undefined; + private findIsOpen: boolean = false; constructor( options: IViewPaneOptions, @@ -131,10 +132,10 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { @ICodeEditorService codeEditorService: ICodeEditorService, @IViewDescriptorService viewDescriptorService: IViewDescriptorService, @IContextMenuService contextMenuService: IContextMenuService, - @IConfigurationService protected override readonly configurationService: IConfigurationService, + @IConfigurationService configurationService: IConfigurationService, @ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService, @IEditorService private readonly editorService: IEditorService, - @IKeybindingService protected override readonly keybindingService: IKeybindingService, + @IKeybindingService keybindingService: IKeybindingService, @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, @IHoverService hoverService: IHoverService, @@ -143,14 +144,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { @ILogService private readonly logService: ILogService, ) { const filterText = storageService.get(FILTER_VALUE_STORAGE_KEY, StorageScope.WORKSPACE, ''); - super({ - ...options, - filterOptions: { - placeholder: localize({ key: 'workbench.debug.filter.placeholder', comment: ['Text in the brackets after e.g. is not localizable'] }, "Filter (e.g. text, !exclude, \\escape)"), - text: filterText, - history: JSON.parse(storageService.get(FILTER_HISTORY_STORAGE_KEY, StorageScope.WORKSPACE, '[]')) as string[], - } - }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService); this.menu = menuService.createMenu(MenuId.DebugConsoleContext, contextKeyService); this._register(this.menu); @@ -230,14 +224,6 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { this._register(this.editorService.onDidActiveEditorChange(() => { this.setMode(); })); - - this._register(this.filterWidget.onDidChangeFilterText(() => { - this.filter.filterQuery = this.filterWidget.getFilterText(); - if (this.tree) { - this.tree.refilter(); - revealLastElement(this.tree); - } - })); } private async onDidFocusSession(session: IDebugSession | undefined): Promise { @@ -344,8 +330,8 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { } } - focusFilter(): void { - this.filterWidget.focus(); + openFind(): void { + this.tree?.openFind(); } private setMode(): void { @@ -396,7 +382,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { this.tree?.rerender(); if (this.bodyContentDimension) { - this.layoutBodyContent(this.bodyContentDimension.height, this.bodyContentDimension.width); + this.layoutBody(this.bodyContentDimension.height, this.bodyContentDimension.width); } } } @@ -470,7 +456,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { this.replInputLineCount = 1; if (shouldRelayout && this.bodyContentDimension) { // Trigger a layout to shrink a potential multi line input - this.layoutBodyContent(this.bodyContentDimension.height, this.bodyContentDimension.width); + this.layoutBody(this.bodyContentDimension.height, this.bodyContentDimension.width); } } } @@ -504,7 +490,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { return removeAnsiEscapeCodes(text); } - protected layoutBodyContent(height: number, width: number): void { + protected override layoutBody(height: number, width: number): void { this.bodyContentDimension = new dom.Dimension(width, height); const replInputHeight = Math.min(this.replInput.getContentHeight(), height); if (this.tree) { @@ -598,9 +584,6 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { }; await autoExpandElements(session.getReplElements()); } - // Repl elements count changed, need to update filter stats on the badge - const { total, filtered } = this.getFilterStats(); - this.filterWidget.updateBadge(total === filtered || total === 0 ? undefined : localize('showing filtered repl lines', "Showing {0} of {1}", filtered, total)); }, Repl.REFRESH_DELAY); } @@ -610,10 +593,10 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { super.render(); this._register(registerNavigableContainer({ name: 'repl', - focusNotifiers: [this, this.filterWidget], + focusNotifiers: [this], focusNextWidget: () => { const element = this.tree?.getHTMLElement(); - if (this.filterWidget.hasFocus()) { + if (this.findIsOpen) { this.tree?.domFocus(); } else if (element && dom.isActiveElement(element)) { this.focus(); @@ -624,7 +607,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { if (this.replInput.hasTextFocus()) { this.tree?.domFocus(); } else if (element && dom.isActiveElement(element)) { - this.focusFilter(); + this.openFind(); } } })); @@ -664,7 +647,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { accessibilityProvider: new ReplAccessibilityProvider(), identityProvider, mouseSupport: false, - findWidgetEnabled: false, + findWidgetEnabled: true, keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IReplElement) => e.toString(true) }, horizontalScrolling: !wordWrap, setRowLineHeight: false, @@ -689,11 +672,16 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { })); this._register(tree.onContextMenu(e => this.onContextMenu(e))); + this._register(tree.onDidChangeFindOpenState((open) => this.findIsOpen = open)); + let lastSelectedString: string; this._register(tree.onMouseClick(() => { + if (this.findIsOpen) { + return; + } const selection = dom.getWindow(this.treeContainer).getSelection(); if (!selection || selection.type !== 'Range' || lastSelectedString === selection.toString()) { - // only focus the input if the user is not currently selecting. + // only focus the input if the user is not currently selecting and find isn't open. this.replInput.focus(); } lastSelectedString = selection ? selection.toString() : ''; @@ -732,7 +720,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { if (lineCount !== this.replInputLineCount) { this.replInputLineCount = lineCount; if (this.bodyContentDimension) { - this.layoutBodyContent(this.bodyContentDimension.height, this.bodyContentDimension.width); + this.layoutBody(this.bodyContentDimension.height, this.bodyContentDimension.width); } } })); @@ -815,19 +803,6 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { } else { this.storageService.remove(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE); } - const filterHistory = this.filterWidget.getHistory(); - if (filterHistory.length) { - this.storageService.store(FILTER_HISTORY_STORAGE_KEY, JSON.stringify(filterHistory), StorageScope.WORKSPACE, StorageTarget.MACHINE); - } else { - this.storageService.remove(FILTER_HISTORY_STORAGE_KEY, StorageScope.WORKSPACE); - } - const filterValue = this.filterWidget.getFilterText(); - if (filterValue) { - this.storageService.store(FILTER_VALUE_STORAGE_KEY, filterValue, StorageScope.WORKSPACE, StorageTarget.MACHINE); - } else { - this.storageService.remove(FILTER_VALUE_STORAGE_KEY, StorageScope.WORKSPACE); - } - super.saveState(); } @@ -913,25 +888,36 @@ class AcceptReplInputAction extends EditorAction { } } -class FilterReplAction extends EditorAction { +class FilterReplAction extends ViewAction { constructor() { super({ - id: 'repl.action.filter', - label: localize('repl.action.filter', "Debug Console: Focus Filter"), - alias: 'Debug Console: Focus Filter', - precondition: CONTEXT_IN_DEBUG_REPL, - kbOpts: { - kbExpr: EditorContextKeys.textInputFocus, + viewId: REPL_VIEW_ID, + id: 'repl.action.find', + title: localize('repl.action.find', "Debug Console: Focus Find"), + precondition: ContextKeyExpr.or(CONTEXT_IN_DEBUG_REPL, ContextKeyExpr.equals('focusedView', 'workbench.panel.repl.view')), + keybinding: [{ + when: ContextKeyExpr.or(CONTEXT_IN_DEBUG_REPL, ContextKeyExpr.equals('focusedView', 'workbench.panel.repl.view')), primary: KeyMod.CtrlCmd | KeyCode.KeyF, - weight: KeybindingWeight.EditorContrib - } + // override the editor's find + weight: KeybindingWeight.EditorContrib + 10 + }], + icon: Codicon.search, + menu: [{ + id: MenuId.ViewTitle, + group: 'navigation', + when: ContextKeyExpr.equals('view', REPL_VIEW_ID), + order: 10 + }, { + id: MenuId.DebugConsoleContext, + group: 'z_commands', + order: 20 + }], }); } - run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise { - const repl = getReplView(accessor.get(IViewsService)); - repl?.focusFilter(); + runInView(accessor: ServicesAccessor, view: Repl): void | Promise { + view.openFind(); } } @@ -957,7 +943,7 @@ class ReplCopyAllAction extends EditorAction { registerEditorAction(AcceptReplInputAction); registerEditorAction(ReplCopyAllAction); -registerEditorAction(FilterReplAction); +registerAction2(FilterReplAction); class SelectReplActionViewItem extends FocusSessionActionViewItem {