diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vs/workbench/contrib/notebook/common/notebookCommon.ts | 38 | ||||
-rw-r--r-- | src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts | 17 |
2 files changed, 41 insertions, 14 deletions
diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 40b6b6a2074..28ff3f4f885 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { VSBuffer } from 'vs/base/common/buffer'; +import { decodeBase64, encodeBase64, VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IDiffResult } from 'vs/base/common/diff/diff'; import { Event } from 'vs/base/common/event'; @@ -516,33 +516,45 @@ export namespace CellUri { export const scheme = Schemas.vscodeNotebookCell; - const _regex = /^ch(\d{7,})/; + + const _lengths = ['W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f']; + const _padRegexp = new RegExp(`^[${_lengths.join('')}]+`); + const _radix = 7; export function generate(notebook: URI, handle: number): URI { - return notebook.with({ - scheme, - fragment: `ch${handle.toString().padStart(7, '0')}${notebook.scheme !== Schemas.file ? notebook.scheme : ''}` - }); + + const s = handle.toString(_radix); + const p = s.length < _lengths.length ? _lengths[s.length - 1] : 'z'; + + const fragment = `${p}${s}s${encodeBase64(VSBuffer.fromString(notebook.scheme), true, true)}`; + return notebook.with({ scheme, fragment }); } export function parse(cell: URI): { notebook: URI; handle: number } | undefined { if (cell.scheme !== scheme) { return undefined; } - const match = _regex.exec(cell.fragment); - if (!match) { + + const idx = cell.fragment.indexOf('s'); + if (idx < 0) { + return undefined; + } + + const handle = parseInt(cell.fragment.substring(0, idx).replace(_padRegexp, ''), _radix); + const _scheme = decodeBase64(cell.fragment.substring(idx + 1)).toString(); + + if (isNaN(handle)) { return undefined; } - const handle = Number(match[1]); return { handle, - notebook: cell.with({ - scheme: cell.fragment.substring(match[0].length) || Schemas.file, - fragment: null - }) + notebook: cell.with({ scheme: _scheme, fragment: null }) }; } + + const _regex = /^(\d{8,})(\w[\w\d+.-]*)$/; + export function generateCellOutputUri(notebook: URI, outputId?: string) { return notebook.with({ scheme: Schemas.vscodeNotebookCellOutput, diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts index 7f762509d5b..1fa57c44f31 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts @@ -295,7 +295,7 @@ suite('CellUri', function () { test('parse, generate (file-scheme)', function () { - const nb = URI.parse('foo:///bar/følder/file.nb'); + const nb = URI.parse('file:///bar/følder/file.nb'); const id = 17; const data = CellUri.generate(nb, id); @@ -316,6 +316,21 @@ suite('CellUri', function () { assert.strictEqual(actual?.handle, id); assert.strictEqual(actual?.notebook.toString(), nb.toString()); }); + + test('stable order', function () { + + const nb = URI.parse('foo:///bar/følder/file.nb'); + const handles = [1, 2, 9, 10, 88, 100, 666666, 7777777]; + + const uris = handles.map(h => CellUri.generate(nb, h)).sort(); + + const strUris = uris.map(String).sort(); + const parsedUris = strUris.map(s => URI.parse(s)); + + const actual = parsedUris.map(u => CellUri.parse(u)?.handle); + + assert.deepStrictEqual(actual, handles); + }); }); |