diff --git a/src/vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions.ts index 8d6325c6b26..5959e33fcd7 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions.ts @@ -14,7 +14,8 @@ import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkey import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChatResponseFeedbackKind, InlineChatResponseTypes } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; -import { CTX_NOTEBOOK_CELL_CHAT_FOCUSED, CTX_NOTEBOOK_CHAT_HAS_ACTIVE_REQUEST, MENU_CELL_CHAT_INPUT, MENU_CELL_CHAT_WIDGET, MENU_CELL_CHAT_WIDGET_FEEDBACK, MENU_CELL_CHAT_WIDGET_STATUS, NotebookChatController } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController'; +import { CTX_NOTEBOOK_CELL_CHAT_FOCUSED, CTX_NOTEBOOK_CHAT_HAS_ACTIVE_REQUEST, MENU_CELL_CHAT_INPUT, MENU_CELL_CHAT_WIDGET, MENU_CELL_CHAT_WIDGET_FEEDBACK, MENU_CELL_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext'; +import { NotebookChatController } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController'; import { INotebookActionContext, INotebookCellActionContext, NotebookAction, NotebookCellAction, getEditorFromArgsOrActivePane } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; import { CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellKind, NOTEBOOK_EDITOR_CURSOR_BOUNDARY, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -87,7 +88,7 @@ registerAction2(class extends NotebookCellAction { } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super( { @@ -106,7 +107,7 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { await NotebookChatController.get(context.notebookEditor)?.focusNext(); } }); @@ -171,7 +172,7 @@ registerAction2(class extends NotebookCellAction { } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super( { @@ -187,12 +188,12 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.cancelCurrentRequest(false); } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super( { @@ -207,7 +208,7 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.dismiss(); } }); @@ -237,12 +238,12 @@ registerAction2(class extends NotebookAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.acceptSession(); } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super( { @@ -262,12 +263,12 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.discard(); } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super({ id: 'notebook.cell.feedbackHelpful', @@ -282,12 +283,12 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.feedbackLast(InlineChatResponseFeedbackKind.Helpful); } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super({ id: 'notebook.cell.feedbackUnhelpful', @@ -302,12 +303,12 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.feedbackLast(InlineChatResponseFeedbackKind.Unhelpful); } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookAction { constructor() { super({ id: 'notebook.cell.reportIssueForBug', @@ -322,7 +323,7 @@ registerAction2(class extends NotebookCellAction { }); } - async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) { + async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext) { NotebookChatController.get(context.notebookEditor)?.feedbackLast(InlineChatResponseFeedbackKind.Bug); } }); diff --git a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts new file mode 100644 index 00000000000..995340fb191 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions'; diff --git a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext.ts b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext.ts new file mode 100644 index 00000000000..af75c65626d --- /dev/null +++ b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { MenuId } from 'vs/platform/actions/common/actions'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; + +export const CTX_NOTEBOOK_CELL_CHAT_FOCUSED = new RawContextKey('notebookCellChatFocused', false, localize('notebookCellChatFocused', "Whether the cell chat editor is focused")); +export const CTX_NOTEBOOK_CHAT_HAS_ACTIVE_REQUEST = new RawContextKey('notebookChatHasActiveRequest', false, localize('notebookChatHasActiveRequest', "Whether the cell chat editor has an active request")); +export const MENU_CELL_CHAT_INPUT = MenuId.for('cellChatInput'); +export const MENU_CELL_CHAT_WIDGET = MenuId.for('cellChatWidget'); +export const MENU_CELL_CHAT_WIDGET_STATUS = MenuId.for('cellChatWidget.status'); +export const MENU_CELL_CHAT_WIDGET_FEEDBACK = MenuId.for('cellChatWidget.feedback'); +export const MENU_CELL_CHAT_WIDGET_TOOLBAR = MenuId.for('cellChatWidget.toolbar'); 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 86aadb52b8d..99b982368a2 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController.ts @@ -26,9 +26,8 @@ import { ICursorStateComputer, ITextModel } from 'vs/editor/common/model'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; import { IModelService } from 'vs/editor/common/services/model'; import { localize } from 'vs/nls'; -import { MenuId } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { AsyncProgress } from 'vs/platform/progress/common/progress'; import { SaveReason } from 'vs/workbench/common/editor'; @@ -41,21 +40,13 @@ import { InlineChatWidget } from 'vs/workbench/contrib/inlineChat/browser/inline import { asProgressiveEdit, performAsyncTextEdit } from 'vs/workbench/contrib/inlineChat/browser/utils'; import { CTX_INLINE_CHAT_LAST_RESPONSE_TYPE, EditMode, IInlineChatProgressItem, IInlineChatRequest, InlineChatResponseFeedbackKind, InlineChatResponseType } 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, MENU_CELL_CHAT_INPUT, MENU_CELL_CHAT_WIDGET, MENU_CELL_CHAT_WIDGET_FEEDBACK, MENU_CELL_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext'; import { INotebookEditor, INotebookEditorContribution, INotebookViewZone, ScrollToRevealBehavior } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { registerNotebookContribution } from 'vs/workbench/contrib/notebook/browser/notebookEditorExtensions'; import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl'; import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import 'vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions'; - -export const CTX_NOTEBOOK_CELL_CHAT_FOCUSED = new RawContextKey('notebookCellChatFocused', false, localize('notebookCellChatFocused', "Whether the cell chat editor is focused")); -export const CTX_NOTEBOOK_CHAT_HAS_ACTIVE_REQUEST = new RawContextKey('notebookChatHasActiveRequest', false, localize('notebookChatHasActiveRequest', "Whether the cell chat editor has an active request")); -export const MENU_CELL_CHAT_INPUT = MenuId.for('cellChatInput'); -export const MENU_CELL_CHAT_WIDGET = MenuId.for('cellChatWidget'); -export const MENU_CELL_CHAT_WIDGET_STATUS = MenuId.for('cellChatWidget.status'); -export const MENU_CELL_CHAT_WIDGET_FEEDBACK = MenuId.for('cellChatWidget.feedback'); -export const MENU_CELL_CHAT_WIDGET_TOOLBAR = MenuId.for('cellChatWidget.toolbar'); const WIDGET_MARGIN_BOTTOM = 16; diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index bcc27365df5..cf5cf217587 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -67,6 +67,7 @@ import 'vs/workbench/contrib/notebook/browser/controller/editActions'; import 'vs/workbench/contrib/notebook/browser/controller/cellOutputActions'; import 'vs/workbench/contrib/notebook/browser/controller/apiActions'; import 'vs/workbench/contrib/notebook/browser/controller/foldingController'; +import 'vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution'; // Editor Contribution import 'vs/workbench/contrib/notebook/browser/contrib/editorHint/emptyCellEditorHint'; diff --git a/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts b/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts index 62cf6f3b766..e613e8af3e6 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts @@ -592,6 +592,11 @@ export class NotebookCellList extends WorkbenchList implements ID return modelIndex; } + if (modelIndex >= this.hiddenRangesPrefixSum.getTotalSum()) { + // it's already after the last hidden range + return this.hiddenRangesPrefixSum.getTotalSum(); + } + return this.hiddenRangesPrefixSum.getIndexOf(modelIndex).index; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/notebookCellListView.ts b/src/vs/workbench/contrib/notebook/browser/view/notebookCellListView.ts index c2752fe8103..8ff1afea0c1 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/notebookCellListView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/notebookCellListView.ts @@ -49,6 +49,15 @@ export class NotebookCellsLayout implements IRangeMap { this._size = this._paddingTop; } + getWhitespaces(): IWhitespace[] { + return this._whitespace; + } + + restoreWhitespace(items: IWhitespace[]) { + this._whitespace = items; + this._size = this._paddingTop + this._items.reduce((total, item) => total + item.size, 0) + this._whitespace.reduce((total, ws) => total + ws.size, 0); + } + /** */ splice(index: number, deleteCount: number, items?: IItem[] | undefined): void { @@ -240,7 +249,15 @@ export class NotebookCellListView extends ListView { } protected override createRangeMap(paddingTop: number): IRangeMap { - return new NotebookCellsLayout(paddingTop); + const existingMap = this.rangeMap as NotebookCellsLayout | undefined; + if (existingMap) { + const layout = new NotebookCellsLayout(paddingTop); + layout.restoreWhitespace(existingMap.getWhitespaces()); + return layout; + } else { + return new NotebookCellsLayout(paddingTop); + } + } insertWhitespace(afterPosition: number, size: number): string {