diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts index ed78feed024..8d9a0869da9 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts @@ -7,7 +7,7 @@ import { EditorContributionInstantiation, registerEditorContribution } from 'vs/ import { IMenuItem, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; import { InlineChatController } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; import * as InlineChatActions from 'vs/workbench/contrib/inlineChat/browser/inlineChatActions'; -import { CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, INLINE_CHAT_ID, MENU_INLINE_CHAT_CONTENT_STATUS, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CTX_INLINE_CHAT_EDITING, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, INLINE_CHAT_ID, MENU_INLINE_CHAT_CONTENT_STATUS, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -39,21 +39,38 @@ registerAction2(InlineChatExpandLineAction); // --- MENU special --- -const sendActionMenuItem: IMenuItem = { +const editActionMenuItem: IMenuItem = { group: '0_main', order: 0, command: { id: SubmitAction.ID, - title: localize('edit', "Send"), + title: localize('send.edit', "Edit Code"), }, when: ContextKeyExpr.and( CONTEXT_CHAT_INPUT_HAS_TEXT, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.toNegated(), + CTX_INLINE_CHAT_EDITING ), }; -MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_CONTENT_STATUS, sendActionMenuItem); -MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_WIDGET_STATUS, sendActionMenuItem); +const generateActionMenuItem: IMenuItem = { + group: '0_main', + order: 0, + command: { + id: SubmitAction.ID, + title: localize('send.generate', "Generate"), + }, + when: ContextKeyExpr.and( + CONTEXT_CHAT_INPUT_HAS_TEXT, + CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.toNegated(), + CTX_INLINE_CHAT_EDITING.toNegated() + ), +}; + +MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_CONTENT_STATUS, editActionMenuItem); +MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_CONTENT_STATUS, generateActionMenuItem); +MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_WIDGET_STATUS, editActionMenuItem); +MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_WIDGET_STATUS, generateActionMenuItem); const cancelActionMenuItem: IMenuItem = { group: '0_main', diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 5f078bf49d7..52477995683 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -35,7 +35,7 @@ import { EmptyResponse, ErrorResponse, ReplyResponse, Session, SessionPrompt, St import { IInlineChatSessionService } from './inlineChatSessionService'; import { EditModeStrategy, IEditObserver, LiveStrategy, PreviewStrategy, ProgressingEditsOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatStrategies'; import { InlineChatZoneWidget } from './inlineChatZoneWidget'; -import { CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, CTX_INLINE_CHAT_USER_DID_EDIT, CTX_INLINE_CHAT_VISIBLE, EditMode, INLINE_CHAT_ID, InlineChatConfigKeys, InlineChatResponseType } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CTX_INLINE_CHAT_EDITING, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, CTX_INLINE_CHAT_USER_DID_EDIT, CTX_INLINE_CHAT_VISIBLE, EditMode, INLINE_CHAT_ID, InlineChatConfigKeys, InlineChatResponseType } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { IValidEditOperation } from 'vs/editor/common/model'; import { InlineChatContentWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget'; import { MessageController } from 'vs/editor/contrib/message/browser/messageController'; @@ -108,6 +108,7 @@ export class InlineChatController implements IEditorContribution { private readonly _ui: Lazy<{ content: InlineChatContentWidget; zone: InlineChatZoneWidget }>; private readonly _ctxVisible: IContextKey; + private readonly _ctxEditing: IContextKey; private readonly _ctxResponseType: IContextKey; private readonly _ctxUserDidEdit: IContextKey; private readonly _ctxRequestInProgress: IContextKey; @@ -144,6 +145,7 @@ export class InlineChatController implements IEditorContribution { @INotebookEditorService notebookEditorService: INotebookEditorService, ) { this._ctxVisible = CTX_INLINE_CHAT_VISIBLE.bindTo(contextKeyService); + this._ctxEditing = CTX_INLINE_CHAT_EDITING.bindTo(contextKeyService); this._ctxUserDidEdit = CTX_INLINE_CHAT_USER_DID_EDIT.bindTo(contextKeyService); this._ctxResponseType = CTX_INLINE_CHAT_RESPONSE_TYPE.bindTo(contextKeyService); this._ctxRequestInProgress = CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.bindTo(contextKeyService); @@ -381,13 +383,18 @@ export class InlineChatController implements IEditorContribution { this._sessionStore.clear(); const wholeRangeDecoration = this._editor.createDecorationsCollection(); - const updateWholeRangeDecoration = () => { + const handleWholeRangeChange = () => { const newDecorations = this._strategy?.getWholeRangeDecoration() ?? []; wholeRangeDecoration.set(newDecorations); + + this._ctxEditing.set(!this._session?.wholeRange.trackedInitialRange.isEmpty()); }; - this._sessionStore.add(toDisposable(() => wholeRangeDecoration.clear())); - this._sessionStore.add(this._session.wholeRange.onDidChange(updateWholeRangeDecoration)); - updateWholeRangeDecoration(); + this._sessionStore.add(toDisposable(() => { + wholeRangeDecoration.clear(); + this._ctxEditing.reset(); + })); + this._sessionStore.add(this._session.wholeRange.onDidChange(handleWholeRangeChange)); + handleWholeRangeChange(); this._sessionStore.add(this._ui.value.content.onDidBlur(() => this.cancelSession())); diff --git a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts index 5655fc11bf3..7245babf43d 100644 --- a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts +++ b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts @@ -83,6 +83,7 @@ export const enum InlineChatResponseType { export const CTX_INLINE_CHAT_HAS_AGENT = new RawContextKey('inlineChatHasProvider', false, localize('inlineChatHasProvider', "Whether a provider for interactive editors exists")); export const CTX_INLINE_CHAT_VISIBLE = new RawContextKey('inlineChatVisible', false, localize('inlineChatVisible', "Whether the interactive editor input is visible")); export const CTX_INLINE_CHAT_FOCUSED = new RawContextKey('inlineChatFocused', false, localize('inlineChatFocused', "Whether the interactive editor input is focused")); +export const CTX_INLINE_CHAT_EDITING = new RawContextKey('inlineChatEditing', true, localize('inlineChatEditing', "Whether the user is currently editing or generating code in the inline chat")); export const CTX_INLINE_CHAT_RESPONSE_FOCUSED = new RawContextKey('inlineChatResponseFocused', false, localize('inlineChatResponseFocused', "Whether the interactive widget's response is focused")); export const CTX_INLINE_CHAT_EMPTY = new RawContextKey('inlineChatEmpty', false, localize('inlineChatEmpty', "Whether the interactive editor input is empty")); export const CTX_INLINE_CHAT_INNER_CURSOR_FIRST = new RawContextKey('inlineChatInnerCursorFirst', false, localize('inlineChatInnerCursorFirst', "Whether the cursor of the iteractive editor input is on the first line"));