What I have: I added a Reconciling Strategy to my Editor Plugin to determine the folding positions to enable code folding. It works very well, but if I execute my plugin, fold some code and type something, all the folded code parts unfold itselfs. I observed, that reconcile(IRegion partition) is the only method which gets called, and the offset of partition is always 0 and the length is always the length of the whole document. So there is always only one partition. How to change that?
The code for the Reconciling Strategy:
public class TFReconcilingStrategy implements IReconcilingStrategy {
IDocument doc = null;
TextEditorImpl editor = null;
ISourceViewer sourceViewer = null;
ModelState state = null;
public void reconcile(IRegion partition) {
updateEditor(partition.getOffset(),partition.getLength());
}
private void updateEditor(int offset, int length){
if (editor == null)
return;
createFoldingPositions(offset, length);
editor.redrawViewer();
}
//Determines where foldable positions are
private void createFoldingPositions(int offset, int length) {
final ArrayList<Position> positions = new ArrayList<Position>();
String content = editor.getDocument().get();
int line = 1, col = 1;
for(int i = 0; i < content.length(); i++){
if (content.charAt(i) == 'n'){
line++;
col = 1;
} else {
col++;
} //Curly Bracket Handling
if(content.charAt(i) == '{'){
int startOffset = 0;
try {
startOffset = doc.getLineOffset(line-1) + col -1;
} catch (BadLocationException e) {
e.printStackTrace();
}
int endOffset = getMatchingBracketPosition(line, col, i, content, '{', '}', 'z');
if (offset >= 0 && length > 0){
if (!(startOffset >= offset && endOffset <= (offset + length)))
continue;
}
if(endOffset != -1 && endOffset > 0){
Position pos = new Position(startOffset, (endOffset-startOffset));
positions.add(pos);
}
}//Edge Bracket Handling
if(content.charAt(i) == '[' && content.charAt(i+1) == '['){
int startOffset = 0;
try {
startOffset = doc.getLineOffset(line-1) + col -1;
} catch (BadLocationException e) {
e.printStackTrace();
}
int endOffset = getMatchingBracketPosition(line, col, i, content, '[', ']', 'z');
if (offset >= 0 && length > 0){
if (!(startOffset >= offset && endOffset <= (offset + length)))
continue;
}
if(endOffset != -1&& endOffset >0){ //if endoffset = -1 then the matching bracket is located in the same line
Position pos = new Position(startOffset, (endOffset-startOffset));
positions.add(pos);
}
}//Comment Handling
if(content.charAt(i) == '/' && content.charAt(i+1) == '*'){
int startOffset = 0;
try {
startOffset = doc.getLineOffset(line-1) + col -1;
} catch (BadLocationException e) {
e.printStackTrace();
}
int endOffset = getMatchingBracketPosition(line, col, i, content, '/', '*', '/');
if (offset >= 0 && length > 0){
if (!(startOffset >= offset && endOffset <= (offset + length)))
continue;
}
if(endOffset != -1 && endOffset >0){ //if endoffset = -1 then the matching bracket is located in the same line
Position pos = new Position(startOffset, (endOffset-startOffset));
positions.add(pos);
}
}
}
if (positions.size() > 0)
{
Display.getDefault().asyncExec(new Runnable() {
public void run() {
editor.updateFoldingStructure(positions);
editor.redrawViewer();
}
});
}
}
public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
updateEditor(dirtyRegion.getOffset(), dirtyRegion.getLength());
}
public void setDocument(IDocument document) {
doc = document;
updateEditor(-1,-1);
}
public void setEditor(TextEditorImpl editor){
this.editor = editor;
}
public void setSourceViewer (ISourceViewer viewer){
this.sourceViewer = viewer;
}
// param add is used, if the end of the foldable area is indicated by two chars
private int getMatchingBracketPosition(int line, int column, int position, String content, char openBracketType, char closedBracketType, char add){
int endOffset = 0;
int j = position;
boolean found = false;
int startLine = line;
int ignoredBrackets = 0;
while (j < content.length() && !found){
if (content.charAt(j) == 'n'){
line++;
column = 1;
} else {
column++;
}
if(content.charAt(j) == openBracketType){
ignoredBrackets++;
}
if (add == 'z'){
if (content.charAt(j) == closedBracketType){
ignoredBrackets--;
if(ignoredBrackets == 0){
found = true;
if(startLine != line){
try {
endOffset = doc.getLineOffset(line-1) + column -1;
} catch (BadLocationException e) {
e.printStackTrace();
}
}
else endOffset = -1;
}
}
} else {
if (content.charAt(j) == closedBracketType && content.charAt(j+1) == add){
ignoredBrackets--;
if(ignoredBrackets == 0){
found = true;
if(startLine != line){
try {
endOffset = doc.getLineOffset(line-1) + column -1;
} catch (BadLocationException e) {
e.printStackTrace();
}
}
else endOffset = -1;
}
}
}
j++;
}
return endOffset;
}
}
And the Code in my TextEditor Implementation:
public void redrawViewer(){
Display.getDefault().asyncExec(new Runnable() {
public void run() {
//refresh view
if ( getSourceViewer() != null)
getSourceViewer().getTextWidget().redraw();
}
});
}
and:
public void updateFoldingStructure(ArrayList positions){
Annotation[] annotations = new Annotation[positions.size()];
//this will hold the new annotations along
//with their corresponding positions
HashMap newAnnotations = new HashMap();
for(int i = 0; i < positions.size(); i++){
ProjectionAnnotation annotation = new ProjectionAnnotation();
newAnnotations.put(annotation,positions.get(i));
annotations[i]=annotation;
}
annotationModel.modifyAnnotations(oldAnnotations,newAnnotations,null);
oldAnnotations=annotations;
}
What I want: I want, that folded parts stay folded even though I type something. Hope someone can help me!
Aucun commentaire:
Enregistrer un commentaire