Skip to content

Commit c83f54a

Browse files
authored
Implement "clear history" command for interactive sessions (microsoft#178194)
1 parent b962dd0 commit c83f54a

File tree

4 files changed

+91
-35
lines changed

4 files changed

+91
-35
lines changed

src/vs/workbench/contrib/interactiveSession/browser/actions/interactiveSessionActions.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { IInteractiveSessionEditorOptions, InteractiveSessionEditor } from 'vs/w
1919
import { InteractiveSessionViewPane } from 'vs/workbench/contrib/interactiveSession/browser/interactiveSessionSidebar';
2020
import { IInteractiveSessionWidgetService } from 'vs/workbench/contrib/interactiveSession/browser/interactiveSessionWidget';
2121
import { CONTEXT_IN_INTERACTIVE_INPUT, CONTEXT_IN_INTERACTIVE_SESSION } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionContextKeys';
22+
import { IInteractiveSessionWidgetHistoryService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionWidgetHistoryService';
2223
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
2324

2425
export const INTERACTIVE_SESSION_CATEGORY = { value: localize('interactiveSession.category', "Interactive Session"), original: 'Interactive Session' };
@@ -48,28 +49,6 @@ export function registerInteractiveSessionActions() {
4849
}
4950
});
5051

51-
// registerAction2(class OpenInteractiveSessionWindow extends Action2 {
52-
// constructor() {
53-
// super({
54-
// id: 'workbench.action.interactiveSession.start',
55-
// title: localize('interactiveSession', 'Open Interactive Session...'),
56-
// icon: Codicon.commentDiscussion,
57-
// precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE),
58-
// f1: false,
59-
// menu: {
60-
// id: MENU_INTERACTIVE_EDITOR_WIDGET,
61-
// group: 'Z',
62-
// order: 1
63-
// }
64-
// });
65-
// }
66-
67-
// override run(accessor: ServicesAccessor, ...args: any[]): void {
68-
// const viewsService = accessor.get(IViewsService);
69-
// viewsService.openView(InteractiveSessionViewPane.ID, true);
70-
// }
71-
// });
72-
7352
registerAction2(class ClearEditorAction extends Action2 {
7453
constructor() {
7554
super({
@@ -96,6 +75,24 @@ export function registerInteractiveSessionActions() {
9675
}
9776
});
9877

78+
registerAction2(class ClearEditorAction extends Action2 {
79+
constructor() {
80+
super({
81+
id: 'workbench.action.interactiveSessionEditor.clearHistory',
82+
title: {
83+
value: localize('interactiveSession.clearHistory.label', "Clear Input History"),
84+
original: 'Clear Input History'
85+
},
86+
category: INTERACTIVE_SESSION_CATEGORY,
87+
f1: true,
88+
});
89+
}
90+
async run(accessor: ServicesAccessor, ...args: any[]) {
91+
const historyService = accessor.get(IInteractiveSessionWidgetHistoryService);
92+
historyService.clearHistory();
93+
}
94+
});
95+
9996
registerEditorAction(class FocusInteractiveSessionAction extends EditorAction {
10097
constructor() {
10198
super({

src/vs/workbench/contrib/interactiveSession/browser/interactiveSession.contribution.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { IInteractiveSessionWidgetService, InteractiveSessionWidgetService } fro
2626
import { IInteractiveSessionContributionService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionContributionService';
2727
import { IInteractiveSessionService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionService';
2828
import { InteractiveSessionService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionServiceImpl';
29+
import { IInteractiveSessionWidgetHistoryService, InteractiveSessionWidgetHistoryService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionWidgetHistoryService';
2930
import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService';
3031
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
3132
import '../common/interactiveSessionColors';
@@ -117,6 +118,8 @@ registerInteractiveSessionExecuteActions();
117118
registerSingleton(IInteractiveSessionService, InteractiveSessionService, InstantiationType.Delayed);
118119
registerSingleton(IInteractiveSessionContributionService, InteractiveSessionContributionService, InstantiationType.Delayed);
119120
registerSingleton(IInteractiveSessionWidgetService, InteractiveSessionWidgetService, InstantiationType.Delayed);
121+
registerSingleton(IInteractiveSessionWidgetHistoryService, InteractiveSessionWidgetHistoryService, InstantiationType.Delayed);
120122

121-
import 'vs/workbench/contrib/interactiveSession/browser/contrib/interactiveSessionInputEditorContrib';
122123
import 'vs/workbench/contrib/interactiveSession/browser/contrib/interactiveSessionCodeBlockCopy';
124+
import 'vs/workbench/contrib/interactiveSession/browser/contrib/interactiveSessionInputEditorContrib';
125+

src/vs/workbench/contrib/interactiveSession/browser/interactiveSessionWidget.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { InteractiveSessionEditorOptions } from 'vs/workbench/contrib/interactiv
4141
import { CONTEXT_INTERACTIVE_REQUEST_IN_PROGRESS, CONTEXT_IN_INTERACTIVE_INPUT, CONTEXT_IN_INTERACTIVE_SESSION } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionContextKeys';
4242
import { IInteractiveSessionReplyFollowup, IInteractiveSessionService, IInteractiveSlashCommand } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionService';
4343
import { IInteractiveSessionViewModel, InteractiveSessionViewModel, isRequestVM, isResponseVM, isWelcomeVM } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionViewModel';
44+
import { IInteractiveSessionWidgetHistoryService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionWidgetHistoryService';
4445
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
4546

4647
export const IInteractiveSessionWidgetService = createDecorator<IInteractiveSessionWidgetService>('interactiveSessionWidgetService');
@@ -64,11 +65,9 @@ function revealLastElement(list: WorkbenchObjectTree<any>) {
6465
}
6566

6667
interface IViewState {
67-
history: string[];
6868
inputValue: string;
6969
}
7070

71-
const HISTORY_STORAGE_KEY = 'interactiveSession.history';
7271
const INPUT_EDITOR_MAX_HEIGHT = 250;
7372

7473
export class InteractiveSessionWidget extends Disposable implements IInteractiveSessionWidget, IHistoryNavigationWidget {
@@ -155,14 +154,15 @@ export class InteractiveSessionWidget extends Disposable implements IInteractive
155154
private readonly listBackgroundColorDelegate: () => string,
156155
private readonly inputEditorBackgroundColorDelegate: () => string,
157156
private readonly resultEditorBackgroundColorDelegate: () => string,
158-
@IStorageService private readonly storageService: IStorageService,
157+
@IStorageService storageService: IStorageService,
159158
@IContextKeyService private readonly contextKeyService: IContextKeyService,
160159
@IInstantiationService private readonly instantiationService: IInstantiationService,
161160
@IModelService private readonly modelService: IModelService,
162161
@IExtensionService private readonly extensionService: IExtensionService,
163162
@IInteractiveSessionService private readonly interactiveSessionService: IInteractiveSessionService,
164163
@IInteractiveSessionWidgetService interactiveSessionWidgetService: IInteractiveSessionWidgetService,
165164
@IContextMenuService private readonly contextMenuService: IContextMenuService,
165+
@IInteractiveSessionWidgetHistoryService private readonly historyService: IInteractiveSessionWidgetHistoryService,
166166
) {
167167
super();
168168
CONTEXT_IN_INTERACTIVE_SESSION.bindTo(contextKeyService).set(true);
@@ -171,12 +171,12 @@ export class InteractiveSessionWidget extends Disposable implements IInteractive
171171
this._register((interactiveSessionWidgetService as InteractiveSessionWidgetService).register(this));
172172
this.initializeSessionModel(true);
173173

174-
const oldPersistedHistory = JSON.parse(this.storageService.get(this.getHistoryStorageKey(), StorageScope.WORKSPACE, '[]'));
174+
const history = this.historyService.getHistory(this.providerId);
175+
this.history = new HistoryNavigator(history, 50);
176+
this._register(this.historyService.onDidClearHistory(() => this.history.clear()));
177+
175178
this.memento = new Memento('interactive-session-' + this.providerId, storageService);
176179
this.viewState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.USER) as IViewState;
177-
178-
const history = this.viewState.history ?? oldPersistedHistory;
179-
this.history = new HistoryNavigator(history, 50);
180180
}
181181

182182
get element(): HTMLElement {
@@ -637,13 +637,10 @@ export class InteractiveSessionWidget extends Disposable implements IInteractive
637637
this._inputEditor.layout({ width: width - inputPartPadding - editorBorder - editorPadding - executeToolbarWidth, height: inputEditorHeight });
638638
}
639639

640-
private getHistoryStorageKey(): string {
641-
return HISTORY_STORAGE_KEY + this.providerId;
642-
}
643-
644640
saveState(): void {
645641
const inputHistory = this.history.getHistory();
646-
this.viewState.history = inputHistory;
642+
this.historyService.saveHistory(this.providerId, inputHistory);
643+
647644
this.viewState.inputValue = this._inputEditor.getValue();
648645
this.memento.saveMemento();
649646
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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 { Emitter, Event } from 'vs/base/common/event';
7+
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
8+
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
9+
import { Memento } from 'vs/workbench/common/memento';
10+
11+
export const IInteractiveSessionWidgetHistoryService = createDecorator<IInteractiveSessionWidgetHistoryService>('IInteractiveSessionWidgetHistoryService');
12+
export interface IInteractiveSessionWidgetHistoryService {
13+
_serviceBrand: undefined;
14+
15+
readonly onDidClearHistory: Event<void>;
16+
17+
clearHistory(): void;
18+
getHistory(providerId: string): string[];
19+
saveHistory(providerId: string, history: string[]): void;
20+
}
21+
22+
interface IInteractiveSessionHistory {
23+
history: { [providerId: string]: string[] };
24+
}
25+
26+
export class InteractiveSessionWidgetHistoryService implements IInteractiveSessionWidgetHistoryService {
27+
_serviceBrand: undefined;
28+
29+
private memento: Memento;
30+
private viewState: IInteractiveSessionHistory;
31+
32+
private readonly _onDidClearHistory = new Emitter<void>();
33+
readonly onDidClearHistory: Event<void> = this._onDidClearHistory.event;
34+
35+
constructor(
36+
@IStorageService storageService: IStorageService
37+
) {
38+
this.memento = new Memento('interactive-session', storageService);
39+
this.viewState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.USER) as IInteractiveSessionHistory;
40+
}
41+
42+
getHistory(providerId: string): string[] {
43+
return this.viewState.history?.[providerId] ?? [];
44+
}
45+
46+
saveHistory(providerId: string, history: string[]): void {
47+
if (!this.viewState.history) {
48+
this.viewState.history = {};
49+
}
50+
this.viewState.history[providerId] = history;
51+
this.memento.saveMemento();
52+
}
53+
54+
clearHistory(): void {
55+
this.viewState.history = {};
56+
this.memento.saveMemento();
57+
this._onDidClearHistory.fire();
58+
}
59+
}

0 commit comments

Comments
 (0)