Allow cmd+c to copy chat row content (#193410)

* Allow cmd+c to copy chat row content
Fix microsoft/vscode-copilot#1433

* Add onDidBlur listener
This commit is contained in:
Rob Lourens
2023-09-18 16:50:05 -07:00
committed by GitHub
parent 308a69b603
commit ee8f89f614
3 changed files with 21 additions and 3 deletions

View File

@@ -3,12 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { localize } from 'vs/nls';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat';
import { CONTEXT_IN_CHAT_LIST } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { IChatRequestViewModel, IChatResponseViewModel, isRequestVM, isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel';
export function registerChatCopyActions() {
@@ -57,15 +60,24 @@ export function registerChatCopyActions() {
category: CHAT_CATEGORY,
menu: {
id: MenuId.ChatContext
},
keybinding: {
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyMod.CtrlCmd | KeyCode.KeyC,
when: CONTEXT_IN_CHAT_LIST
}
});
}
run(accessor: ServicesAccessor, ...args: any[]) {
const item = args[0];
let item = args[0];
if (!isRequestVM(item) && !isResponseVM(item)) {
const widgetService = accessor.get(IChatWidgetService);
item = widgetService.lastFocusedWidget?.getFocus();
if (!isRequestVM(item) && !isResponseVM(item)) {
return;
}
}
const clipboardService = accessor.get(IClipboardService);
const text = stringifyItem(item);

View File

@@ -25,7 +25,7 @@ import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart';
import { ChatAccessibilityProvider, ChatListDelegate, ChatListItemRenderer, IChatListItemRendererOptions, IChatRendererDelegate } from 'vs/workbench/contrib/chat/browser/chatListRenderer';
import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions';
import { ChatViewPane } from 'vs/workbench/contrib/chat/browser/chatViewPane';
import { CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_LIST, CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService';
import { IChatModel } from 'vs/workbench/contrib/chat/common/chatModel';
import { IChatReplyFollowup, IChatService, ISlashCommand } from 'vs/workbench/contrib/chat/common/chatService';
@@ -119,6 +119,8 @@ export class ChatWidget extends Disposable implements IChatWidget {
private lastSlashCommands: ISlashCommand[] | undefined;
private slashCommandsPromise: Promise<ISlashCommand[] | undefined> | undefined;
private readonly chatListFocused: IContextKey<boolean>;
constructor(
readonly viewContext: IChatWidgetViewContext,
private readonly styles: IChatWidgetStyles,
@@ -132,6 +134,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
) {
super();
CONTEXT_IN_CHAT_SESSION.bindTo(contextKeyService).set(true);
this.chatListFocused = CONTEXT_IN_CHAT_LIST.bindTo(contextKeyService);
this.requestInProgress = CONTEXT_CHAT_REQUEST_IN_PROGRESS.bindTo(contextKeyService);
this._register((chatWidgetService as ChatWidgetService).register(this));
@@ -351,7 +354,9 @@ export class ChatWidget extends Disposable implements IChatWidget {
}));
this._register(this.tree.onDidFocus(() => {
this._onDidFocus.fire();
this.chatListFocused.set(this.tree.isDOMFocused());
}));
this._register(this.tree.onDidBlur(() => this.chatListFocused.set(false)));
}
private onContextMenu(e: ITreeContextMenuEvent<ChatTreeItem | null>): void {

View File

@@ -17,5 +17,6 @@ export const CONTEXT_REQUEST = new RawContextKey<boolean>('chatRequest', false,
export const CONTEXT_CHAT_INPUT_HAS_TEXT = new RawContextKey<boolean>('chatInputHasText', false, { type: 'boolean', description: localize('interactiveInputHasText', "True when the chat input has text.") });
export const CONTEXT_IN_CHAT_INPUT = new RawContextKey<boolean>('inChatInput', false, { type: 'boolean', description: localize('inInteractiveInput', "True when focus is in the chat input, false otherwise.") });
export const CONTEXT_IN_CHAT_SESSION = new RawContextKey<boolean>('inChat', false, { type: 'boolean', description: localize('inChat', "True when focus is in the chat widget, false otherwise.") });
export const CONTEXT_IN_CHAT_LIST = new RawContextKey<boolean>('chatListFocused', false, { type: 'boolean', description: localize('chatListFocused', "True when a row of the chat list is focused, but not when focus is on a different element inside the chat row.") });
export const CONTEXT_PROVIDER_EXISTS = new RawContextKey<boolean>('hasChatProvider', false, { type: 'boolean', description: localize('hasChatProvider', "True when some chat provider has been registered.") });