package net.sf.eclipsefp.haskell.ui.internal.editors.haskell.codeassist;
import java.util.ArrayList;
import java.util.List;
import net.sf.eclipsefp.haskell.ui.util.HaskellUIImages;
import net.sf.eclipsefp.haskell.ui.util.IImageNames;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.templates.ContextTypeRegistry;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.persistence.TemplateStore;
import org.eclipse.swt.graphics.Image;
/**
* Haskell source code template completion processor.
*
* @author B. Scott Michel
*/
public class HSCodeTemplateAssistProcessor extends TemplateCompletionProcessor {
/**
* Reverse lex the document to extract the prefix for the completion. For example, if the current character at the offset
* is part of an identifier, work backward until a non-identifier lex token is reached.
*
* <p>Things this function lexes:
* <ul>
* <li>Identifiers that don't start with underscore</li>
* <li>Starts of comments, "{-" and "--"</li>
* <li>Groups of Unicode symbol characters, to catch tokens like "=>"</li>
* </ul>
*
* @return The collected prefix string or the empty string if nothing was collected.
*/
@Override
protected String extractPrefix( final ITextViewer viewer, final int offset ) {
return HaskellContentAssistProcessor.lexCompletionPrefix( viewer.getDocument(), offset );
}
@Override
protected Template[] getTemplates( final String contextTypeId ) {
HSCodeTemplateManager manager = HSCodeTemplateManager.getInstance();
TemplateStore tStore = manager.getTemplateStore();
return tStore.getTemplates();
}
@Override
protected TemplateContextType getContextType( final ITextViewer viewer, final IRegion region ) {
HSCodeTemplateManager manager = HSCodeTemplateManager.getInstance();
ContextTypeRegistry ctxRegistry = manager.getContextTypeRegistry();
return ctxRegistry.getContextType( HSCodeTemplateContextType.CONTEXT_TYPE );
}
@Override
protected Image getImage( final Template template ) {
return HaskellUIImages.getImage( IImageNames.TESTSUITE_STANZA );
// We need a template icon...
// return HaskellUIPlugin.getDefault().getImageRegistry().get( HaskellUIPlugin.ICON_TEMPLATE );
}
@Override
public ICompletionProposal[] computeCompletionProposals( final ITextViewer viewer, final int offset ) {
ITextSelection selection = ( ITextSelection )viewer.getSelectionProvider().getSelection();
int theOffset = offset;
// adjust offset to end of normalized selection
if ( selection.getOffset() == theOffset ) {
theOffset = selection.getOffset() + selection.getLength();
}
String prefix = extractPrefix( viewer, theOffset );
if (prefix == null) {
return new ICompletionProposal[ 0 ];
}
Region region = new Region( theOffset - prefix.length(), prefix.length() );
TemplateContext context = createContext( viewer, region );
if( context == null ) {
return new ICompletionProposal[ 0 ];
}
context.setVariable( "selection", selection.getText() ); // name of the selection variables {line, word_selection //$NON-NLS-1$
Template[] templates = getTemplates( context.getContextType().getId() );
String contextId = context.getContextType().getId();
List<ICompletionProposal> matches = new ArrayList<>();
for( int i = 0; i < templates.length; i++ ) {
try {
Template template = templates[ i ];
context.getContextType().validate( template.getPattern() );
if (prefix.length() > 0 ) {
String templateName = template.getName();
if ( templateName.startsWith( prefix ) && template.matches( prefix, contextId ) ) {
matches.add( createProposal( template, context, ( IRegion )region, getRelevance( template, prefix ) ) );
}
}
} catch( TemplateException e ) {
continue;
}
}
return matches.toArray( new ICompletionProposal[ matches.size() ] );
}
}