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};
|
|
});
|