Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use correct cell type for selected language #13983

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { NotebookModel } from '../view-model/notebook-model';
* a collection of different reusable notbook cell operations
*/

export function changeCellType(notebookModel: NotebookModel, cell: NotebookCellModel, type: CellKind): void {
export function changeCellType(notebookModel: NotebookModel, cell: NotebookCellModel, type: CellKind, language?: string): void {
if (cell.cellKind === type) {
return;
}
Expand All @@ -32,7 +32,8 @@ export function changeCellType(notebookModel: NotebookModel, cell: NotebookCellM
count: 1,
cells: [{
...cell.getData(),
cellKind: type
cellKind: type,
language: language ?? cell.language
}]
}], true);
}
Original file line number Diff line number Diff line change
Expand Up @@ -370,18 +370,25 @@ export class NotebookCellActionContribution implements MenuContribution, Command
return;
}
const language = await this.languageQuickPickService.pickEditorLanguage(selectedCell.language);
if (!language?.value || language.value === 'autoDetect') {
if (!language?.value || language.value === 'autoDetect' || language.value.id === selectedCell.language) {
return;
}
if (language.value.id === 'markdown') {
selectedCell.language = 'markdown';
changeCellType(activeNotebook, selectedCell, CellKind.Markup);
const isMarkdownCell = selectedCell.cellKind === CellKind.Markup;
const isMarkdownLanguage = language.value.id === 'markdown';
if (isMarkdownLanguage) {
if (!isMarkdownCell) {
changeCellType(activeNotebook, selectedCell, CellKind.Markup, language.value.id);
}
} else {
this.notebookEditorWidgetService.focusedEditor?.model?.applyEdits([{
editType: CellEditType.CellLanguage,
index: activeNotebook.cells.indexOf(selectedCell),
language: language.value.id
}], true);
if (isMarkdownCell) {
changeCellType(activeNotebook, selectedCell, CellKind.Code, language.value.id);
} else {
this.notebookEditorWidgetService.focusedEditor?.model?.applyEdits([{
editType: CellEditType.CellLanguage,
index: activeNotebook.cells.indexOf(selectedCell),
language: language.value.id
}], true);
}
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions packages/notebook/src/browser/style/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@
}

/* Markdown cell edit mode */
.theia-notebook-cell-content:has(> .theia-notebook-cell-editor) {
.theia-notebook-cell-content:has(.theia-notebook-markdown-editor-container>.theia-notebook-cell-editor) {
margin-left: 37px;
margin-right: var(--theia-notebook-cell-editor-margin-right);
outline: 1px solid var(--theia-notebook-cellBorderColor);
}

/* Markdown cell edit mode focused */
.theia-notebook-cell.focused .theia-notebook-cell-content:has(> .theia-notebook-cell-editor) {
.theia-notebook-cell.focused .theia-notebook-cell-content:has(.theia-notebook-markdown-editor-container>.theia-notebook-cell-editor) {
outline-color: var(--theia-notebook-focusedEditorBorder);
}

Expand Down
36 changes: 19 additions & 17 deletions packages/notebook/src/browser/view/notebook-code-cell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export interface NotebookCodeCellStatusProps {
notebook: NotebookModel;
cell: NotebookCellModel;
commandRegistry: CommandRegistry;
executionStateService: NotebookExecutionStateService;
executionStateService?: NotebookExecutionStateService;
onClick: () => void;
}

Expand All @@ -171,22 +171,24 @@ export class NotebookCodeCellStatus extends React.Component<NotebookCodeCellStat
};

let currentInterval: NodeJS.Timeout | undefined;
this.toDispose.push(props.executionStateService.onDidChangeExecution(event => {
if (event.affectsCell(this.props.cell.uri)) {
this.setState({ currentExecution: event.changed, executionTime: 0 });
clearInterval(currentInterval);
if (event.changed?.state === NotebookCellExecutionState.Executing) {
const startTime = Date.now();
// The resolution of the time display is only a single digit after the decimal point.
// Therefore, we only need to update the display every 100ms.
currentInterval = setInterval(() => {
this.setState({
executionTime: Date.now() - startTime
});
}, 100);
if (props.executionStateService) {
this.toDispose.push(props.executionStateService.onDidChangeExecution(event => {
if (event.affectsCell(this.props.cell.uri)) {
this.setState({ currentExecution: event.changed, executionTime: 0 });
clearInterval(currentInterval);
if (event.changed?.state === NotebookCellExecutionState.Executing) {
const startTime = Date.now();
// The resolution of the time display is only a single digit after the decimal point.
// Therefore, we only need to update the display every 100ms.
currentInterval = setInterval(() => {
this.setState({
executionTime: Date.now() - startTime
});
}, 100);
}
}
}
}));
}));
}

this.toDispose.push(props.cell.onDidChangeLanguage(() => {
this.forceUpdate();
Expand All @@ -200,7 +202,7 @@ export class NotebookCodeCellStatus extends React.Component<NotebookCodeCellStat
override render(): React.ReactNode {
return <div className='notebook-cell-status' onClick={() => this.props.onClick()}>
<div className='notebook-cell-status-left'>
{this.renderExecutionState()}
{this.props.executionStateService && this.renderExecutionState()}
</div>
<div className='notebook-cell-status-right'>
<span className='notebook-cell-language-label' onClick={() => {
Expand Down
52 changes: 39 additions & 13 deletions packages/notebook/src/browser/view/notebook-markdown-cell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import { NotebookCellModel } from '../view-model/notebook-cell-model';
import { CellEditor } from './notebook-cell-editor';
import { inject, injectable } from '@theia/core/shared/inversify';
import { MonacoEditorServices } from '@theia/monaco/lib/browser/monaco-editor';
import { nls } from '@theia/core';
import { CommandRegistry, nls } from '@theia/core';
import { NotebookContextManager } from '../service/notebook-context-manager';
import { NotebookOptionsService } from '../service/notebook-options';
import { NotebookCodeCellStatus } from './notebook-code-cell-view';
import { NotebookEditorFindMatch, NotebookEditorFindMatchOptions } from './notebook-find-widget';
import * as mark from 'advanced-mark.js';

Expand All @@ -39,9 +41,21 @@ export class NotebookMarkdownCellRenderer implements CellRenderer {
@inject(NotebookContextManager)
protected readonly notebookContextManager: NotebookContextManager;

@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;

@inject(NotebookOptionsService)
protected readonly notebookOptionsService: NotebookOptionsService;

render(notebookModel: NotebookModel, cell: NotebookCellModel): React.ReactNode {
return <MarkdownCell markdownRenderer={this.markdownRenderer} monacoServices={this.monacoServices}
cell={cell} notebookModel={notebookModel} notebookContextManager={this.notebookContextManager} />;
return <MarkdownCell
markdownRenderer={this.markdownRenderer}
commandRegistry={this.commandRegistry}
monacoServices={this.monacoServices}
notebookOptionsService={this.notebookOptionsService}
cell={cell}
notebookModel={notebookModel}
notebookContextManager={this.notebookContextManager} />;
}

renderDragImage(cell: NotebookCellModel): HTMLElement {
Expand All @@ -55,15 +69,19 @@ export class NotebookMarkdownCellRenderer implements CellRenderer {
}

interface MarkdownCellProps {
markdownRenderer: MarkdownRenderer
monacoServices: MonacoEditorServices

cell: NotebookCellModel
notebookModel: NotebookModel
notebookContextManager: NotebookContextManager
markdownRenderer: MarkdownRenderer;
monacoServices: MonacoEditorServices;

commandRegistry: CommandRegistry;
cell: NotebookCellModel;
notebookModel: NotebookModel;
notebookContextManager: NotebookContextManager;
notebookOptionsService: NotebookOptionsService;
}

function MarkdownCell({ markdownRenderer, monacoServices, cell, notebookModel, notebookContextManager }: MarkdownCellProps): React.JSX.Element {
function MarkdownCell({
markdownRenderer, monacoServices, cell, notebookModel, notebookContextManager, notebookOptionsService, commandRegistry
}: MarkdownCellProps): React.JSX.Element {
const [editMode, setEditMode] = React.useState(cell.editing);
let empty = false;

Expand Down Expand Up @@ -111,11 +129,19 @@ function MarkdownCell({ markdownRenderer, monacoServices, cell, notebookModel, n
}

return editMode ?
<CellEditor cell={cell} notebookModel={notebookModel} monacoServices={monacoServices} notebookContextManager={notebookContextManager} /> :
<div className='theia-notebook-markdown-content'
(<div className='theia-notebook-markdown-editor-container' key="code">
<CellEditor notebookModel={notebookModel} cell={cell}
monacoServices={monacoServices}
notebookContextManager={notebookContextManager}
fontInfo={notebookOptionsService.editorFontInfo} />
<NotebookCodeCellStatus cell={cell} notebook={notebookModel}
commandRegistry={commandRegistry}
onClick={() => cell.requestFocusEditor()} />
</div >) :
(<div className='theia-notebook-markdown-content' key="markdown"
onDoubleClick={() => cell.requestEdit()}
ref={node => node?.replaceChildren(markdownContent)}
/>;
/>);
}

function searchInMarkdown(instance: mark, options: NotebookEditorFindMatchOptions): NotebookEditorFindMatch[] {
Expand Down
Loading