/*
* $Id$
*
* Copyright (c) 2006 by the TeXlipse team.
* 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
*/
package net.sourceforge.texlipse.editor;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.texlipse.TexlipsePlugin;
import net.sourceforge.texlipse.model.ReferenceManager;
import net.sourceforge.texlipse.model.TexCommandEntry;
import net.sourceforge.texlipse.model.TexDocumentModel;
import net.sourceforge.texlipse.templates.TexContextType;
import net.sourceforge.texlipse.templates.TexTemplateCompletion;
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.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.source.ISourceViewer;
/**
* ContentAssistProcessor for math commands.
*
* @author Boris von Loesch
* @author Oskar Ojala
*/
public class TexMathCompletionProcessor implements IContentAssistProcessor {
private TexTemplateCompletion templatesCompletion = new TexTemplateCompletion(TexContextType.MATH_CONTEXT_TYPE);
private TexDocumentModel model;
private ISourceViewer fviewer;
/**
* Receives the document model from the editor (one model/editor view)
* and creates a new completion processor.
*
* @param tdm The document model for this editor
* @param viewer The ISourceviewer for this editor
*/
public TexMathCompletionProcessor(TexDocumentModel tdm, ISourceViewer viewer) {
this.model = tdm;
fviewer = viewer;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
*/
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
model.removeStatusLineErrorMessage();
String lineStart = "";
IDocument doc = viewer.getDocument();
try {
int lineStartOffset = doc.getLineOffset(doc.getLineOfOffset(offset));
lineStart = doc.get(lineStartOffset, offset - lineStartOffset);
} catch (BadLocationException e) {
TexlipsePlugin.log("TexCompletionProcessor: ", e);
return new ICompletionProposal[0];
}
if (lineStart.endsWith("\\\\"))
return null;
int backpos = lineStart.lastIndexOf('\\');
int templatepos = Math.max(Math.max(lineStart.lastIndexOf(' '),
lineStart.lastIndexOf('$')), lineStart.lastIndexOf('}')) + 1;
String replacement = lineStart.substring(templatepos);
ICompletionProposal[] templateProposals = computeTemplateCompletions(offset, replacement.length(), replacement, viewer);
ICompletionProposal[] proposals = null;
if (backpos >= 0) {
String command = lineStart.substring(backpos + 1);
if (!(command.indexOf(' ') >= 0
|| command.indexOf('{') >= 0
|| command.indexOf('(') >= 0)) {
CompletionProposal cp = null;
if ("\\".equals(command) || "end".startsWith(command)) {
String endString = TexCompletionProcessor.environmentEnd(doc.get(), offset);
if (endString != null) {
cp = new CompletionProposal("\\"+endString,
offset - replacement.length(),
replacement.length(), endString.length()+1);
}
}
ReferenceManager refManager = model.getRefMana();
List<TexCommandEntry> comEntries = refManager.getCompletionsCom(command, TexCommandEntry.MATH_CONTEXT);
if (comEntries != null){
int start = 0;
if (cp == null) {
proposals = new ICompletionProposal[comEntries.size()];
} else {
proposals = new ICompletionProposal[comEntries.size()+1];
proposals[0] = cp;
start = 1;
}
int len = command.length();
for (int i=0; i < comEntries.size(); i++) {
proposals[start + i] = new TexCompletionProposal(comEntries.get(i), offset - len,
len, fviewer);
}
} else {
if (cp != null) {
proposals = new ICompletionProposal[1];
proposals[0] = cp;
}
}
}
}
// Concatenate the lists if necessary
if ((proposals != null) && (templateProposals != null)) {
ICompletionProposal[] value = new ICompletionProposal[proposals.length
+ templateProposals.length];
System.arraycopy(proposals, 0, value, 0, proposals.length);
System.arraycopy(templateProposals, 0, value, proposals.length, templateProposals.length);
return value;
} else {
if (templateProposals.length == 0) {
model.setStatusLineErrorMessage(" No completions available.");
}
return templateProposals;
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
*/
public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
*/
public char[] getCompletionProposalAutoActivationCharacters() {
return new char[] {'\\'};
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
*/
public char[] getContextInformationAutoActivationCharacters() {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
*/
public String getErrorMessage() {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
*/
public IContextInformationValidator getContextInformationValidator() {
return null;
}
// copied from TexCompletion Processor
/**
* Calculates and returns the template completions proposals.
*
* @param offset Current cursor offset
* @param replacementLength The length of the string to be replaced
* @param prefix The already typed prefix of the entry to assist with
* @param viewer The text viewer of this document
* @return An array of completion proposals to use directly or null
*/
private ICompletionProposal[] computeTemplateCompletions(int offset, int replacementLength, String prefix, ITextViewer viewer) {
ArrayList returnProposals = templatesCompletion.addTemplateProposals(viewer, offset, prefix);
ICompletionProposal[] proposals = new ICompletionProposal[returnProposals.size()];
// and fill with list elements
returnProposals.toArray(proposals);
return proposals;
}
}