private add()

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