Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/vs/sessions/common/sessionCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export const RENAME_SESSION_COMMAND_ID = 'sessionsViewPane.renameSession';
/** Closes a chat tab. Registered in `sessionsActions.ts`. */
export const CLOSE_CHAT_COMMAND_ID = 'sessions.chatCompositeBar.closeChat';

/** Focuses the active session. Registered in `sessionsActions.ts`. */
export const FOCUS_ACTIVE_SESSION_COMMAND_ID = 'sessions.focusActiveSession';

export const FOCUS_PREVIOUS_CHAT_GROUP_COMMAND_ID = 'sessions.focusPreviousChatGroup';

export const FOCUS_NEXT_CHAT_GROUP_COMMAND_ID = 'sessions.focusNextChatGroup';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { FOCUS_AI_CUSTOMIZATION_VIEW_ID } from '../../aiCustomizationTreeView/br
import { ISessionsPartService } from '../../../services/sessions/browser/sessionsPartService.js';
import { ISessionsService } from '../../../services/sessions/browser/sessionsService.js';
import { REPLACE_PROMPT_TEMPLATE_PLACEHOLDER_COMMAND_ID } from './promptTemplatePlaceholder.js';
import { FOCUS_NEXT_CHAT_GROUP_COMMAND_ID, FOCUS_PREVIOUS_CHAT_GROUP_COMMAND_ID, MOVE_CHAT_TO_NEXT_GROUP_COMMAND_ID, MOVE_CHAT_TO_PREVIOUS_GROUP_COMMAND_ID, SPLIT_CHAT_GROUP_DOWN_COMMAND_ID, SPLIT_CHAT_GROUP_RIGHT_COMMAND_ID } from '../../../common/sessionCommands.js';
import { FOCUS_ACTIVE_SESSION_COMMAND_ID, FOCUS_NEXT_CHAT_GROUP_COMMAND_ID, FOCUS_PREVIOUS_CHAT_GROUP_COMMAND_ID, MOVE_CHAT_TO_NEXT_GROUP_COMMAND_ID, MOVE_CHAT_TO_PREVIOUS_GROUP_COMMAND_ID, SPLIT_CHAT_GROUP_DOWN_COMMAND_ID, SPLIT_CHAT_GROUP_RIGHT_COMMAND_ID } from '../../../common/sessionCommands.js';
export class SessionsChatAccessibilityHelp implements IAccessibleViewImplementation {
readonly priority = 120;
readonly name = 'sessionsChat';
Expand Down Expand Up @@ -66,6 +66,7 @@ export class SessionsChatAccessibilityHelp implements IAccessibleViewImplementat
content.push(localize('sessionsChat.deleteChat', "To permanently delete a chat, open the chat tab's context menu and choose Delete Chat. This is destructive and cannot be undone."));
content.push(localize('sessionsChat.promptTimeline', "When the prompt timeline is enabled, a handle on the left edge of the transcript lists your prompts. Activate it to expand the list, use the up and down arrows (or Home and End) to move between prompts, Enter or Space to jump to a prompt, and Escape to dismiss the list and return focus to the handle. When a prompt title is pinned above the transcript, activate its title to jump to that prompt."));
content.push(localize('sessionsChat.find', "To search the chat transcript, invoke Find in Chat{0}. Find Next{1} and Find Previous{2} move between results, scrolling each one into view.", '<keybinding:workbench.action.chat.find>', '<keybinding:workbench.action.chat.findNext>', '<keybinding:workbench.action.chat.findPrevious>'));
content.push(localize('sessionsChat.focusActiveSession', "Focus the active session{0}. The default Open Chat (Agent) shortcut also focuses the active session in the Agents window.", `<keybinding:${FOCUS_ACTIVE_SESSION_COMMAND_ID}>`));
content.push(localize('sessionsChat.goBack', "Go back through visited sessions{0}.", '<keybinding:sessions.goBack>'));
content.push(localize('sessionsChat.goForward', "Go forward through visited sessions{0}.", '<keybinding:sessions.goForward>'));
content.push(localize('sessionsChat.navigatePreviousSession', "Navigate to the previous session in the list{0}.", '<keybinding:sessionsViewPane.navigatePreviousSession>'));
Expand Down
14 changes: 11 additions & 3 deletions src/vs/sessions/contrib/sessions/browser/sessionsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { Menus } from '../../../browser/menus.js';
import { SessionsCategories } from '../../../common/categories.js';
import { CanGoBackContext, CanGoForwardContext, SessionProviderIdContext, MultipleSessionsVisibleContext, SessionIsArchivedContext, SessionIsCreatedContext, SessionIsMaximizedContext, SessionIsStickyContext, SessionsFocusContext, SessionSupportsMultipleChatsContext, SessionsWelcomeVisibleContext, SessionIdContext, SessionHasMultipleCommittedChatsContext, SessionHasMultipleOpenChatsContext, SessionsPickerVisibleContext, SessionActiveChatIsClosableContext, SessionActiveChatIsDeletableContext, SessionChatsPickerVisibleContext, SessionActiveChatHasSubagentsContext, SessionsTitleBarNewSessionEnabledContext, SessionsEditorScopeContext, SessionsHasClosedItemContext, IsQuickChatSessionContext } from '../../../common/contextkeys.js';
import { ANY_AGENT_HOST_PROVIDER_RE } from '../../../common/agentHostSessionsProvider.js';
import { CLOSE_CHAT_COMMAND_ID, FOCUS_NEXT_CHAT_GROUP_COMMAND_ID, FOCUS_PREVIOUS_CHAT_GROUP_COMMAND_ID, MOVE_CHAT_TO_NEXT_GROUP_COMMAND_ID, MOVE_CHAT_TO_PREVIOUS_GROUP_COMMAND_ID, SPLIT_CHAT_GROUP_DOWN_COMMAND_ID, SPLIT_CHAT_GROUP_RIGHT_COMMAND_ID } from '../../../common/sessionCommands.js';
import { CLOSE_CHAT_COMMAND_ID, FOCUS_ACTIVE_SESSION_COMMAND_ID, FOCUS_NEXT_CHAT_GROUP_COMMAND_ID, FOCUS_PREVIOUS_CHAT_GROUP_COMMAND_ID, MOVE_CHAT_TO_NEXT_GROUP_COMMAND_ID, MOVE_CHAT_TO_PREVIOUS_GROUP_COMMAND_ID, SPLIT_CHAT_GROUP_DOWN_COMMAND_ID, SPLIT_CHAT_GROUP_RIGHT_COMMAND_ID } from '../../../common/sessionCommands.js';
import { IActiveSession, ISessionsManagementService } from '../../../services/sessions/common/sessionsManagement.js';
import { ISessionsService } from '../../../services/sessions/browser/sessionsService.js';
import { ChatOriginKind, getChatCapabilities, getUntitledSessionTitle, IChat, ISession, SessionStatus } from '../../../services/sessions/common/session.js';
Expand Down Expand Up @@ -328,7 +328,7 @@ registerAction2(class GoForwardAction extends Action2 {
registerAction2(class FocusActiveSessionAction extends Action2 {
constructor() {
super({
id: 'sessions.focusActiveSession',
id: FOCUS_ACTIVE_SESSION_COMMAND_ID,
title: localize2('focusActiveSession', "Focus Active Session"),
f1: true,
category: SessionsCategories.Sessions,
Expand All @@ -338,7 +338,15 @@ registerAction2(class FocusActiveSessionAction extends Action2 {
// focuses the active session. Using the normal open chat action will not work for new session views.
weight: KeybindingWeight.SessionsContrib,
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyI,
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KeyI },
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI],
mac: {
primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KeyI,
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI]
},
linux: {
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyI,
secondary: [KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift | KeyCode.KeyI]
},
},
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import assert from 'assert';
import { decodeKeybinding } from '../../../../../base/common/keybindings.js';
import { KeyCode, KeyMod } from '../../../../../base/common/keyCodes.js';
import { OperatingSystem } from '../../../../../base/common/platform.js';
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
import { KeybindingsRegistry, KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
import '../../../../../editor/contrib/format/browser/formatActions.js';
import { FOCUS_ACTIVE_SESSION_COMMAND_ID } from '../../../../common/sessionCommands.js';
import '../../browser/sessionsActions.js';

suite('Sessions - Focus Active Session keybinding', () => {

ensureNoDisposablesAreLeakedInTestSuite();

function getRule(os: OperatingSystem, keybinding: number) {
const hash = decodeKeybinding(keybinding, os)!.getHashCode();
return KeybindingsRegistry.getDefaultKeybindingsForOS(os)
.find(item => item.command === FOCUS_ACTIVE_SESSION_COMMAND_ID && item.keybinding?.getHashCode() === hash);
}

test('aliases the platform Open Chat (Agent) keybinding', () => {
const windowsRule = getRule(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI);
const macRule = getRule(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI);
const linuxRule = getRule(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift | KeyCode.KeyI);

assert.deepStrictEqual({
windows: { weight: windowsRule?.weight1, secondary: windowsRule?.weight2 },
mac: { weight: macRule?.weight1, secondary: macRule?.weight2 },
linux: { weight: linuxRule?.weight1, secondary: linuxRule?.weight2 },
}, {
windows: { weight: KeybindingWeight.SessionsContrib, secondary: -1 },
mac: { weight: KeybindingWeight.SessionsContrib, secondary: -1 },
linux: { weight: KeybindingWeight.SessionsContrib, secondary: -1 },
});
});

test('preserves the Linux Format Document keybinding', () => {
const hash = decodeKeybinding(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI, OperatingSystem.Linux)!.getHashCode();
const rules = KeybindingsRegistry.getDefaultKeybindingsForOS(OperatingSystem.Linux)
.filter(item => item.keybinding?.getHashCode() === hash);

assert.deepStrictEqual({
formatDocument: rules.some(item => item.command === 'editor.action.formatDocument'),
focusActiveSession: rules.some(item => item.command === FOCUS_ACTIVE_SESSION_COMMAND_ID),
}, {
formatDocument: true,
focusActiveSession: false,
});
});
});
Loading