Repopulate slash command in chat input editor (#187207)

* Repopulate slash command in chat input editor
This commit is contained in:
Joyce Er
2023-07-10 15:01:54 -07:00
committed by GitHub
parent 0422c8fe28
commit 1beeb2e113
4 changed files with 44 additions and 1 deletions
@@ -21,6 +21,7 @@ import { IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/brows
import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart';
import { IChatService } from 'vs/workbench/contrib/chat/common/chatService';
const decorationDescription = 'chat';
const slashCommandPlaceholderDecorationType = 'chat-session-detail';
@@ -131,7 +132,36 @@ class InputEditorDecorations extends Disposable {
}
}
ChatWidget.CONTRIBS.push(InputEditorDecorations);
class InputEditorSlashCommandFollowups extends Disposable {
constructor(
private readonly widget: IChatWidget,
@IChatService private readonly chatService: IChatService
) {
super();
this._register(this.chatService.onDidCompleteSlashCommand(({ slashCommand, sessionId }) => this.repopulateSlashCommand(slashCommand, sessionId)));
}
private async repopulateSlashCommand(slashCommand: string, sessionId: string) {
if (this.widget.viewModel?.sessionId !== sessionId) {
return;
}
const slashCommands = await this.widget.getSlashCommands();
if (this.widget.inputEditor.getValue().trim().length !== 0) {
return;
}
if (slashCommands?.find(c => c.command === slashCommand)?.shouldRepopulate) {
const value = `/${slashCommand} `;
this.widget.inputEditor.setValue(value);
this.widget.inputEditor.setPosition({ lineNumber: 1, column: value.length + 1 });
}
}
}
ChatWidget.CONTRIBS.push(InputEditorDecorations, InputEditorSlashCommandFollowups);
class SlashCommandCompletions extends Disposable {
constructor(
@@ -67,6 +67,7 @@ export interface ISlashCommandProvider {
export interface ISlashCommand {
command: string;
shouldRepopulate?: boolean;
provider?: ISlashCommandProvider;
sortText?: string;
detail?: string;
@@ -176,6 +177,8 @@ export const IChatService = createDecorator<IChatService>('IChatService');
export interface IChatService {
_serviceBrand: undefined;
transferredSessionId: string | undefined;
onDidCompleteSlashCommand: Event<{ slashCommand: string; sessionId: string }>;
registerProvider(provider: IChatProvider): IDisposable;
registerSlashCommandProvider(provider: ISlashCommandProvider): IDisposable;
getProviderInfos(): IChatProviderInfo[];
@@ -135,6 +135,9 @@ export class ChatService extends Disposable implements IChatService {
private readonly _onDidPerformUserAction = this._register(new Emitter<IChatUserActionEvent>());
public readonly onDidPerformUserAction: Event<IChatUserActionEvent> = this._onDidPerformUserAction.event;
private readonly _onDidCompleteSlashCommand = this._register(new Emitter<{ slashCommand: string; sessionId: string }>());
public readonly onDidCompleteSlashCommand = this._onDidCompleteSlashCommand.event;
constructor(
@IStorageService private readonly storageService: IStorageService,
@ILogService private readonly logService: ILogService,
@@ -472,9 +475,15 @@ export class ChatService extends Disposable implements IChatService {
Promise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => {
model.setFollowups(request, withNullAsUndefined(followups));
model.completeResponse(request);
if (usedSlashCommand?.command) {
this._onDidCompleteSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId });
}
});
} else {
model.completeResponse(request);
if (usedSlashCommand?.command) {
this._onDidCompleteSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId });
}
}
}
});
+1
View File
@@ -128,6 +128,7 @@ declare module 'vscode' {
export interface InteractiveSessionSlashCommand {
command: string;
shouldRepopulate?: boolean;
kind: CompletionItemKind;
detail?: string;
}