| 1 | import type { TextDocument } from 'vscode' |
| 2 | import { parse } from '@slidev/parser' |
| 3 | import { defineService, useDisposable, useEventEmitter, watch } from 'reactive-vscode' |
| 4 | import { FoldingRangeKind, languages } from 'vscode' |
| 5 | import { getProjectFromDoc } from '../composables/useProjectFromDoc' |
| 6 | import { projects } from '../projects' |
| 7 | |
| 8 | export const useFoldings = defineService(() => { |
| 9 | const emitter = useEventEmitter<void>() |
| 10 | watch(projects, () => emitter.fire(), { deep: true }) |
| 11 | useDisposable(languages.registerFoldingRangeProvider( |
| 12 | { |
| 13 | scheme: 'file', |
| 14 | language: 'markdown', |
| 15 | }, |
| 16 | { |
| 17 | onDidChangeFoldingRanges: emitter.event, |
| 18 | async provideFoldingRanges(document: TextDocument) { |
| 19 | if (!getProjectFromDoc(document)) |
| 20 | return // Not a slidev markdown file |
| 21 | // Not using global slides data because it updates too late |
| 22 | const md = await parse(document.getText(), document.uri.fsPath) |
| 23 | return md?.slides.map(source => ({ |
| 24 | start: Math.max(0, source.frontmatterStyle === 'frontmatter' ? source.start : source.start - 1), |
| 25 | end: source.end - 1, |
| 26 | kind: FoldingRangeKind.Region, |
| 27 | })) |
| 28 | }, |
| 29 | }, |
| 30 | )) |
| 31 | }) |
| 32 |