mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Reserve focus for cell chat widget. (#207000)
This commit is contained in:
parent
59ec734843
commit
c8024cf91f
|
@ -40,7 +40,7 @@ import { asProgressiveEdit, performAsyncTextEdit } from 'vs/workbench/contrib/in
|
|||
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, CTX_NOTEBOOK_CHAT_OUTER_FOCUS_POSITION, CTX_NOTEBOOK_CHAT_USER_DID_EDIT, 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 { INotebookEditor, INotebookEditorContribution, INotebookViewZone } 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';
|
||||
|
@ -96,21 +96,35 @@ class NotebookChatWidget extends Disposable implements INotebookViewZone {
|
|||
this._layoutWidget(inlineChatWidget, widgetContainer);
|
||||
}
|
||||
|
||||
hasFocus() {
|
||||
return this.inlineChatWidget.hasFocus();
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.updateNotebookEditorFocusNSelections();
|
||||
this.inlineChatWidget.focus();
|
||||
}
|
||||
|
||||
updateNotebookEditorFocusNSelections() {
|
||||
this._notebookEditor.focusContainer(true);
|
||||
this._notebookEditor.setFocus({ start: this.afterModelPosition, end: this.afterModelPosition });
|
||||
this._notebookEditor.setSelections([{
|
||||
start: this.afterModelPosition,
|
||||
end: this.afterModelPosition
|
||||
}]);
|
||||
}
|
||||
|
||||
getEditingCell() {
|
||||
return this._editingCell;
|
||||
}
|
||||
|
||||
async getOrCreateEditingCell(): Promise<{ cell: CellViewModel; editor: IActiveCodeEditor } | undefined> {
|
||||
if (this._editingCell) {
|
||||
await this._notebookEditor.focusNotebookCell(this._editingCell, 'editor');
|
||||
if (this._notebookEditor.activeCodeEditor?.hasModel()) {
|
||||
const codeEditor = this._notebookEditor.codeEditors.find(ce => ce[0] === this._editingCell)?.[1];
|
||||
if (codeEditor?.hasModel()) {
|
||||
return {
|
||||
cell: this._editingCell,
|
||||
editor: this._notebookEditor.activeCodeEditor
|
||||
editor: codeEditor
|
||||
};
|
||||
} else {
|
||||
return undefined;
|
||||
|
@ -121,17 +135,25 @@ class NotebookChatWidget extends Disposable implements INotebookViewZone {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const widgetHasFocus = this.inlineChatWidget.hasFocus();
|
||||
|
||||
this._editingCell = insertCell(this._languageService, this._notebookEditor, this.afterModelPosition, CellKind.Code, 'above');
|
||||
|
||||
if (!this._editingCell) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await this._notebookEditor.focusNotebookCell(this._editingCell, 'editor', { revealBehavior: ScrollToRevealBehavior.firstLine });
|
||||
if (this._notebookEditor.activeCodeEditor?.hasModel()) {
|
||||
await this._notebookEditor.revealFirstLineIfOutsideViewport(this._editingCell);
|
||||
|
||||
if (widgetHasFocus) {
|
||||
this.focus();
|
||||
}
|
||||
|
||||
const codeEditor = this._notebookEditor.codeEditors.find(ce => ce[0] === this._editingCell)?.[1];
|
||||
if (codeEditor?.hasModel()) {
|
||||
return {
|
||||
cell: this._editingCell,
|
||||
editor: this._notebookEditor.activeCodeEditor
|
||||
editor: codeEditor
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -390,12 +412,7 @@ export class NotebookChatController extends Disposable implements INotebookEdito
|
|||
return;
|
||||
}
|
||||
|
||||
this._notebookEditor.focusContainer(true);
|
||||
this._notebookEditor.setFocus({ start: this._widget.afterModelPosition, end: this._widget.afterModelPosition });
|
||||
this._notebookEditor.setSelections([{
|
||||
start: this._widget.afterModelPosition,
|
||||
end: this._widget.afterModelPosition
|
||||
}]);
|
||||
this._widget.updateNotebookEditorFocusNSelections();
|
||||
}
|
||||
|
||||
async acceptInput() {
|
||||
|
@ -739,6 +756,10 @@ export class NotebookChatController extends Disposable implements INotebookEdito
|
|||
await this._notebookEditor.focusNotebookCell(cell, 'editor');
|
||||
}
|
||||
|
||||
hasFocus() {
|
||||
return this._widget?.hasFocus() ?? false;
|
||||
}
|
||||
|
||||
focus() {
|
||||
this._focusWidget();
|
||||
}
|
||||
|
@ -769,6 +790,10 @@ export class NotebookChatController extends Disposable implements INotebookEdito
|
|||
this._activeRequestCts?.cancel();
|
||||
}
|
||||
|
||||
getEditingCell() {
|
||||
return this._widget?.getEditingCell();
|
||||
}
|
||||
|
||||
discard() {
|
||||
this._strategy?.cancel();
|
||||
this._activeRequestCts?.cancel();
|
||||
|
|
|
@ -20,6 +20,8 @@ import { IDebugService } from 'vs/workbench/contrib/debug/common/debug';
|
|||
import { InlineChatController } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController';
|
||||
import { CTX_INLINE_CHAT_FOCUSED } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { insertCell } from 'vs/workbench/contrib/notebook/browser/controller/cellOperations';
|
||||
import { CTX_NOTEBOOK_CELL_CHAT_FOCUSED } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext';
|
||||
import { NotebookChatController } from 'vs/workbench/contrib/notebook/browser/controller/chat/notebookChatController';
|
||||
import { CELL_TITLE_CELL_GROUP_ID, CellToolbarOrder, INotebookActionContext, INotebookCellActionContext, INotebookCellToolbarActionContext, INotebookCommandContext, NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT, NotebookAction, NotebookCellAction, NotebookMultiCellAction, cellExecutionArgs, executeNotebookCondition, getContextFromActiveEditor, getContextFromUri, parseMultiCellExecutionArgs } from 'vs/workbench/contrib/notebook/browser/controller/coreActions';
|
||||
import { CellEditState, CellFocusMode, EXECUTE_CELL_COMMAND_ID, IFocusNotebookCellOptions, ScrollToRevealBehavior } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons';
|
||||
|
@ -198,7 +200,10 @@ registerAction2(class ExecuteCell extends NotebookMultiCellAction {
|
|||
precondition: executeThisCellCondition,
|
||||
title: localize('notebookActions.execute', "Execute Cell"),
|
||||
keybinding: {
|
||||
when: NOTEBOOK_CELL_LIST_FOCUSED,
|
||||
when: ContextKeyExpr.or(
|
||||
NOTEBOOK_CELL_LIST_FOCUSED,
|
||||
ContextKeyExpr.and(CTX_NOTEBOOK_CELL_CHAT_FOCUSED, CTX_INLINE_CHAT_FOCUSED)
|
||||
),
|
||||
primary: KeyMod.WinCtrl | KeyCode.Enter,
|
||||
win: {
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter
|
||||
|
@ -229,6 +234,21 @@ registerAction2(class ExecuteCell extends NotebookMultiCellAction {
|
|||
await context.notebookEditor.focusNotebookCell(context.cell, 'container', { skipReveal: true });
|
||||
}
|
||||
|
||||
const chatController = NotebookChatController.get(context.notebookEditor);
|
||||
const editingCell = chatController?.getEditingCell();
|
||||
if (chatController?.hasFocus() && editingCell) {
|
||||
const group = editorGroupsService.activeGroup;
|
||||
|
||||
if (group) {
|
||||
if (group.activeEditor) {
|
||||
group.pinEditor(group.activeEditor);
|
||||
}
|
||||
}
|
||||
|
||||
await context.notebookEditor.executeNotebookCells([editingCell]);
|
||||
return;
|
||||
}
|
||||
|
||||
await runCell(editorGroupsService, context);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -629,6 +629,11 @@ export interface INotebookEditor {
|
|||
*/
|
||||
revealInCenterIfOutsideViewport(cell: ICellViewModel): Promise<void>;
|
||||
|
||||
/**
|
||||
* Reveal the first line of the cell into the view if the cell is outside of the viewport.
|
||||
*/
|
||||
revealFirstLineIfOutsideViewport(cell: ICellViewModel): Promise<void>;
|
||||
|
||||
/**
|
||||
* Reveal a line in notebook cell into viewport with minimal scrolling.
|
||||
*/
|
||||
|
|
|
@ -2122,8 +2122,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
|
|||
await this._list.revealCell(cell, CellRevealType.CenterIfOutsideViewport);
|
||||
}
|
||||
|
||||
revealFirstLineIfOutsideViewport(cell: ICellViewModel) {
|
||||
this._list.revealCell(cell, CellRevealType.FirstLineIfOutsideViewport);
|
||||
async revealFirstLineIfOutsideViewport(cell: ICellViewModel) {
|
||||
await this._list.revealCell(cell, CellRevealType.FirstLineIfOutsideViewport);
|
||||
}
|
||||
|
||||
async revealLineInViewAsync(cell: ICellViewModel, line: number): Promise<void> {
|
||||
|
@ -2446,7 +2446,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
|
|||
this._cursorNavMode.set(true);
|
||||
await this.revealInView(cell);
|
||||
} else if (options?.revealBehavior === ScrollToRevealBehavior.firstLine) {
|
||||
this.revealFirstLineIfOutsideViewport(cell);
|
||||
await this.revealFirstLineIfOutsideViewport(cell);
|
||||
} else if (options?.revealBehavior === ScrollToRevealBehavior.fullCell) {
|
||||
await this.revealInView(cell);
|
||||
} else {
|
||||
|
|
|
@ -925,8 +925,12 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
|
|||
break;
|
||||
}
|
||||
|
||||
// wait for the editor to be created only if the cell is in editing mode (meaning it has an editor and will focus the editor)
|
||||
if (cell.getEditState() === CellEditState.Editing && !cell.editorAttached) {
|
||||
if ((
|
||||
// wait for the editor to be created if the cell is in editing mode
|
||||
cell.getEditState() === CellEditState.Editing
|
||||
// wait for the editor to be created if we are revealing the first line of the cell
|
||||
|| revealType === CellRevealType.FirstLineIfOutsideViewport
|
||||
) && !cell.editorAttached) {
|
||||
return getEditorAttachedPromise(cell);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue