in src/lib/CodeMirror/indentationMarkers.ts [187:234]
private add(line: Line) {
if (this.has(line)) {
return this.get(line);
}
// empty lines continue their indentation from surrounding lines
if (!line.length || !line.text.trim().length) {
// the very first line, if empty, is just ignored and set as a 0 indent level
if (line.number === 1) {
return this.set(line, 0, 0);
}
// if we're at the end, we'll just use the previous line's indentation
if (line.number === this.state.doc.lines) {
const prev = this.closestNonEmpty(line, -1);
return this.set(line, 0, prev.level);
}
const prev = this.closestNonEmpty(line, -1);
const next = this.closestNonEmpty(line, 1);
// if the next line ends the block, we'll use the previous line's indentation
if (prev.level >= next.level) {
return this.set(line, 0, prev.level);
}
// having an indent marker that starts from an empty line looks weird
if (prev.empty && prev.level === 0 && next.level !== 0) {
return this.set(line, 0, 0);
}
// if the next indentation level is greater than the previous,
// we'll only increment up to the next indentation level. this prevents
// a weirdly "backwards propagating" indentation.
if (next.level > prev.level) {
return this.set(line, 0, prev.level + 1);
}
// else, we default to the next line's indentation
return this.set(line, 0, next.level);
}
const col = numColumns(line.text, this.state.tabSize);
const level = Math.floor(col / this.unitWidth);
return this.set(line, col, level);
}