Skip to content

Commit 826e91f

Browse files
committed
consolidate input block language options
1 parent 727f55c commit 826e91f

File tree

4 files changed

+49
-35
lines changed

4 files changed

+49
-35
lines changed

src/notebooks/deepnote/deepnoteInputBlockEditProtection.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
WorkspaceEdit
1414
} from 'vscode';
1515
import { ILogger } from '../../platform/logging/types';
16-
import { formatInputBlockCellContent } from './inputBlockContentFormatter';
16+
import { formatInputBlockCellContent, getInputBlockLanguage } from './inputBlockContentFormatter';
1717

1818
/**
1919
* Protects readonly input blocks from being edited by reverting changes.
@@ -46,19 +46,6 @@ export class DeepnoteInputBlockEditProtection implements Disposable {
4646
'button'
4747
]);
4848

49-
// Map of block types to their expected language IDs
50-
private readonly expectedLanguages = new Map<string, string>([
51-
['input-text', 'plaintext'],
52-
['input-textarea', 'plaintext'],
53-
['input-select', 'python'],
54-
['input-slider', 'python'],
55-
['input-checkbox', 'python'],
56-
['input-date', 'python'],
57-
['input-date-range', 'python'],
58-
['input-file', 'python'],
59-
['button', 'python']
60-
]);
61-
6249
constructor(@inject(ILogger) private readonly logger: ILogger) {
6350
// Listen for notebook document changes
6451
this.disposables.push(
@@ -99,7 +86,7 @@ export class DeepnoteInputBlockEditProtection implements Disposable {
9986
const blockType = cell.metadata?.__deepnotePocket?.type || cell.metadata?.type;
10087

10188
if (blockType && this.allInputTypes.has(blockType)) {
102-
const expectedLanguage = this.expectedLanguages.get(blockType);
89+
const expectedLanguage = getInputBlockLanguage(blockType);
10390
// Only add to fix list if language is actually wrong
10491
if (expectedLanguage && cell.document.languageId !== expectedLanguage) {
10592
cellsToFix.push({ cell, blockType });
@@ -149,7 +136,7 @@ export class DeepnoteInputBlockEditProtection implements Disposable {
149136
const editsByNotebook = new Map<string, { uri: Uri; edits: NotebookEdit[] }>();
150137

151138
for (const { cell, blockType } of cellsToFix) {
152-
const expectedLanguage = this.expectedLanguages.get(blockType);
139+
const expectedLanguage = getInputBlockLanguage(blockType);
153140

154141
if (!expectedLanguage) {
155142
continue;

src/notebooks/deepnote/deepnoteNotebookCommandListener.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { IExtensionSyncActivationService } from '../../platform/activation/types
1717
import { IDisposableRegistry } from '../../platform/common/types';
1818
import { Commands } from '../../platform/common/constants';
1919
import { chainWithPendingUpdates } from '../../kernels/execution/notebookUpdater';
20+
import { formatInputBlockCellContent, getInputBlockLanguage } from './inputBlockContentFormatter';
2021
import {
2122
DeepnoteBigNumberMetadataSchema,
2223
DeepnoteTextInputMetadataSchema,
@@ -281,15 +282,17 @@ export class DeepnoteNotebookCommandListener implements IExtensionSyncActivation
281282
__deepnotePocket: {
282283
type: blockType,
283284
...defaultMetadata
284-
}
285+
},
286+
...defaultMetadata
285287
};
286288

287289
const result = await chainWithPendingUpdates(document, (edit) => {
288-
const newCell = new NotebookCellData(
289-
NotebookCellKind.Code,
290-
JSON.stringify(defaultMetadata, null, 2),
291-
'json'
292-
);
290+
// Use the formatter to get the correct cell content based on block type and metadata
291+
const cellContent = formatInputBlockCellContent(blockType, defaultMetadata);
292+
// Get the correct language mode for this input block type
293+
const languageMode = getInputBlockLanguage(blockType) ?? 'python';
294+
295+
const newCell = new NotebookCellData(NotebookCellKind.Code, cellContent, languageMode);
293296
newCell.metadata = metadata;
294297
const nbEdit = NotebookEdit.insertCells(insertIndex, [newCell]);
295298
edit.set(document.uri, [nbEdit]);

src/notebooks/deepnote/deepnoteNotebookCommandListener.unit.test.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
getNextDeepnoteVariableName,
1919
InputBlockType
2020
} from './deepnoteNotebookCommandListener';
21+
import { formatInputBlockCellContent, getInputBlockLanguage } from './inputBlockContentFormatter';
2122
import { IDisposable } from '../../platform/common/types';
2223
import * as notebookUpdater from '../../kernels/execution/notebookUpdater';
2324
import { createMockedNotebookDocument } from '../../test/datascience/editor-integration/helpers';
@@ -605,20 +606,14 @@ suite('DeepnoteNotebookCommandListener', () => {
605606

606607
const newCell = notebookEdit.newCells[0];
607608
assert.equal(newCell.kind, NotebookCellKind.Code, 'Should be a code cell');
608-
assert.equal(newCell.languageId, 'json', 'Should have json language');
609609

610-
// Verify cell content is valid JSON with correct structure
611-
const content = JSON.parse(newCell.value);
612-
assert.equal(
613-
content.deepnote_variable_name,
614-
expectedVariableName,
615-
'Variable name should match expected'
616-
);
610+
// Verify language mode matches the expected language for this block type
611+
const expectedLanguage = getInputBlockLanguage(blockType);
612+
assert.equal(newCell.languageId, expectedLanguage, `Should have ${expectedLanguage} language`);
617613

618-
// Verify all expected metadata keys are present in content
619-
expectedMetadataKeys.forEach((key) => {
620-
assert.property(content, key, `Content should have ${key} property`);
621-
});
614+
// Verify cell content is formatted correctly using the formatter
615+
const expectedContent = formatInputBlockCellContent(blockType, newCell.metadata);
616+
assert.equal(newCell.value, expectedContent, 'Cell content should match formatted content');
622617

623618
// Verify metadata structure
624619
assert.property(newCell.metadata, '__deepnotePocket', 'Should have __deepnotePocket metadata');
@@ -629,11 +624,21 @@ suite('DeepnoteNotebookCommandListener', () => {
629624
'Metadata should have correct variable name'
630625
);
631626

632-
// Verify metadata keys match content keys
627+
// Verify all expected metadata keys are present in __deepnotePocket
633628
expectedMetadataKeys.forEach((key) => {
634629
assert.property(newCell.metadata.__deepnotePocket, key, `Metadata should have ${key} property`);
635630
});
636631

632+
// Verify metadata is also at the top level
633+
assert.equal(
634+
newCell.metadata.deepnote_variable_name,
635+
expectedVariableName,
636+
'Top-level metadata should have correct variable name'
637+
);
638+
expectedMetadataKeys.forEach((key) => {
639+
assert.property(newCell.metadata, key, `Top-level metadata should have ${key} property`);
640+
});
641+
637642
// Verify reveal and selection were set
638643
assert.isTrue(
639644
(editor.revealRange as sinon.SinonStub).calledOnce,

src/notebooks/deepnote/inputBlockContentFormatter.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@
33
* This is the single source of truth for how input block values are displayed in cells.
44
*/
55

6+
/**
7+
* Gets the expected language ID for an input block type.
8+
* This is the single source of truth for input block language modes.
9+
*/
10+
export function getInputBlockLanguage(blockType: string): string | undefined {
11+
const languageMap: Record<string, string> = {
12+
'input-text': 'plaintext',
13+
'input-textarea': 'plaintext',
14+
'input-select': 'python',
15+
'input-slider': 'python',
16+
'input-checkbox': 'python',
17+
'input-date': 'python',
18+
'input-date-range': 'python',
19+
'input-file': 'python',
20+
button: 'python'
21+
};
22+
return languageMap[blockType];
23+
}
24+
625
/**
726
* Formats the cell content for an input block based on its type and metadata.
827
* @param blockType The type of the input block (e.g., 'input-text', 'input-select')

0 commit comments

Comments
 (0)