/** * Copyright (c) 2013 by JP Moresmau * This code is made available under the terms of the Eclipse Public License, * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html */ package net.sf.eclipsefp.haskell.ui.internal.resolve; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IMarker; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext; import org.eclipse.jface.text.quickassist.IQuickAssistProcessor; import org.eclipse.jface.text.source.Annotation; import org.eclipse.ui.IMarkerResolution; import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.spelling.SpellingCorrectionProcessor; /** * <p>Compute quick assist based on the Marker resolution generator</p> * * @author JP Moresmau * @author Alejandro Serrano */ public class QuickAssistProcessor implements IQuickAssistProcessor { private final BuildMarkerResolutionGenerator generator=new BuildMarkerResolutionGenerator(); private final SpellingCorrectionProcessor spelling=new SpellingCorrectionProcessor(); @Override public boolean canAssist( final IQuickAssistInvocationContext invocationContext ) { return spelling.canAssist( invocationContext ); } @Override public boolean canFix( final Annotation annotation ) { boolean can=spelling.canFix( annotation ); if (can){ return true; } if (annotation instanceof MarkerAnnotation){ return generator.getResolutions( ((MarkerAnnotation)annotation ).getMarker()).length>0; } return false; } @Override public ICompletionProposal[] computeQuickAssistProposals( final IQuickAssistInvocationContext invocationContext ) { List<ICompletionProposal> res=new ArrayList<>(); // get line of invocation int line=0; try { line=invocationContext.getSourceViewer().getDocument().getLineOfOffset( invocationContext.getOffset() ); } catch (BadLocationException ble){ // ignore } for (Iterator<?> it=invocationContext.getSourceViewer().getAnnotationModel().getAnnotationIterator();it.hasNext();){ Annotation ann=(Annotation)it.next(); if (ann instanceof MarkerAnnotation){ Position p=invocationContext.getSourceViewer().getAnnotationModel().getPosition( ann ); // line of marker int line2=-1; try { line2=invocationContext.getSourceViewer().getDocument().getLineOfOffset( p.getOffset() ); } catch (BadLocationException ble){ // ignore } // same offset, or same line, or marker includes the offset if (p.getOffset()==invocationContext.getOffset() || p.includes(invocationContext.getOffset()) || line==line2){ IMarker marker=((MarkerAnnotation)ann ).getMarker(); IMarkerResolution[] res1=generator.getResolutions( marker); for (IMarkerResolution imr:res1){ if (imr instanceof MarkerCompletion) { ICompletionProposal cp=((MarkerCompletion)imr).getCompletionProposal( marker, invocationContext.getSourceViewer().getDocument() ); if (cp!=null){ res.add(cp); } } } //res.addAll( Arrays.asList( res1 ) ); } } } for (ICompletionProposal cp:spelling.computeQuickAssistProposals( invocationContext ) ){ // do not show "no suggestions" if we have something else if (!cp.getClass().getName().equals( "org.eclipse.ui.internal.texteditor.spelling.NoCompletionsProposal" ) || res.isEmpty()){ res.add( cp ); } } return res.toArray( new ICompletionProposal[res.size()] ); } @Override public String getErrorMessage() { return null; } }