/**
* Aptana Studio
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.editor.ruby.internal.contentassist;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import com.aptana.editor.common.AbstractThemeableEditor;
import com.aptana.editor.common.CommonContentAssistProcessor;
import com.aptana.editor.ruby.RubyEditorPlugin;
public class RubyDoubleQuotedStringContentAssistProcessor extends CommonContentAssistProcessor
{
private static final ICompletionProposal[] NO_PROPOSALS = new ICompletionProposal[0];
private static final IContextInformation[] NO_CONTEXTS = new IContextInformation[0];
/**
* Proposal text to description.
*/
private static final Map<String, String> PROPOSALS = new TreeMap<String, String>();
static
{
PROPOSALS.put("\\", "\\nnn Octal <i>nnn</i>"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\C-", "Control-<i>x</i>"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\M-", "Meta-<i>x</i>"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\M-\\C-", "Meta-control-<i>x</i>"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\a", "Bell/alert (0x07)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\b", "Backspace (0x08)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\c", "Control-<i>x</i>"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\e", "Escape (0x1b)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\f", "Formfeed (0x0c)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\n", "Newline (0x0a)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\r", "Return (0x0d)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\s", "Space (0x20)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\t", "Tab (0x09)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\v", "Vertical tab (0x0b)"); //$NON-NLS-1$ //$NON-NLS-2$
PROPOSALS.put("\\x", "\\xnn: Hex <i>nn</i>"); //$NON-NLS-1$ //$NON-NLS-2$
}
public RubyDoubleQuotedStringContentAssistProcessor(AbstractThemeableEditor editor)
{
super(editor);
}
@Override
protected ICompletionProposal[] doComputeCompletionProposals(ITextViewer viewer, int offset, char activationChar,
boolean autoActivated)
{
try
{
String prefix = getPrefix(viewer, offset);
List<ICompletionProposal> result = new ArrayList<ICompletionProposal>();
for (Map.Entry<String, String> entry : PROPOSALS.entrySet())
{
if (entry.getKey().startsWith(prefix))
{
// FIXME Don't auto-insert common prefix!
// FIXME add image?
result.add(createProposal(entry.getKey(), prefix, offset - prefix.length(), entry.getValue()));
}
}
// TODO Add "#{}" templated proposal!
// TODO Sort by display string!
if(result==null || result.size()<1){
return computeWordCompletionProposals(offset, RubyContentAssistProcessor.PROPERTY_IMAGE, null);
}
return result.toArray(new ICompletionProposal[result.size()]);
}
catch (BadLocationException x)
{
// ignore and return no proposals
return NO_PROPOSALS;
}
}
private ICompletionProposal createProposal(String proposal, String prefix, int offset, String description)
{
CompletionProposal p = new CompletionProposal(proposal, offset, prefix.length(), proposal.length(), RubyContentAssistProcessor.PROPERTY_IMAGE,
proposal, null, description);
return p;
}
private String getPrefix(ITextViewer viewer, int offset) throws BadLocationException
{
IDocument doc = viewer.getDocument();
if (doc == null || offset > doc.getLength())
{
return null;
}
int length = 0;
while (--offset >= 0 && isPrefixChar(doc.getChar(offset)))
{
length++;
}
return doc.get(offset + 1, length);
}
private boolean isPrefixChar(char c)
{
switch (c)
{
case '\\':
return true;
default:
return Character.isLetter(c);
}
}
protected String getPreferenceNodeQualifier()
{
return RubyEditorPlugin.PLUGIN_ID;
}
public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset)
{
return NO_CONTEXTS;
}
// public char[] getCompletionProposalAutoActivationCharacters()
// {
// return super.getCompletionProposalAutoActivationCharacters();
// }
}