diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts index 46a6fcd29b1..d1b9a255453 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts @@ -30,12 +30,15 @@ import { IAgentSessionsControl } from './agentSessions.js'; import { HoverPosition } from '../../../../../base/browser/ui/hover/hoverWidget.js'; import { URI } from '../../../../../base/common/uri.js'; import { openSession } from './agentSessionsOpener.js'; +import { IEditorService } from '../../../../services/editor/common/editorService.js'; +import { ChatEditorInput } from '../chatEditorInput.js'; export interface IAgentSessionsControlOptions extends IAgentSessionsSorterOptions { readonly overrideStyles?: IStyleOverride; readonly filter?: IAgentSessionsFilter; getHoverPosition(): HoverPosition; + trackActiveEditorSession(): boolean; } type AgentSessionOpenedClassification = { @@ -70,6 +73,7 @@ export class AgentSessionsControl extends Disposable implements IAgentSessionsCo @IMenuService private readonly menuService: IMenuService, @IAgentSessionsService private readonly agentSessionsService: IAgentSessionsService, @ITelemetryService private readonly telemetryService: ITelemetryService, + @IEditorService private readonly editorService: IEditorService, ) { super(); @@ -78,6 +82,41 @@ export class AgentSessionsControl extends Disposable implements IAgentSessionsCo this.focusedAgentSessionTypeContextKey = ChatContextKeys.agentSessionType.bindTo(this.contextKeyService); this.createList(this.container); + + this.registerListeners(); + } + + private registerListeners(): void { + this._register(this.editorService.onDidActiveEditorChange(() => this.revealAndFocusActiveEditorSession())); + } + + private revealAndFocusActiveEditorSession(): void { + if ( + !this.options.trackActiveEditorSession() || + !this.visible + ) { + return; + } + + const input = this.editorService.activeEditor; + if (!(input instanceof ChatEditorInput)) { + return; + } + + const sessionResource = input.sessionResource; + if (!sessionResource) { + return; + } + + const matchingSession = this.agentSessionsService.model.getSession(sessionResource); + if (matchingSession && this.sessionsList?.hasNode(matchingSession)) { + if (this.sessionsList.getRelativeTop(matchingSession) === null) { + this.sessionsList.reveal(matchingSession, 0.5); // only reveal when not already visible + } + + this.sessionsList.setFocus([matchingSession]); + this.sessionsList.setSelection([matchingSession]); + } } private createList(container: HTMLElement): void { diff --git a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts index fe0029a42f9..a581b62842a 100644 --- a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts +++ b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts @@ -368,6 +368,9 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate { const { position } = this.getViewPositionAndLocation(); return position === Position.RIGHT ? HoverPosition.LEFT : HoverPosition.RIGHT; }, + trackActiveEditorSession: () => { + return !this._widget || this._widget?.isEmpty(); // only track and reveal unless we show a chat in the this pane + }, overrideCompare(sessionA: IAgentSession, sessionB: IAgentSession): number | undefined { // When limited where only few sessions show, sort unread sessions to the top