diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts b/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts index 2db562cf9c9..4a1df5b9ce8 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts @@ -30,7 +30,7 @@ export class SuggestWidgetStatus { this.element = dom.append(container, dom.$('.suggest-status-bar')); const actionViewItemProvider = (action => { - return action instanceof MenuItemAction ? instantiationService.createInstance(TextOnlyMenuEntryActionViewItem, action, undefined) : undefined; + return action instanceof MenuItemAction ? instantiationService.createInstance(TextOnlyMenuEntryActionViewItem, action, { useComma: true }) : undefined; }); this._leftActions = new ActionBar(this.element, { actionViewItemProvider }); this._rightActions = new ActionBar(this.element, { actionViewItemProvider }); diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.css b/src/vs/platform/actions/browser/menuEntryActionViewItem.css index 7a75d9f62fd..7eb35af7e4b 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.css +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.css @@ -17,7 +17,7 @@ border-radius: 2px; } -.monaco-action-bar .action-item.menu-entry.text-only:not(:last-of-type) .action-label::after { +.monaco-action-bar .action-item.menu-entry.text-only.use-comma:not(:last-of-type) .action-label::after { content: ', '; } diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index da6ca0985ae..68380cddacf 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -288,6 +288,7 @@ export class MenuEntryActionViewItem { @@ -297,6 +298,7 @@ export class TextOnlyMenuEntryActionViewItem extends MenuEntryActionViewItem void; + + constructor(@IConfigurationService configService: IConfigurationService,) { + + const store = new DisposableStore(); + function updateMenu() { + if (configService.getValue(InlineChatConfigKeys.ExpTextButtons)) { + store.clear(); + for (const item of MenuRegistry.getMenuItems(MenuId.ChatExecute)) { + if (isIMenuItem(item) && (item.command.id === SubmitAction.ID || item.command.id === CancelAction.ID)) { + continue; + } + store.add(MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_EXECUTE, item)); + } + } + } + updateMenu(); + const listener = MenuRegistry.onDidChangeMenu(e => { + if (e.has(MenuId.ChatExecute)) { + updateMenu(); + } + }); + + this.dispose = () => { + listener.dispose(); + store.dispose(); + }; + } +} + +registerWorkbenchContribution2(MenuCopier.Id, MenuCopier, WorkbenchPhase.AfterRestored); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 32e617d9452..063e2de835c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -11,7 +11,7 @@ import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/diffEditor/em import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/codeEditor/embeddedCodeEditorWidget'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { InlineChatController, InlineChatRunOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; -import { ACTION_ACCEPT_CHANGES, CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_USER_DID_EDIT, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_EDIT_MODE, EditMode, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, InlineChatResponseType, ACTION_REGENERATE_RESPONSE, MENU_INLINE_CHAT_CONTENT_STATUS, ACTION_VIEW_IN_CHAT, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF, CTX_INLINE_CHAT_CONFIG_TXT_BTNS } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { ACTION_ACCEPT_CHANGES, CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_USER_DID_EDIT, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_EDIT_MODE, EditMode, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, InlineChatResponseType, ACTION_REGENERATE_RESPONSE, MENU_INLINE_CHAT_CONTENT_STATUS, ACTION_VIEW_IN_CHAT, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { localize, localize2 } from 'vs/nls'; import { Action2, IAction2Options } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -368,7 +368,7 @@ export class CloseAction extends AbstractInlineChatAction { group: '0_main', order: 1, when: ContextKeyExpr.and( - // CTX_INLINE_CHAT_CONFIG_TXT_BTNS, + CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.negate(), ContextKeyExpr.or( CTX_INLINE_CHAT_RESPONSE_TYPE.isEqualTo(InlineChatResponseType.Messages), CTX_INLINE_CHAT_EDIT_MODE.isEqualTo(EditMode.Preview) @@ -498,7 +498,7 @@ export class ViewInChatAction extends AbstractInlineChatAction { order: 1, when: ContextKeyExpr.and( CTX_INLINE_CHAT_RESPONSE_TYPE.isEqualTo(InlineChatResponseType.Messages), - CTX_INLINE_CHAT_CONFIG_TXT_BTNS + CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.negate() ) }], keybinding: { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts index 199f66d0c42..a10f96a8be0 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts @@ -11,7 +11,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { inlineChatBackground, MENU_INLINE_CHAT_CONTENT_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { inlineChatBackground, InlineChatConfigKeys, MENU_INLINE_CHAT_CONTENT_STATUS, MENU_INLINE_CHAT_EXECUTE } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { Session } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession'; import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget'; import { ChatAgentLocation } from 'vs/workbench/contrib/chat/common/chatAgents'; @@ -25,6 +25,7 @@ import { ScrollType } from 'vs/editor/common/editorCommon'; import { MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; import { MenuItemAction } from 'vs/platform/actions/common/actions'; import { TextOnlyMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class InlineChatContentWidget implements IContentWidget { @@ -52,6 +53,7 @@ export class InlineChatContentWidget implements IContentWidget { private readonly _editor: ICodeEditor, @IInstantiationService instaService: IInstantiationService, @IContextKeyService contextKeyService: IContextKeyService, + @IConfigurationService configurationService: IConfigurationService ) { this._defaultChatModel = this._store.add(instaService.createInstance(ChatModel, undefined, ChatAgentLocation.Editor)); @@ -76,7 +78,8 @@ export class InlineChatContentWidget implements IContentWidget { renderFollowups: true, supportsFileReferences: false, menus: { - telemetrySource: 'inlineChat-content' + telemetrySource: 'inlineChat-content', + executeToolbar: MENU_INLINE_CHAT_EXECUTE, }, filter: _item => false }, @@ -98,6 +101,10 @@ export class InlineChatContentWidget implements IContentWidget { this._domNode.appendChild(this._inputContainer); this._toolbarContainer.classList.add('toolbar'); + if (!configurationService.getValue(InlineChatConfigKeys.ExpTextButtons)) { + this._toolbarContainer.style.display = 'none'; + this._domNode.style.paddingBottom = '6px'; + } this._domNode.appendChild(this._toolbarContainer); this._store.add(scopedInstaService.createInstance(MenuWorkbenchToolBar, this._toolbarContainer, MENU_INLINE_CHAT_CONTENT_STATUS, { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts index e4128063fc2..793600ccf0c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts @@ -14,7 +14,7 @@ import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget'; import { localize } from 'vs/nls'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, EditMode, InlineChatConfigKeys, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, EditMode, InlineChatConfigKeys, MENU_INLINE_CHAT_EXECUTE, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { EditorBasedInlineChatWidget } from './inlineChatWidget'; import { isEqual } from 'vs/base/common/resources'; import { StableEditorBottomScrollState } from 'vs/editor/browser/stableEditorScroll'; @@ -63,7 +63,7 @@ export class InlineChatZoneWidget extends ZoneWidget { }, chatWidgetViewOptions: { menus: { - inputSideToolbar: MENU_INLINE_CHAT_WIDGET, + executeToolbar: MENU_INLINE_CHAT_EXECUTE, telemetrySource: 'interactiveEditorWidget-toolbar', }, rendererOptions: { diff --git a/src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css b/src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css index 79fba8eddb9..b2efaecda49 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css +++ b/src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css @@ -13,7 +13,7 @@ .monaco-workbench .inline-chat { color: inherit; - padding: 0 8px 8px 8px; + padding: 0 8px; border-radius: 4px; border: 1px solid var(--vscode-inlineChat-border); box-shadow: 0 2px 4px 0 var(--vscode-widget-shadow); @@ -21,10 +21,6 @@ background: var(--vscode-inlineChat-background); } -.monaco-workbench .inline-chat.toolbar { - padding-bottom: 4px; -} - .monaco-workbench .inline-chat .chat-widget .interactive-session .interactive-input-part .interactive-execute-toolbar { margin-bottom: 1px; } @@ -74,7 +70,6 @@ display: flex; justify-content: space-between; align-items: center; - margin-top: 3px; /*makes space for action focus borders: https://github.com/microsoft/vscode-copilot/issues/5814 */ } .monaco-workbench .inline-chat .status .actions.hidden { @@ -147,24 +142,35 @@ display: none; } -.monaco-workbench .inline-chat .status .actions { +.monaco-workbench .inline-chat .status .actions, +.monaco-workbench .inline-chat-content-widget .toolbar { + display: flex; - padding-top: 3px; -} + height: 18px; + padding: 3px 0; /* makes space for action focus borders: https://github.com/microsoft/vscode-copilot/issues/5814 */ -.monaco-workbench .inline-chat .status .actions .action-item.text-only .action-label, -.monaco-workbench .inline-chat-content-widget .status .actions .action-item.text-only .action-label { - font-size: 12px; - line-height: 16px; - padding: 2px; - border-radius: 2px; -} + .actions-container { + gap: 3px + } -.monaco-action-bar .action-item.menu-entry.text-only + .action-item:not(.text-only) > .monaco-dropdown .action-label { - font-size: 12px; - line-height: 16px; - width: unset; - height: unset; + .action-item.text-only .action-label { + font-size: 12px; + line-height: 16px; + padding: 1px 2px; + border-radius: 3px; + } + + .monaco-action-bar .action-item.menu-entry.text-only:first-of-type .action-label{ + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-background); + } + + .monaco-action-bar .action-item.menu-entry.text-only + .action-item:not(.text-only) > .monaco-dropdown .action-label { + font-size: 12px; + line-height: 16px; + width: unset; + height: unset; + } } .monaco-workbench .inline-chat .status .actions > .monaco-button, diff --git a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts index 7cb071748be..4039811d60d 100644 --- a/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts +++ b/src/vs/workbench/contrib/inlineChat/common/inlineChat.ts @@ -116,7 +116,7 @@ export const ACTION_TOGGLE_DIFF = 'inlineChat.toggleDiff'; // --- menus -export const MENU_INLINE_CHAT_WIDGET = MenuId.for('inlineChatWidget'); +export const MENU_INLINE_CHAT_EXECUTE = MenuId.for('inlineChat.execute'); export const MENU_INLINE_CHAT_CONTENT_STATUS = MenuId.for('inlineChat.content.status'); export const MENU_INLINE_CHAT_WIDGET_STATUS = MenuId.for('inlineChatWidget.status'); diff --git a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController.ts b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController.ts index 5558c1a7b69..fc164d21321 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController.ts @@ -36,7 +36,6 @@ import { countWords } from 'vs/workbench/contrib/chat/common/chatWordCounter'; import { ProgressingEditsOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatStrategies'; import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatWidget'; import { asProgressiveEdit, performAsyncTextEdit } from 'vs/workbench/contrib/inlineChat/browser/utils'; -import { MENU_INLINE_CHAT_WIDGET } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { insertCell, runDeleteAction } from 'vs/workbench/contrib/notebook/browser/controller/cellOperations'; import { CTX_NOTEBOOK_CELL_CHAT_FOCUSED, CTX_NOTEBOOK_CHAT_HAS_ACTIVE_REQUEST, CTX_NOTEBOOK_CHAT_OUTER_FOCUS_POSITION, CTX_NOTEBOOK_CHAT_USER_DID_EDIT, MENU_CELL_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext'; import { ICellViewModel, INotebookEditor, INotebookEditorContribution, INotebookViewZone } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; @@ -423,8 +422,7 @@ export class NotebookChatController extends Disposable implements INotebookEdito } }, menus: { - telemetrySource: 'notebook-generate-cell', - inputSideToolbar: MENU_INLINE_CHAT_WIDGET, + telemetrySource: 'notebook-generate-cell' } } }