// Copyright (c) 2007 by Leif Frenzel - see http://leiffrenzel.de package net.sf.eclipsefp.haskell.ui.internal.editors.text; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.eclipsefp.haskell.buildwrapper.types.Occurrence; import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor; import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.text.ScionTokenScanner; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModelExtension; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; /** <p>computes identifier occurrences for highlighting in a given Haskell * source editor.</p> * * @author Leif Frenzel */ public class MarkOccurrenceComputer { private static final String ANNOTATION_TYPE = "net.sf.eclipsefp.haskell.ui.occurrences"; //$NON-NLS-1$ private HaskellEditor editor; private IDocument document; public MarkOccurrenceComputer( final HaskellEditor editor ) { if( editor == null ) { throw new IllegalArgumentException(); } this.editor = editor; } public void dispose(){ this.editor=null; this.document=null; } public void setDocument( final IDocument document ) { this.document = document; } public void compute(final IProgressMonitor pm) { if (pm!=null && pm.isCanceled()){ return; } final IAnnotationModel model = getAnnotationModel( editor ); if( model instanceof IAnnotationModelExtension ) { ISelection selection = editor.getSelectionProvider().getSelection(); if( selection instanceof ITextSelection ) { ITextSelection textSelection = ( ITextSelection )selection; int offset = textSelection.getOffset(); if (pm!=null && pm.isCanceled()){ return; } ScionTokenScanner sts=editor.getTokenScanner(); if (sts!=null){ if (pm!=null && pm.isCanceled()){ return; } List<Occurrence> occurrences=sts.getOccurrences( offset ); if (occurrences != null) { if (pm!=null && pm.isCanceled()){ return; } Map<Annotation, Position> map = computeAnnotations( occurrences ); IAnnotationModelExtension amx = ( IAnnotationModelExtension )model; if (pm!=null && pm.isCanceled()){ return; } amx.replaceAnnotations( collectToRemove( model ), map ); } } } // WordFinder.getEditorThing( editor, false, false , new WordFinder.EditorThingHandler() { // // public void handle( final EditorThing thing ) { // BuildWrapperPlugin.getJobFacade( thing.getFile().getProject() ).getOccurrences( thing.getFile(), thing.getName(), new OccurrencesHandler() { // // public void handleOccurrences( final List<Occurrence> occurrences ) { // if (occurrences != null) { // Map<Annotation, Position> map = computeAnnotations( occurrences ); // IAnnotationModelExtension amx = ( IAnnotationModelExtension )model; // amx.replaceAnnotations( collectToRemove( model ), map ); // } // // } // }); // } // }); } // String content = document.get(); // ISelection selection = editor.getSelectionProvider().getSelection(); // if( selection instanceof ITextSelection ) { // ITextSelection textSelection = ( ITextSelection )selection; // try { // IAnnotationModel model = getAnnotationModel( editor ); // if( model instanceof IAnnotationModelExtension ) { // int offset = textSelection.getOffset(); // int line = document.getLineOfOffset( offset ); // zero-based // int col = computeColumn( document, offset, line ); // Occurrence[] occs = markOccurrences.mark( content, line + 1, col ); // Map<Annotation, Position> map = computeAnnotations( occs ); // IAnnotationModelExtension amx = ( IAnnotationModelExtension )model; // amx.replaceAnnotations( collectToRemove( model ), map ); // } // } catch( final BadLocationException badlox ) { // // this means we could not properly get information from the // // editor document; no point in continuing // } // } } // helping functions //////////////////// private Annotation[] collectToRemove( final IAnnotationModel model ) { List<Annotation> result = new ArrayList<>(); Iterator<?> iterator = model.getAnnotationIterator(); while( iterator.hasNext() ) { Object next = iterator.next(); if( next instanceof Annotation ) { Annotation annotation = ( Annotation )next; if( ANNOTATION_TYPE.equals( annotation.getType() ) ) { result.add( annotation ); } } } return result.toArray( new Annotation[ result.size() ] ); } private IAnnotationModel getAnnotationModel( final HaskellEditor editor ) { IAnnotationModel result = null; if( editor != null ) { IDocumentProvider documentProvider = editor.getDocumentProvider(); if (documentProvider!=null){ IEditorInput input = editor.getEditorInput(); result = documentProvider.getAnnotationModel( input ); } } return result; } // private int computeColumn( final IDocument document, // final int offset, // final int line ) throws BadLocationException { // return ( offset - document.getLineOffset( line ) + 1 ); // } private List<Position> computePositions( final List<Occurrence> occurrences ) { List<Position> result = new ArrayList<>(); for( Occurrence occ: occurrences ) { try { int offs = document.getLineOffset( occ.getLine() - 1 ); offs += occ.getColumn() ; result.add( new Position( offs, occ.getLength() ) ); } catch( final BadLocationException badlox ) { // ignore that occurrence then } } return result; } private Map<Annotation, Position> computeAnnotations( final List<Occurrence> occs ) { Map<Annotation, Position> result = new HashMap<>(); List<Position> poss = computePositions( occs ); Iterator<Position> it = poss.iterator(); while( it.hasNext() ) { Position pos = it.next(); result.put( new Annotation( ANNOTATION_TYPE, false, "" ), pos ); //$NON-NLS-1$ } return result; } }