Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/history/browser/contextScopedHistoryWidget.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IHistoryNavigationWidget } from '../../../base/browser/history.js';
7
import { IContextViewProvider } from '../../../base/browser/ui/contextview/contextview.js';
8
import { FindInput, IFindInputOptions } from '../../../base/browser/ui/findinput/findInput.js';
9
import { IReplaceInputOptions, ReplaceInput } from '../../../base/browser/ui/findinput/replaceInput.js';
10
import { HistoryInputBox, IHistoryInputOptions } from '../../../base/browser/ui/inputbox/inputBox.js';
11
import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js';
12
import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from '../../contextkey/common/contextkey.js';
13
import { KeybindingsRegistry, KeybindingWeight } from '../../keybinding/common/keybindingsRegistry.js';
14
import { localize } from '../../../nls.js';
15
import { DisposableStore, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
16
import { isActiveElement } from '../../../base/browser/dom.js';
17
18
export const historyNavigationVisible = new RawContextKey<boolean>('suggestWidgetVisible', false, localize('suggestWidgetVisible', "Whether suggestion are visible"));
19
20
const HistoryNavigationWidgetFocusContext = 'historyNavigationWidgetFocus';
21
const HistoryNavigationForwardsEnablementContext = 'historyNavigationForwardsEnabled';
22
const HistoryNavigationBackwardsEnablementContext = 'historyNavigationBackwardsEnabled';
23
24
export interface IHistoryNavigationContext extends IDisposable {
25
historyNavigationForwardsEnablement: IContextKey<boolean>;
26
historyNavigationBackwardsEnablement: IContextKey<boolean>;
27
}
28
29
let lastFocusedWidget: IHistoryNavigationWidget | undefined = undefined;
30
const widgets: IHistoryNavigationWidget[] = [];
31
32
export function registerAndCreateHistoryNavigationContext(scopedContextKeyService: IContextKeyService, widget: IHistoryNavigationWidget): IHistoryNavigationContext {
33
if (widgets.includes(widget)) {
34
throw new Error('Cannot register the same widget multiple times');
35
}
36
37
widgets.push(widget);
38
const disposableStore = new DisposableStore();
39
const historyNavigationWidgetFocus = new RawContextKey<boolean>(HistoryNavigationWidgetFocusContext, false).bindTo(scopedContextKeyService);
40
const historyNavigationForwardsEnablement = new RawContextKey<boolean>(HistoryNavigationForwardsEnablementContext, true).bindTo(scopedContextKeyService);
41
const historyNavigationBackwardsEnablement = new RawContextKey<boolean>(HistoryNavigationBackwardsEnablementContext, true).bindTo(scopedContextKeyService);
42
43
const onDidFocus = () => {
44
historyNavigationWidgetFocus.set(true);
45
lastFocusedWidget = widget;
46
};
47
48
const onDidBlur = () => {
49
historyNavigationWidgetFocus.set(false);
50
if (lastFocusedWidget === widget) {
51
lastFocusedWidget = undefined;
52
}
53
};
54
55
// Check for currently being focused
56
if (isActiveElement(widget.element)) {
57
onDidFocus();
58
}
59
60
disposableStore.add(widget.onDidFocus(() => onDidFocus()));
61
disposableStore.add(widget.onDidBlur(() => onDidBlur()));
62
disposableStore.add(toDisposable(() => {
63
widgets.splice(widgets.indexOf(widget), 1);
64
onDidBlur();
65
}));
66
67
return {
68
historyNavigationForwardsEnablement,
69
historyNavigationBackwardsEnablement,
70
dispose() {
71
disposableStore.dispose();
72
}
73
};
74
}
75
76
export class ContextScopedHistoryInputBox extends HistoryInputBox {
77
78
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options: IHistoryInputOptions,
79
@IContextKeyService contextKeyService: IContextKeyService
80
) {
81
super(container, contextViewProvider, options);
82
const scopedContextKeyService = this._register(contextKeyService.createScoped(this.element));
83
this._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this));
84
}
85
86
}
87
88
export class ContextScopedFindInput extends FindInput {
89
90
constructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider, options: IFindInputOptions,
91
@IContextKeyService contextKeyService: IContextKeyService
92
) {
93
super(container, contextViewProvider, options);
94
const scopedContextKeyService = this._register(contextKeyService.createScoped(this.inputBox.element));
95
this._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this.inputBox));
96
}
97
}
98
99
export class ContextScopedReplaceInput extends ReplaceInput {
100
101
constructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, options: IReplaceInputOptions,
102
@IContextKeyService contextKeyService: IContextKeyService, showReplaceOptions: boolean = false
103
) {
104
super(container, contextViewProvider, showReplaceOptions, options);
105
const scopedContextKeyService = this._register(contextKeyService.createScoped(this.inputBox.element));
106
this._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this.inputBox));
107
}
108
109
}
110
111
KeybindingsRegistry.registerCommandAndKeybindingRule({
112
id: 'history.showPrevious',
113
weight: KeybindingWeight.WorkbenchContrib,
114
when: ContextKeyExpr.and(
115
ContextKeyExpr.has(HistoryNavigationWidgetFocusContext),
116
ContextKeyExpr.equals(HistoryNavigationBackwardsEnablementContext, true),
117
ContextKeyExpr.not('isComposing'),
118
historyNavigationVisible.isEqualTo(false),
119
),
120
primary: KeyCode.UpArrow,
121
secondary: [KeyMod.Alt | KeyCode.UpArrow],
122
handler: (accessor) => {
123
lastFocusedWidget?.showPreviousValue();
124
}
125
});
126
127
KeybindingsRegistry.registerCommandAndKeybindingRule({
128
id: 'history.showNext',
129
weight: KeybindingWeight.WorkbenchContrib,
130
when: ContextKeyExpr.and(
131
ContextKeyExpr.has(HistoryNavigationWidgetFocusContext),
132
ContextKeyExpr.equals(HistoryNavigationForwardsEnablementContext, true),
133
ContextKeyExpr.not('isComposing'),
134
historyNavigationVisible.isEqualTo(false),
135
),
136
primary: KeyCode.DownArrow,
137
secondary: [KeyMod.Alt | KeyCode.DownArrow],
138
handler: (accessor) => {
139
lastFocusedWidget?.showNextValue();
140
}
141
});
142
143