Skip to content

Commit

Permalink
Notebook: Support for Alt+Enter keybinding (#14022)
Browse files Browse the repository at this point in the history
Co-authored-by: Mark Sujew <mark.sujew@typefox.io>
  • Loading branch information
dhuebner and msujew authored Aug 7, 2024
1 parent 1e5fb53 commit 5255c51
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,14 @@ export class NotebookActionsContribution implements CommandContribution, MenuCon

if (change === CellChangeDirection.Up && currentIndex > 0) {
model.setSelectedCell(model.cells[currentIndex - 1]);
if (model.selectedCell?.cellKind === CellKind.Code && shouldFocusEditor) {
if ((model.selectedCell?.cellKind === CellKind.Code
|| (model.selectedCell?.cellKind === CellKind.Markup && model.selectedCell?.editing)) && shouldFocusEditor) {
model.selectedCell.requestFocusEditor('lastLine');
}
} else if (change === CellChangeDirection.Down && currentIndex < model.cells.length - 1) {
model.setSelectedCell(model.cells[currentIndex + 1]);
if (model.selectedCell?.cellKind === CellKind.Code && shouldFocusEditor) {
if ((model.selectedCell?.cellKind === CellKind.Code
|| (model.selectedCell?.cellKind === CellKind.Markup && model.selectedCell?.editing)) && shouldFocusEditor) {
model.selectedCell.requestFocusEditor();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ export namespace NotebookCellCommands {
/** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
export const EDIT_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.edit',
category: 'Notebook',
iconClass: codicon('edit')
});
/** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
export const STOP_EDIT_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.stop-edit',
category: 'Notebook',
iconClass: codicon('check')
});
/** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
Expand All @@ -59,11 +61,21 @@ export namespace NotebookCellCommands {
/** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
export const EXECUTE_SINGLE_CELL_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.execute-cell',
category: 'Notebook',
label: nls.localizeByDefault('Execute Cell'),
iconClass: codicon('play'),
});
/** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
export const EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.execute-cell-and-focus-next',
label: nls.localizeByDefault('Execute Notebook Cell and Select Below'),
category: 'Notebook',
});
/** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
export const EXECUTE_SINGLE_CELL_AND_INSERT_BELOW_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.execute-cell-and-insert-below',
label: nls.localizeByDefault('Execute Notebook Cell and Insert Below'),
category: 'Notebook',
});

export const EXECUTE_ABOVE_CELLS_COMMAND = Command.toDefaultLocalizedCommand({
Expand All @@ -85,11 +97,13 @@ export namespace NotebookCellCommands {
/** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
export const CLEAR_OUTPUTS_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.clear-outputs',
category: 'Notebook',
label: 'Clear Cell Outputs',
});
/** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel | undefined, output: NotebookCellOutputModel */
export const CHANGE_OUTPUT_PRESENTATION_COMMAND = Command.toDefaultLocalizedCommand({
id: 'notebook.cell.change-presentation',
category: 'Notebook',
label: 'Change Presentation',
});

Expand All @@ -114,11 +128,13 @@ export namespace NotebookCellCommands {

export const TO_CODE_CELL_COMMAND = Command.toLocalizedCommand({
id: 'notebook.cell.changeToCode',
category: 'Notebook',
label: 'Change Cell to Code'
});

export const TO_MARKDOWN_CELL_COMMAND = Command.toLocalizedCommand({
id: 'notebook.cell.changeToMarkdown',
category: 'Notebook',
label: 'Change Cell to Markdown'
});

Expand Down Expand Up @@ -302,6 +318,23 @@ export class NotebookCellActionContribution implements MenuContribution, Command
}
})
);
commands.registerCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_INSERT_BELOW_COMMAND, this.editableCellCommandHandler(
async (notebookModel, cell) => {
if (cell.cellKind === CellKind.Code) {
await commands.executeCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id, notebookModel, cell);
}
await commands.executeCommand(NotebookCellCommands.STOP_EDIT_COMMAND.id, notebookModel, cell);

if (cell.cellKind === CellKind.Code) {
await commands.executeCommand(NotebookCellCommands.INSERT_NEW_CELL_BELOW_COMMAND.id);
} else {
await commands.executeCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_BELOW_COMMAND.id);
}

const index = notebookModel.cells.indexOf(cell);
notebookModel.setSelectedCell(notebookModel.cells[index + 1]);
})
);

