Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/inlineChat/electron-browser/inlineChatActions.ts
3296 views
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
import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';
6
import { ICodeEditor } from '../../../../editor/browser/editorBrowser.js';
7
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
8
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
9
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
10
import { InlineChatController } from '../browser/inlineChatController.js';
11
import { AbstractInline1ChatAction, setHoldForSpeech } from '../browser/inlineChatActions.js';
12
import { disposableTimeout } from '../../../../base/common/async.js';
13
import { EditorContextKeys } from '../../../../editor/common/editorContextKeys.js';
14
import { ICommandService } from '../../../../platform/commands/common/commands.js';
15
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
16
import { StartVoiceChatAction, StopListeningAction, VOICE_KEY_HOLD_THRESHOLD } from '../../chat/electron-browser/actions/voiceChatActions.js';
17
import { IChatExecuteActionContext } from '../../chat/browser/actions/chatExecuteActions.js';
18
import { CTX_INLINE_CHAT_VISIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
19
import { HasSpeechProvider, ISpeechService } from '../../speech/common/speechService.js';
20
import { localize2 } from '../../../../nls.js';
21
import { Action2 } from '../../../../platform/actions/common/actions.js';
22
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
23
import { EditorAction2 } from '../../../../editor/browser/editorExtensions.js';
24
25
export class HoldToSpeak extends EditorAction2 {
26
27
constructor() {
28
super({
29
id: 'inlineChat.holdForSpeech',
30
category: AbstractInline1ChatAction.category,
31
precondition: ContextKeyExpr.and(HasSpeechProvider, CTX_INLINE_CHAT_VISIBLE),
32
title: localize2('holdForSpeech', "Hold for Speech"),
33
keybinding: {
34
when: EditorContextKeys.textInputFocus,
35
weight: KeybindingWeight.WorkbenchContrib,
36
primary: KeyMod.CtrlCmd | KeyCode.KeyI,
37
},
38
});
39
}
40
41
override runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ..._args: any[]) {
42
const ctrl = InlineChatController.get(editor);
43
if (ctrl) {
44
holdForSpeech(accessor, ctrl, this);
45
}
46
}
47
}
48
49
function holdForSpeech(accessor: ServicesAccessor, ctrl: InlineChatController, action: Action2): void {
50
51
const configService = accessor.get(IConfigurationService);
52
const speechService = accessor.get(ISpeechService);
53
const keybindingService = accessor.get(IKeybindingService);
54
const commandService = accessor.get(ICommandService);
55
56
// enabled or possible?
57
if (!configService.getValue<boolean>(InlineChatConfigKeys.HoldToSpeech || !speechService.hasSpeechProvider)) {
58
return;
59
}
60
61
const holdMode = keybindingService.enableKeybindingHoldMode(action.desc.id);
62
if (!holdMode) {
63
return;
64
}
65
let listening = false;
66
const handle = disposableTimeout(() => {
67
// start VOICE input
68
commandService.executeCommand(StartVoiceChatAction.ID, { voice: { disableTimeout: true } } satisfies IChatExecuteActionContext);
69
listening = true;
70
}, VOICE_KEY_HOLD_THRESHOLD);
71
72
holdMode.finally(() => {
73
if (listening) {
74
commandService.executeCommand(StopListeningAction.ID).finally(() => {
75
ctrl.widget.chatWidget.acceptInput();
76
});
77
}
78
handle.dispose();
79
});
80
}
81
82
// make this accessible to the chat actions from the browser layer
83
setHoldForSpeech(holdForSpeech);
84
85