If wanted to indent a specific keyword after a user types it what would be the best strategy.
The keywords are tagged correctly as nodes with a lezer grammar.
I’m currently using an update listener with a regex to check each line and add spaces but the results are flaky. Is an indentation more than just some spaces? I wanted to use the regex to be certain the word only appears at the start of a line.
If your language’s auto-indent provides the desired indentation for such lines, indentOnInput, with appropriate language data adding the proper regexp, might do what you want here.
The nodeType stack has the correct function as a prop and every line indents.
However when I add the following, changing the selector to Modifier the nodeType Modifier has the correct function as a prop but no indentation takes place. How do I tell code mirror to indent lines with Modifiers?
Another approach which is working for me, as I also want it to be an auto-correcting linter is to use an updateListener and iterate thru the syntax tree and check the Modifier nodes for the correct indentation.
const simpleLinter = EditorView.updateListener.of((update) => {
if (!update.docChanged) return;
// don't take action on deletes
for (const tr of update.transactions) {
if (tr.isUserEvent("delete.backward")) return;
}
syntaxTree(update.state).cursor().iterate(node => {
const pos = node.from;
const line = update.state.doc.lineAt(pos);
let text = line.text;
let indent = false;
if (node.name === "Modifier") {
// lint the line and check it's indentation
[text, indent] = checkModifierIndent(text);
}
if (indent) {
let indentation = indentString(update.state, 2);
changes.push({ from: line.from, to: line.from, insert: indentation });
}
}
if (changes.length > 0) {
update.view.dispatch({ changes });
}
}
See this blog post for a general overview of how syntax-tree indentation works. Sometimes you need to write a bit more complicated indentation functions that figure out where in the node you are (i.e. before an else in a conditional) to adjust indentation.