Path: blob/main/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { KeyCode, KeyMod } from '../../../../../base/common/keyCodes.js';6import { ServicesAccessor } from '../../../../../editor/browser/editorExtensions.js';7import { localize2 } from '../../../../../nls.js';8import { Action2, registerAction2 } from '../../../../../platform/actions/common/actions.js';9import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';10import { CHAT_CATEGORY } from './chatActions.js';11import { IChatWidgetService } from '../chat.js';12import { ChatContextKeys } from '../../common/chatContextKeys.js';13import { IChatResponseViewModel, isResponseVM } from '../../common/chatViewModel.js';1415export function registerChatFileTreeActions() {16registerAction2(class NextFileTreeAction extends Action2 {17constructor() {18super({19id: 'workbench.action.chat.nextFileTree',20title: localize2('interactive.nextFileTree.label', "Next File Tree"),21keybinding: {22primary: KeyMod.CtrlCmd | KeyCode.F9,23weight: KeybindingWeight.WorkbenchContrib,24when: ChatContextKeys.inChatSession,25},26precondition: ChatContextKeys.enabled,27f1: true,28category: CHAT_CATEGORY,29});30}3132run(accessor: ServicesAccessor, ...args: any[]) {33navigateTrees(accessor, false);34}35});3637registerAction2(class PreviousFileTreeAction extends Action2 {38constructor() {39super({40id: 'workbench.action.chat.previousFileTree',41title: localize2('interactive.previousFileTree.label', "Previous File Tree"),42keybinding: {43primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F9,44weight: KeybindingWeight.WorkbenchContrib,45when: ChatContextKeys.inChatSession,46},47precondition: ChatContextKeys.enabled,48f1: true,49category: CHAT_CATEGORY,50});51}5253run(accessor: ServicesAccessor, ...args: any[]) {54navigateTrees(accessor, true);55}56});57}5859function navigateTrees(accessor: ServicesAccessor, reverse: boolean) {60const chatWidgetService = accessor.get(IChatWidgetService);61const widget = chatWidgetService.lastFocusedWidget;62if (!widget) {63return;64}6566const focused = !widget.inputEditor.hasWidgetFocus() && widget.getFocus();67const focusedResponse = isResponseVM(focused) ? focused : undefined;6869const currentResponse = focusedResponse ?? widget.viewModel?.getItems().reverse().find((item): item is IChatResponseViewModel => isResponseVM(item));70if (!currentResponse) {71return;72}7374widget.reveal(currentResponse);75const responseFileTrees = widget.getFileTreeInfosForResponse(currentResponse);76const lastFocusedFileTree = widget.getLastFocusedFileTreeForResponse(currentResponse);77const focusIdx = lastFocusedFileTree ?78(lastFocusedFileTree.treeIndex + (reverse ? -1 : 1) + responseFileTrees.length) % responseFileTrees.length :79reverse ? responseFileTrees.length - 1 : 0;8081responseFileTrees[focusIdx]?.focus();82}838485