Hey there,
I have a use case which I need to fold only the first level of json.
e,g, this json:
{
"0": {
"a": 1
},
"1": {
"b": 2
},
}
I want to folded like this:
{
{...},
{...},
}
And not:
{...}
I tried to look at foldEffect/foldInside but i am not sure how it can help and how.
Thanks you very much in advance
marijn
February 7, 2023, 1:38pm
2
You could walk the syntax tree to find all the lines that start a 1st-level nesting, collect foldEffect
s for those lines, and dispatch those. For big documents it may be somewhat tricky to get the editor to parse the entire document, but you can use ensureSyntaxTree
if you want to force it to do that immediately.
Thanks @marijn for the response.
How can I detect that a node is start a 1st level nesting?
I am doing something like that:
syntaxTree(this.editor.state).iterate({
from,
to,
enter: (node) => {
//do something here
},
});
I guess i need to collect them, but how?
How can I detect out of node if it start a 1st-level nesting?
@marijn Sorry for nudging, I really need your help here
marijn
February 13, 2023, 1:37pm
6
I’m sorry, I don’t have the time or energy to help people write specific code here. I provide the library, I wrote docs, if you can’t take it from there you’ll have to do more studying or hire someone to implement this.
joshw
July 9, 2023, 8:53pm
8
import { syntaxTree, foldEffect } from "@codemirror/language";
function onCollapse() {
const tree = syntaxTree(cm.state);
tree.iterate({
enter(node) {
const firstChild = node.node.firstChild;
const lastChild = node.node.lastChild;
const isObjectOrArray =
(firstChild?.type.name === "{" && lastChild?.type.name === "}") ||
(firstChild?.type.name === "[" && lastChild?.type.name === "]");
const isNestedOneLevel = node.node.parent?.parent?.from === 0;
if (isObjectOrArray && isNestedOneLevel) {
cm.dispatch({
effects: foldEffect.of({
from: node.from + 1,
to: node.to - 1,
}),
});
}
},
});
};
Thanks @joshw , I managed to solve it with this code:
const foldAllTree = (cm: EditorView) => {
const effects: any[] = [];
const from = 0;
const to = cm.state.doc.length;
ensureSyntaxTree(cm.state, to, 5000)?.iterate({
from,
to,
enter: (node: SyntaxNodeRef) => {
const foldRange = foldable(cm.state, node.from, node.to);
if (foldRange) {
effects.push(foldEffect.of({ from: foldRange.from, to: foldRange.to }));
}
},
});
if (effects.length) cm.dispatch({ effects: effects });
};