1 package net.mograsim.plugin.asm.editor;
3 import java.util.ArrayList;
4 import java.util.HashMap;
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.eclipse.jface.text.BadLocationException;
10 import org.eclipse.jface.text.IDocument;
11 import org.eclipse.jface.text.IRegion;
12 import org.eclipse.jface.text.Position;
13 import org.eclipse.jface.text.reconciler.DirtyRegion;
14 import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
15 import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
16 import org.eclipse.jface.text.source.Annotation;
17 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
18 import org.eclipse.jface.text.source.projection.ProjectionViewer;
20 public class AsmReconcilerStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension
22 private IDocument document;
23 private String oldDocument;
24 private ProjectionViewer projectionViewer;
25 private List<Annotation> oldAnnotations = new ArrayList<>();
26 private List<Position> oldPositions = new ArrayList<>();
29 public void setDocument(IDocument document)
31 this.document = document;
34 public void setProjectionViewer(ProjectionViewer projectionViewer)
36 this.projectionViewer = projectionViewer;
40 public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion)
46 public void reconcile(IRegion partition)
52 public void initialReconcile()
54 if (document.get().equals(oldDocument))
56 oldDocument = document.get();
58 List<Position> positions = getNewPositionsOfAnnotations();
60 List<Position> positionsToRemove = new ArrayList<>();
61 List<Annotation> annotationToRemove = new ArrayList<>();
63 for (Position position : oldPositions)
65 if (!positions.contains(position))
67 projectionViewer.getProjectionAnnotationModel().removeAnnotation(oldAnnotations.get(oldPositions.indexOf(position)));
68 positionsToRemove.add(position);
69 annotationToRemove.add(oldAnnotations.get(oldPositions.indexOf(position)));
72 positions.remove(position);
75 oldPositions.removeAll(positionsToRemove);
76 oldAnnotations.removeAll(annotationToRemove);
78 for (Position position : positions)
80 Annotation annotation = new ProjectionAnnotation();
81 projectionViewer.getProjectionAnnotationModel().addAnnotation(annotation, position);
82 oldPositions.add(position);
83 oldAnnotations.add(annotation);
87 private static enum SearchingFor
89 START_OF_TAG, START_OF_WORD, END_OF_WORD, END_OF_LINE
92 private List<Position> getNewPositionsOfAnnotations()
94 List<Position> positions = new ArrayList<>();
95 Map<String, Integer> startOfAnnotation = new HashMap<>();
96 SearchingFor searchingFor = SearchingFor.START_OF_TAG;
98 int characters = document.getLength();
99 int currentCharIndex = 0;
101 int wordStartIndex = 0;
102 int sectionStartIndex = 0;
107 while (currentCharIndex < characters)
109 char currentChar = document.getChar(currentCharIndex);
110 switch (searchingFor)
113 if (currentChar == '<')
115 char nextChar = document.getChar(currentCharIndex + 1);
118 sectionStartIndex = currentCharIndex;
119 searchingFor = SearchingFor.START_OF_WORD;
124 if (Character.isLetter(currentChar))
126 wordStartIndex = currentCharIndex;
127 searchingFor = SearchingFor.END_OF_WORD;
131 if (!Character.isLetter(currentChar))
133 word = document.get(wordStartIndex, currentCharIndex - wordStartIndex);
134 if (startOfAnnotation.containsKey(word))
136 searchingFor = SearchingFor.END_OF_LINE;
139 startOfAnnotation.put(word, sectionStartIndex);
140 searchingFor = SearchingFor.START_OF_TAG;
145 if (currentChar == '\n')
147 int start = startOfAnnotation.get(word);
148 if (document.getLineOfOffset(start) != document.getLineOfOffset(currentCharIndex))
150 positions.add(new Position(start, currentCharIndex + 1 - start));
152 startOfAnnotation.remove(word);
153 searchingFor = SearchingFor.START_OF_TAG;
157 throw new IllegalStateException("Unknown enum type: " + searchingFor);
162 catch (@SuppressWarnings("unused") BadLocationException e)
164 // skip the remainder of file due to error
170 public void setProgressMonitor(IProgressMonitor monitor)
172 // no progress monitor used