blob: 85bd95eb10d90f4b21e14660c03476ef2091fe0b [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.ui.text.makefile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import org.eclipse.cdt.make.core.makefile.IMacroDefinition;
import org.eclipse.cdt.make.core.makefile.IMakefile;
import org.eclipse.cdt.make.core.makefile.IRule;
import org.eclipse.cdt.make.core.makefile.IDirective;
import org.eclipse.cdt.make.internal.ui.MakeUIImages;
import org.eclipse.cdt.make.internal.ui.MakeUIPlugin;
import org.eclipse.cdt.make.internal.ui.text.CompletionProposalComparator;
import org.eclipse.cdt.make.internal.ui.text.WordPartDetector;
import org.eclipse.cdt.make.ui.IWorkingCopyManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ContextInformation;
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.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorPart;
/**
* MakefileCompletionProcessor
*/
public class MakefileCompletionProcessor implements IContentAssistProcessor {
/**
* Simple content assist tip closer. The tip is valid in a range
* of 5 characters around its popup location.
*/
protected static class Validator implements IContextInformationValidator, IContextInformationPresenter {
protected int fInstallOffset;
/*
* @see IContextInformationValidator#isContextInformationValid(int)
*/
public boolean isContextInformationValid(int offset) {
return Math.abs(fInstallOffset - offset) < 5;
}
/*
* @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
*/
public void install(IContextInformation info, ITextViewer viewer, int offset) {
fInstallOffset = offset;
}
/*
* @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int, TextPresentation)
*/
public boolean updatePresentation(int documentPosition, TextPresentation presentation) {
return false;
}
}
public class DirectiveComparator implements Comparator {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object o1, Object o2) {
String name1;
String name2;
if (o1 instanceof IMacroDefinition) {
name1 = ((IMacroDefinition)o1).getName();
} else if (o1 instanceof IRule) {
name1 = ((IRule)o1).getTarget().toString();
} else {
name1 ="";
}
if (o2 instanceof IMacroDefinition) {
name2 = ((IMacroDefinition)o1).getName();
} else if (o2 instanceof IRule) {
name2 = ((IRule)o1).getTarget().toString();
} else {
name2 ="";
}
//return String.CASE_INSENSITIVE_ORDER.compare(name1, name2);
return name1.compareToIgnoreCase(name2);
}
}
protected IContextInformationValidator fValidator = new Validator();
protected Image imageMacro = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_MACRO);
protected Image imageTarget = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_TARGET_RULE);
protected CompletionProposalComparator comparator = new CompletionProposalComparator();
protected IEditorPart fEditor;
protected IWorkingCopyManager fManager;
public MakefileCompletionProcessor(IEditorPart editor) {
fEditor = editor;
fManager = MakeUIPlugin.getDefault().getWorkingCopyManager();
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
*/
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
boolean macro = inMacro(viewer, documentOffset);
IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput());
IDirective[] statements = null;
if (macro) {
IDirective[] m1 = makefile.getMacroDefinitions();
IDirective[] m2 = makefile.getBuiltinMacroDefinitions();
statements = new IDirective[m1.length + m2.length];
System.arraycopy(m1, 0, statements, 0, m1.length);
System.arraycopy(m2, 0, statements, m1.length, m2.length);
} else {
statements = makefile.getTargetRules();
}
ArrayList proposalList = new ArrayList(statements.length);
WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset);
// iterate over all the different categories
for (int i = 0; i < statements.length; i++) {
String name = null;
Image image = null;
String infoString = "";//getContentInfoString(name);
if (statements[i] instanceof IMacroDefinition) {
name = ((IMacroDefinition) statements[i]).getName();
image = imageMacro;
infoString = ((IMacroDefinition)statements[i]).getValue().toString();
} else if (statements[i] instanceof IRule) {
name = ((IRule) statements[i]).getTarget().toString();
image = imageTarget;
infoString = name;
}
if (name != null && name.startsWith(wordPart.getString())) {
IContextInformation info = new ContextInformation(name, infoString);
String displayString = (name.equals(infoString) ? name : name + " - " + infoString);
ICompletionProposal result =
new CompletionProposal(
name,
wordPart.getOffset(),
wordPart.getString().length(),
name.length(),
image,
displayString,
info,
infoString);
proposalList.add(result);
}
}
ICompletionProposal[] proposals = (ICompletionProposal[]) proposalList.toArray(new ICompletionProposal[0]);
Arrays.sort(proposals, comparator);
return proposals;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
*/
public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset);
boolean macro = inMacro(viewer, documentOffset);
IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput());
ArrayList contextList = new ArrayList();
if (macro) {
IDirective[] statements = makefile.getMacroDefinitions();
for (int i = 0; i < statements.length; i++) {
if (statements[i] instanceof IMacroDefinition) {
String name = ((IMacroDefinition) statements[i]).getName();
if (name != null && name.equals(wordPart.getString())) {
String value = ((IMacroDefinition) statements[i]).getValue().toString();
if (value != null && value.length() > 0) {
contextList.add(value);
}
}
}
}
statements = makefile.getBuiltinMacroDefinitions();
for (int i = 0; i < statements.length; i++) {
if (statements[i] instanceof IMacroDefinition) {
String name = ((IMacroDefinition) statements[i]).getName();
if (name != null && name.equals(wordPart.getString())) {
String value = ((IMacroDefinition) statements[i]).getValue().toString();
if (value != null && value.length() > 0) {
contextList.add(value);
}
}
}
}
}
IContextInformation[] result = new IContextInformation[contextList.size()];
for (int i = 0; i < result.length; i++) {
String context = (String)contextList.get(i);
result[i] = new ContextInformation(imageMacro, wordPart.getString(), context);
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
*/
public char[] getCompletionProposalAutoActivationCharacters() {
return null;
}
/* (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 fValidator;
}
private boolean inMacro(ITextViewer viewer, int offset) {
boolean isMacro = false;
IDocument document = viewer.getDocument();
// Try to figure out if we are in a Macro.
try {
for (int index = offset - 1; index >= 0; index--) {
char c;
c = document.getChar(index);
if (c == '$') {
isMacro = true;
break;
} else if (Character.isWhitespace(c)) {
break;
}
}
} catch (BadLocationException e) {
}
return isMacro;
}
}