diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineEntryFactory.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineEntryFactory.ts index 391862fc9d0..01897cf0e25 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineEntryFactory.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineEntryFactory.ts @@ -5,7 +5,7 @@ import { renderMarkdownAsPlaintext } from 'vs/base/browser/markdownRenderer'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IOutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; +import { IOutlineModelService, OutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { localize } from 'vs/nls'; import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { getMarkdownHeadersInCell } from 'vs/workbench/contrib/notebook/browser/viewModel/foldingModel'; @@ -23,7 +23,7 @@ export interface INotebookOutlineEntryFactory { createOutlineEntrys(cell: ICellViewModel, index: number, includeAllSymbols: boolean, cacheSymbols: boolean): OutlineEntry[]; } -type entryDesc = { name: string; children?: entryDesc[] }; +type entryDesc = { name: string; level: number }; export class NotebookOutlineEntryFactory implements INotebookOutlineEntryFactory, IDisposable { _serviceBrand: undefined; @@ -81,7 +81,7 @@ export class NotebookOutlineEntryFactory implements INotebookOutlineEntryFactory // This will just provide the most recently cached values to stay syncronous, while refreshing the cache asyncronously. if (includeAllSymbols && cachedEntries) { cachedEntries.forEach((cached) => { - entries.push(new OutlineEntry(index++, 7, cell, cached.name, false, false)); + entries.push(new OutlineEntry(index++, cached.level, cell, cached.name, false, false)); }); } @@ -108,10 +108,7 @@ export class NotebookOutlineEntryFactory implements INotebookOutlineEntryFactory const timeout = this.outlineModelService.getDebounceValue(textModel); this.cacheTimer.cancelAndSet(async () => { const outlineModel = await this.outlineModelService.getOrCreate(textModel, CancellationToken.None); - const symbols = outlineModel.getTopLevelSymbols().map((symbol) => { - return { name: symbol.name }; - }); - + const symbols = createOutlineEntry(outlineModel.getTopLevelSymbols(), 7); this.cellOutlineEntryCache[textModel.id] = symbols; }, timeout); } @@ -122,6 +119,20 @@ export class NotebookOutlineEntryFactory implements INotebookOutlineEntryFactory } } +type outlineModel = Awaited>; +type documentSymbol = ReturnType[number]; + +function createOutlineEntry(symbols: documentSymbol[], level: number): entryDesc[] { + const entries: entryDesc[] = []; + symbols.forEach(symbol => { + entries.push({ name: symbol.name, level }); + if (symbol.children) { + entries.push(...createOutlineEntry(symbol.children, level + 1)); + } + }); + return entries; +} + function getCellFirstNonEmptyLine(cell: ICellViewModel) { const textBuffer = cell.textBuffer; for (let i = 0; i < textBuffer.getLineCount(); i++) { diff --git a/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookSymbols.test.ts b/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookSymbols.test.ts index 9adea2f2bc3..2508ed1ff7c 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookSymbols.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookSymbols.test.ts @@ -28,6 +28,9 @@ suite('Notebook Symbols', function () { override getOrCreate(arg0: any, arg1: any) { return Promise.resolve(outlineModel); } + override getDebounceValue(arg0: any) { + return 0; + } }; function createCellViewModel(version: number = 1) { @@ -109,7 +112,7 @@ suite('Notebook Symbols', function () { test('Cell with nested symbols', async function () { symbols = [ - { name: 'root1', children: [{ name: 'nested1' }] }, + { name: 'root1', children: [{ name: 'nested1' }, { name: 'nested2' }] }, { name: 'root2', children: [{ name: 'nested1' }] } ]; const entryFactory = new NotebookOutlineEntryFactory(executionService, outlineModelService); @@ -119,14 +122,16 @@ suite('Notebook Symbols', function () { await new Promise(resolve => setTimeout(resolve, 0)); const entries = entryFactory.createOutlineEntrys(createCellViewModel(), 0, true, true); - assert.equal(entries.length, 4, 'wrong number of outline entries'); + assert.equal(entries.length, 5, 'wrong number of outline entries'); assert.equal(entries[0].label, 'root1'); assert.equal(entries[0].level, 7); assert.equal(entries[1].label, 'nested1'); assert.equal(entries[1].level, 8); - assert.equal(entries[0].label, 'root2'); - assert.equal(entries[0].level, 7); - assert.equal(entries[1].label, 'nested1'); - assert.equal(entries[1].level, 8); + assert.equal(entries[2].label, 'nested2'); + assert.equal(entries[2].level, 8); + assert.equal(entries[3].label, 'root2'); + assert.equal(entries[3].level, 7); + assert.equal(entries[4].label, 'nested1'); + assert.equal(entries[4].level, 8); }); });