From 396a0a87133a4feb5ed7816cd9b8613c79bae8d9 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Wed, 20 Mar 2024 09:51:39 +1100 Subject: [PATCH] Sort cell metadata to avoid unnecessary scm diffs --- src/helper.ts | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/helper.ts b/src/helper.ts index 9e03df6..cb2891e 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -13,17 +13,50 @@ export async function updateCellTags(cell: vscode.NotebookCell, tags: string[]) const metadata = JSON.parse(JSON.stringify(cell.metadata)); if (useCustomMetadata()) { metadata.custom = metadata.custom || {}; - metadata.custom.tags = tags; + metadata.custom.metadata = metadata.custom.metadata || {}; + metadata.custom.metadata.tags = tags; + if (tags.length === 0) { + delete metadata.custom.metadata.tags; + } } else { metadata.metadata = metadata.metadata || {}; metadata.metadata.tags = tags; + if (tags.length === 0) { + delete metadata.metadata.tags; + } } const edit = new vscode.WorkspaceEdit(); - const nbEdit = vscode.NotebookEdit.updateCellMetadata(cell.index, metadata); + const nbEdit = vscode.NotebookEdit.updateCellMetadata(cell.index, sortObjectPropertiesRecursively(metadata)); edit.set(cell.notebook.uri, [nbEdit]); await vscode.workspace.applyEdit(edit); } function useCustomMetadata() { - return !vscode.workspace.getConfiguration('jupyter').get('experimental.dropCustomMetadata', false); + if (vscode.extensions.getExtension('vscode.ipynb')?.exports.dropCustomMetadata) { + return false; + } + return true; +} + + +/** + * Sort the JSON to minimize unnecessary SCM changes. + * Jupyter notbeooks/labs sorts the JSON keys in alphabetical order. + * https://github.com/microsoft/vscode/issues/208137 + */ +function sortObjectPropertiesRecursively(obj: any): any { + if (Array.isArray(obj)) { + return obj.map(sortObjectPropertiesRecursively); + } + if (obj !== undefined && obj !== null && typeof obj === 'object' && Object.keys(obj).length > 0) { + return ( + Object.keys(obj) + .sort() + .reduce>((sortedObj, prop) => { + sortedObj[prop] = sortObjectPropertiesRecursively(obj[prop]); + return sortedObj; + }, {}) as any + ); + } + return obj; }