/******************************************************************************* * Copyright (c) 2011 Sebastian Benz. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sebastian Benz - initial API and implementation ******************************************************************************/ package de.sebastianbenz.task.ui.contentassist; import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.jface.bindings.keys.ParseException; import org.eclipse.jface.fieldassist.ContentProposal; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.rules.FastPartitioner; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.ui.editor.XtextSourceViewer; import org.eclipse.xtext.ui.editor.XtextSourceViewerConfiguration; import org.eclipse.xtext.ui.editor.model.DocumentPartitioner; import org.eclipse.xtext.ui.editor.model.IXtextDocument; import org.eclipse.xtext.ui.editor.model.XtextDocument; import com.google.inject.Inject; import com.google.inject.Provider; import de.sebastianbenz.task.query.Query; import de.sebastianbenz.task.query.QueryStringParser; public class TextProposalProvider implements IContentProposalProvider { private static String KEY_PRESS = "Ctrl+Space"; @Inject private QueryStringParser queryParser; @Inject private XtextSourceViewer.Factory factory; @Inject private Provider<XtextSourceViewerConfiguration> configurationProvider; @Inject private Provider<XtextDocument> documentProvider; @Inject private Provider<DocumentPartitioner> partitionerProvider; @Inject private SimplePrefixMatcher prefixMatcher; public ICompletionProposal[] computeCompletionProposals( String currentModelToParse, int cursorPosition) { if (currentModelToParse == null) { currentModelToParse = ""; } Query query = queryParser.parse(currentModelToParse); if (query == null) { return new ICompletionProposal[0]; } final XtextResource xtextResource = (XtextResource) query.eResource(); final IXtextDocument xtextDocument = getDocument(xtextResource, currentModelToParse); XtextSourceViewerConfiguration configuration = configurationProvider .get(); ISourceViewer sourceViewer = getSourceViewer(xtextDocument, configuration); IContentAssistant contentAssistant = configuration .getContentAssistant(sourceViewer); String contentType; try { contentType = xtextDocument.getContentType(cursorPosition); } catch (BadLocationException e) { return new ICompletionProposal[0]; } IContentAssistProcessor processor = contentAssistant .getContentAssistProcessor(contentType); if (processor != null) { return processor.computeCompletionProposals(sourceViewer, cursorPosition); } return new ICompletionProposal[0]; } protected ISourceViewer getSourceViewer(final IXtextDocument xtextDocument, XtextSourceViewerConfiguration configuration) { ISourceViewer sourceViewer = factory.createSourceViewer(new Shell(), null, null, false, 0); sourceViewer.configure(configuration); sourceViewer.setDocument(xtextDocument); return sourceViewer; } public IXtextDocument getDocument(final XtextResource xtextResource, final String model) { XtextDocument document = documentProvider.get(); document.set(model); document.setInput(xtextResource); DocumentPartitioner partitioner = partitionerProvider.get(); partitioner.connect(document); document.setDocumentPartitioner(partitioner); return document; } public void configure(final Text text) { try { KeyStroke ks = KeyStroke.getInstance(KEY_PRESS); ContentProposalAdapter adapter = new ContentProposalAdapter(text, new TextContentAdapter(), this, ks, null); adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_INSERT); } catch (ParseException e) { throw new RuntimeException(e); } } public IContentProposal[] getProposals(String contents, int position) { ICompletionProposal[] proposals = computeCompletionProposals(contents, position); IContentProposal[] result = new IContentProposal[proposals.length]; int i = 0; for (ICompletionProposal completionProposal : proposals) { String description = ""; String label = completionProposal.getDisplayString(); String content = prefixMatcher.apply(contents, position, label); result[i] = new ContentProposal(content, label, description); i++; } return result; } }