commands.registerCommand(NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND, this.editableCellCommandHandler(
(notebookModel, cell) => {
Expand Down Expand Up @@ -432,8 +465,8 @@ export class NotebookCellActionContribution implements MenuContribution, Command
},
{
command: NotebookCellCommands.STOP_EDIT_COMMAND.id,
keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Alt] }).toString(),
when: `editorTextFocus && !inputFocus && ${NOTEBOOK_EDITOR_FOCUSED}`,
keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Alt, KeyModifier.CtrlCmd] }).toString(),
when: `editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'markdown'`,
},
{
command: NotebookCellCommands.STOP_EDIT_COMMAND.id,
Expand All @@ -450,6 +483,11 @@ export class NotebookCellActionContribution implements MenuContribution, Command
keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Shift] }).toString(),
when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
},
{
command: NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_INSERT_BELOW_COMMAND.id,
keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Alt] }).toString(),
when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
},
{
command: NotebookCellCommands.CLEAR_OUTPUTS_COMMAND.id,
keybinding: KeyCode.createKeyCode({ first: Key.KEY_O, modifiers: [KeyModifier.Alt] }).toString(),
Expand Down
3 changes: 0 additions & 3 deletions packages/notebook/src/browser/notebook-editor-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
@postConstruct()
protected init(): void {
this.id = NOTEBOOK_EDITOR_ID_PREFIX + this.props.uri.toString();
this.node.tabIndex = -1;

this.scrollOptions = {
suppressScrollY: true
Expand All @@ -174,8 +173,6 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
this.commandRegistry.executeCommand(NotebookCellCommands.EDIT_COMMAND.id, model, model.cells[0]);
model.setSelectedCell(model.cells[0]);
}
model.cells.forEach(cell => cell.onWillBlurCellEditor(() => this.node.focus()));
model.onDidAddOrRemoveCell(e => e.newCellIds?.forEach(cellId => model.cells.find(cell => cell.handle === cellId)?.onWillBlurCellEditor(() => this.node.focus())));
});
}

Expand Down
10 changes: 10 additions & 0 deletions packages/notebook/src/browser/view/notebook-cell-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
this.props.notebookContextManager.scopedStore.setContext(NOTEBOOK_CELL_CURSOR_LAST_LINE, currentLine === lineCount);
}));

this.toDispose.push(this.props.cell.onWillBlurCellEditor(() => {
let parent = this.container?.parentElement;
while (parent && !parent.classList.contains('theia-notebook-cell')) {
parent = parent.parentElement;
}
if (parent) {
parent.focus();
}
}));

this.toDispose.push(this.props.cell.onDidChangeEditorOptions(options => {
this.editor?.getControl().updateOptions(options);
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,14 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
onDrop={e => this.onDrop(e, index)}
draggable={true}
tabIndex={-1}
ref={ref => cell === this.state.selectedCell && this.state.scrollIntoView && ref?.scrollIntoView({ block: 'nearest' })}>
ref={ref => {
if (ref && cell === this.state.selectedCell && this.state.scrollIntoView) {
ref.scrollIntoView({ block: 'nearest' });
if (cell.cellKind === CellKind.Markup && !cell.editing) {
ref.focus();
}
}
}}>
<div className={'theia-notebook-cell-marker' + (this.state.selectedCell === cell ? ' theia-notebook-cell-marker-selected' : '')}></div>
<div className='theia-notebook-cell-content'>
{this.renderCellContent(cell, index)}
Expand Down

0 comments on commit 5255c51

Please sign in to comment.