diff --git a/src/vs/workbench/api/common/extHostInlineChat.ts b/src/vs/workbench/api/common/extHostInlineChat.ts index d46e67243fc25..7e3474b5d24c8 100644 --- a/src/vs/workbench/api/common/extHostInlineChat.ts +++ b/src/vs/workbench/api/common/extHostInlineChat.ts @@ -18,6 +18,7 @@ import type * as vscode from 'vscode'; import { ApiCommand, ApiCommandArgument, ApiCommandResult, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { IRange } from 'vs/editor/common/core/range'; import { IPosition } from 'vs/editor/common/core/position'; +import { TextEdit } from 'vs/editor/common/languages'; class ProviderWrapper { @@ -62,6 +63,7 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape { message?: string; autoSend?: boolean; position?: vscode.Position; + edits?: extHostTypes.TextEdit[]; }; type InteractiveEditorRunOptions = { @@ -70,6 +72,7 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape { message?: string; autoSend?: boolean; position?: IPosition; + edits?: TextEdit[]; }; extHostCommands.registerApiCommand(new ApiCommand( @@ -86,6 +89,7 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape { message: v.message, autoSend: v.autoSend, position: v.position ? typeConvert.Position.from(v.position) : undefined, + edits: v.edits ? v.edits.map(edit => typeConvert.TextEdit.from(edit)) : undefined, }; })], ApiCommandResult.Void @@ -222,8 +226,10 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape { $handleFeedback(handle: number, sessionId: number, responseId: number, kind: InlineChatResponseFeedbackKind): void { const entry = this._inputProvider.get(handle); const sessionData = this._inputSessions.get(sessionId); - const response = sessionData?.responses[responseId]; - if (entry && response) { + + // Allows to handle feedback on Edit Only triggers + const response = responseId === Number.MAX_VALUE ? { edits: [] } : sessionData?.responses[responseId]; + if (entry && sessionData?.session && response) { const apiKind = typeConvert.InteractiveEditorResponseFeedbackKind.to(kind); entry.provider.handleInteractiveEditorResponseFeedback?.(sessionData.session, response, apiKind); } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css index 87f586d2f0247..696c327034396 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css @@ -22,10 +22,6 @@ /* body */ -.monaco-editor .inline-chat .body { - display: flex; -} - .monaco-editor .inline-chat .body .content { display: flex; box-sizing: border-box; @@ -105,10 +101,6 @@ align-items: center; } -.monaco-editor .inline-chat .status.actions { - margin-top: 6px; -} - .monaco-editor .inline-chat .status .actions.hidden { display: none; } @@ -299,6 +291,7 @@ /* create zone */ + .monaco-editor .inline-chat-newfile-widget { padding: 3px 0 6px 0; background-color: var(--vscode-inlineChat-regionHighlight); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 1d8cacb29850d..87ee0a8cab846 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -71,6 +71,7 @@ export interface InlineChatRunOptions { existingSession?: Session; isUnstashed?: boolean; position?: IPosition; + edits?: TextEdit[]; } export class InlineChatController implements IEditorContribution { @@ -189,6 +190,8 @@ export class InlineChatController implements IEditorContribution { private _currentRun?: Promise; async run(options: InlineChatRunOptions | undefined = {}): Promise { + // Modifies the styling of inlineChat based on the mode of usage. + this._zone.value.widget.showEditOnlyActions(options.edits && options.edits.length > 0); this.finishExistingSession(); if (this._currentRun) { await this._currentRun; @@ -367,6 +370,22 @@ export class InlineChatController implements IEditorContribution { } })); + if (options.edits && options.edits.length > 0) { + this._activeSession.addExchange(new SessionExchange( + new SessionPrompt('edit'), + new EditResponse( + this._activeSession.textModelN.uri, + this._activeSession.textModelN.getAlternativeVersionId(), + { + id: Number.MAX_VALUE, + type: InlineChatResponseType.EditorEdit, + edits: options.edits + }, + [] + ))); + return State.APPLY_RESPONSE; + } + if (!this._activeSession.lastExchange) { return State.WAIT_FOR_INPUT; } else if (options.isUnstashed) { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 9703af6a00a0b..0d3ff4ba9c680 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -405,6 +405,21 @@ export class InlineChatWidget { this._inputEditor.updateOptions({ ariaLabel: label }); } + // Changes styling of properties (e.g. Hides the input field), when toolbar is used only for Edit application. + showEditOnlyActions(isEditOnly?: boolean) { + if (isEditOnly) { + this._elements.content.style.display = 'none'; + this._elements.status.style.marginTop = '0px'; + this._elements.previewCreateTitle.classList.add('hidden'); + this._elements.previewCreate.classList.add('hidden'); + } else { + this._elements.content.style.display = 'flex'; + this._elements.status.style.marginTop = '2px'; + this._elements.previewCreateTitle.classList.remove('hidden'); + this._elements.previewCreate.classList.remove('hidden'); + } + } + dispose(): void { this._store.dispose(); this._ctxInputEmpty.reset(); @@ -446,7 +461,8 @@ export class InlineChatWidget { getHeight(): number { const base = getTotalHeight(this._elements.progress) + getTotalHeight(this._elements.status); - const editorHeight = this._inputEditor.getContentHeight() + 12 /* padding and border */; + // If the input area is not shown, then don't extend the viewZone with its height. + const editorHeight = this._elements.content.style.display === 'none' ? 0 : this._inputEditor.getContentHeight() + 12 /* padding and border */; const markdownMessageHeight = getTotalHeight(this._elements.markdownMessage); const previewDiffHeight = this._previewDiffEditor.value.getModel() ? 12 + Math.min(300, Math.max(0, this._previewDiffEditor.value.getContentHeight())) : 0; const previewCreateTitleHeight = getTotalHeight(this._elements.previewCreateTitle);