diff --git a/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonEditor.java b/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonEditor.java index 3325cc16..04d56e86 100755 --- a/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonEditor.java +++ b/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonEditor.java @@ -93,7 +93,7 @@ public abstract class JsonEditor extends YEdit implements IShowInSource, IShowIn private final Validator validator = createValidator(); private ProjectionSupport projectionSupport; - private Annotation[] oldAnnotations; + private Map oldProjectionAnnotations = new HashMap<>();; private ProjectionAnnotationModel annotationModel; private Composite topPanel; protected JsonSourceViewerConfiguration sourceViewerConfiguration; @@ -312,14 +312,23 @@ public void widgetSelected(SelectionEvent e) { return viewer; } - public void updateFoldingStructure(List positions) { + public void updateFoldingStructure(Iterable newNodes, JsonDocument document) { final Map newAnnotations = new HashMap(); - for (Position position : positions) { - newAnnotations.put(new ProjectionAnnotation(), position); + final Map node2Annotations = new HashMap<>(); + for (AbstractNode node : newNodes) { + if (node.isObject()) { + Position position = node.getPosition(document, true); + boolean isCollapsed = false; + if (oldProjectionAnnotations.get(node) != null) { + isCollapsed = oldProjectionAnnotations.get(node).isCollapsed(); + } + ProjectionAnnotation newAnnotation = new ProjectionAnnotation(isCollapsed); + newAnnotations.put(newAnnotation, position); + node2Annotations.put(node, newAnnotation); + } } - - annotationModel.modifyAnnotations(oldAnnotations, newAnnotations, null); - oldAnnotations = newAnnotations.keySet().toArray(new Annotation[0]); + annotationModel.modifyAnnotations(oldProjectionAnnotations.values().toArray(new Annotation[0]), newAnnotations, null); + oldProjectionAnnotations = node2Annotations; } @Override diff --git a/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonReconcilingStrategy.java b/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonReconcilingStrategy.java index 1b476db4..b00751da 100644 --- a/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonReconcilingStrategy.java +++ b/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/editor/JsonReconcilingStrategy.java @@ -10,21 +10,15 @@ *******************************************************************************/ package com.reprezen.swagedit.core.editor; -import java.util.ArrayList; -import java.util.List; - import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.Position; import org.eclipse.jface.text.reconciler.DirtyRegion; import org.eclipse.jface.text.reconciler.IReconcilingStrategy; import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension; import org.eclipse.swt.widgets.Display; -import org.yaml.snakeyaml.nodes.MappingNode; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.nodes.NodeTuple; + +import com.reprezen.swagedit.core.model.Model; public class JsonReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension { @@ -62,45 +56,15 @@ protected void calculatePositions() { if (!(document instanceof JsonDocument)) return; - final Node yaml = ((JsonDocument) document).getYaml(); - if (!(yaml instanceof MappingNode)) { - return; - } - + final Model model = ((JsonDocument) document).getModel(); + Display.getDefault().asyncExec(new Runnable() { public void run() { - editor.updateFoldingStructure(calculatePositions((MappingNode) yaml)); + editor.updateFoldingStructure(model.allNodes(), (JsonDocument) document); } }); } - protected List calculatePositions(MappingNode mapping) { - List positions = new ArrayList<>(); - int start; - int end = -1; - - for (NodeTuple tuple : mapping.getValue()) { - start = tuple.getKeyNode().getStartMark().getLine(); - end = tuple.getValueNode().getEndMark().getLine(); - - if ((end - start) > 0) { - try { - int startOffset = document.getLineOffset(start); - int endOffset = document.getLineOffset(end); - - positions.add(new Position(startOffset, (endOffset - startOffset))); - } catch (BadLocationException e) { - } - } - - if (tuple.getValueNode() instanceof MappingNode) { - positions.addAll(calculatePositions((MappingNode) tuple.getValueNode())); - } - } - - return positions; - } - public void setEditor(JsonEditor editor) { this.editor = editor; } diff --git a/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/model/AbstractNode.java b/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/model/AbstractNode.java index a30babe6..9c23f7b5 100644 --- a/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/model/AbstractNode.java +++ b/com.reprezen.swagedit.core/src/com/reprezen/swagedit/core/model/AbstractNode.java @@ -195,7 +195,18 @@ public int size() { * @return position inside the document */ public Position getPosition(IDocument document) { - boolean selectEntireElement = false; + return getPosition(document, false); + } + + /** + * Returns the position of the node inside the given document.
+ * The position matches the area that contains all the node's content. + * + * @param document + * @param selectEntireElement - the entire element will be selected if true, only the first line otherwise + * @return position inside the document + */ + public Position getPosition(IDocument document, boolean selectEntireElement) { int startLine = getStart().getLine(); int offset = 0; int length = 0;