38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
import {foldService} from '@codemirror/language';
|
|
|
|
export const foldingOnIndent = foldService.of((state, from, to) => {
|
|
const line = state.doc.lineAt(from) // First line
|
|
const lines = state.doc.lines // Number of lines in the document
|
|
const indent = line.text.search(/\S|$/) // Indent level of the first line
|
|
let foldStart = from // Start of the fold
|
|
let foldEnd = to // End of the fold
|
|
|
|
// Check the next line if it is on a deeper indent level
|
|
// If it is, check the next line and so on
|
|
// If it is not, go on with the foldEnd
|
|
let nextLine = line
|
|
while (nextLine.number < lines) {
|
|
nextLine = state.doc.line(nextLine.number + 1) // Next line
|
|
const nextIndent = nextLine.text.search(/\S|$/) // Indent level of the next line
|
|
|
|
// If the next line is on a deeper indent level, add it to the fold
|
|
if (nextIndent > indent) {
|
|
foldEnd = nextLine.to // Set the fold end to the end of the next line
|
|
} else {
|
|
break // If the next line is not on a deeper indent level, stop
|
|
}
|
|
}
|
|
|
|
// If the fold is only one line, don't fold it
|
|
if (state.doc.lineAt(foldStart).number === state.doc.lineAt(foldEnd).number) {
|
|
return null
|
|
}
|
|
|
|
// Set the fold start to the end of the first line
|
|
// With this, the fold will not include the first line
|
|
foldStart = line.to
|
|
|
|
// Return a fold that covers the entire indent level
|
|
return {from: foldStart, to: foldEnd}
|
|
});
|