Skip to content

Commit e3af4ea

Browse files
committed
add ghost text
1 parent 5d941e4 commit e3af4ea

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/vs/workbench/contrib/terminal/browser/media/terminalSpeechToText.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,10 @@
3838
color: var(--vscode-terminalCursor-background);
3939
}
4040
}
41+
42+
.terminal-speech-progress-text {
43+
font-style: italic;
44+
color: var(--vscode-editorGhostText-foreground) !important;
45+
border: 1px solid var(--vscode-editorGhostText-border);
46+
z-index: 1000;
47+
}

src/vs/workbench/contrib/terminal/browser/terminalSpeechToText.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ import { Codicon } from 'vs/base/common/codicons';
1919

2020
export class TerminalSpeechToTextSession extends Disposable {
2121
private _input: string = '';
22+
private _ghostText: IDecoration | undefined;
2223
private _decoration: IDecoration | undefined;
2324
private _marker: IXtermMarker | undefined;
25+
private _ghostTextMarker: IXtermMarker | undefined;
2426
private static _instance: TerminalSpeechToTextSession | undefined = undefined;
2527
private _acceptTranscriptionScheduler: RunOnceScheduler | undefined;
2628
static getInstance(instantiationService: IInstantiationService): TerminalSpeechToTextSession {
@@ -69,6 +71,7 @@ export class TerminalSpeechToTextSession extends Disposable {
6971
break;
7072
case SpeechToTextStatus.Recognizing: {
7173
this._updateInput(e);
74+
this._renderGhostText(e);
7275
if (voiceTimeout > 0) {
7376
this._acceptTranscriptionScheduler!.cancel();
7477
}
@@ -94,6 +97,9 @@ export class TerminalSpeechToTextSession extends Disposable {
9497
this._terminalService.activeInstance?.sendText(this._input, false);
9598
}
9699
this._marker?.dispose();
100+
this._ghostTextMarker?.dispose();
101+
this._ghostText?.dispose();
102+
this._ghostText = undefined;
97103
this._decoration?.dispose();
98104
this._decoration = undefined;
99105
this._cancellationTokenSource?.cancel();
@@ -165,6 +171,33 @@ export class TerminalSpeechToTextSession extends Disposable {
165171
private _setInactive(): void {
166172
this._decoration?.element?.classList.remove('recording');
167173
}
174+
175+
private _renderGhostText(e: ISpeechToTextEvent): void {
176+
this._ghostText?.dispose();
177+
const text = e.text;
178+
if (!text) {
179+
return;
180+
}
181+
const activeInstance = this._terminalService.activeInstance;
182+
const xterm = activeInstance?.xterm?.raw;
183+
if (!xterm) {
184+
return;
185+
}
186+
this._ghostTextMarker = activeInstance.registerMarker();
187+
if (!this._ghostTextMarker) {
188+
return;
189+
}
190+
this._ghostText = xterm.registerDecoration({
191+
marker: this._ghostTextMarker,
192+
layer: 'top',
193+
x: xterm.buffer.active.cursorX + 1 ?? 0,
194+
});
195+
this._ghostText?.onRender((e: HTMLElement) => {
196+
e.classList.add('terminal-speech-progress-text');
197+
e.textContent = text;
198+
e.style.width = 'fit-content';
199+
});
200+
}
168201
}
169202

170203

0 commit comments

Comments
 (0)