mirror of
https://github.com/Microsoft/vscode
synced 2024-09-29 07:51:27 +00:00
enable find in the debug console (#225093)
This commit is contained in:
parent
de688270dd
commit
8f88d203d7
|
@ -690,6 +690,8 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
|||
}
|
||||
|
||||
openFind(): void {
|
||||
// Until #212077, set to filter so behavior is consistent with filter widget
|
||||
this.tree.findMode = TreeFindMode.Filter;
|
||||
this.tree.openFind();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<any, any, any>) {
|
|||
const sessionsToIgnore = new Set<IDebugSession>();
|
||||
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<boolean>;
|
||||
private menu: IMenu;
|
||||
private replDataSource: IAsyncDataSource<IDebugSession, IReplElement> | 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<void> {
|
||||
|
@ -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<Repl> {
|
||||
|
||||
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<void> {
|
||||
const repl = getReplView(accessor.get(IViewsService));
|
||||
repl?.focusFilter();
|
||||
runInView(accessor: ServicesAccessor, view: Repl): void | Promise<void> {
|
||||
view.openFind();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,7 +943,7 @@ class ReplCopyAllAction extends EditorAction {
|
|||
|
||||
registerEditorAction(AcceptReplInputAction);
|
||||
registerEditorAction(ReplCopyAllAction);
|
||||
registerEditorAction(FilterReplAction);
|
||||
registerAction2(FilterReplAction);
|
||||
|
||||
class SelectReplActionViewItem extends FocusSessionActionViewItem {
|
||||
|
||||
|
|
Loading…
Reference in a new issue