/* * Copyright (C) 2003-2007 Kepler Project. Permission is hereby granted, free of * charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: The above copyright notice and this permission * notice shall be included in all copies or substantial portions of the * Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO * EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package org.keplerproject.ldt.ui.baseExts.completion; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.text.ITextViewer; 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.IContextInformationValidator; import org.eclipse.swt.graphics.Image; import org.keplerproject.ldt.core.LuaScriptsSpecs; import org.keplerproject.ldt.ui.baseExts.BaseExtsPlugin; import org.keplerproject.ldt.ui.baseExts.scanner.ILuaSyntax; import org.keplerproject.ldt.ui.baseExts.scanner.LuaVariableDetector; import org.keplerproject.luajava.LuaState; /** * A simple Lua Completion Processor thats use the default Lua Packages to * assist the programmer. * * @author guilherme * @version $Id: LuaCompletionProcessor.java,v 1.8 2007/05/20 23:17:09 guilherme * Exp $ */ public class LuaCompletionProcessor implements IContentAssistProcessor, ILuaSyntax { protected ArrayList<ICompletionProposal> proposalList; public LuaCompletionProcessor() { proposalList = new ArrayList<ICompletionProposal>(); } @SuppressWarnings("unchecked") public ICompletionProposal[] computeCompletionProposals( final ITextViewer viewer, final int documentOffset) { LuaVariableDetector wordPart = new LuaVariableDetector(viewer, documentOffset); List<ICompletionProposal> internalProposalList = getInternalProposals(wordPart); proposalList.addAll(internalProposalList); List<ICompletionProposal> functionProposalList = getFunctionProposals(viewer.getDocument().get(), wordPart); proposalList.addAll(functionProposalList); Collections.sort(proposalList, new CompletionProposalComparator()); ICompletionProposal result[] = new ICompletionProposal[proposalList.size()]; result = proposalList.toArray(result); proposalList.clear(); return result; } private List<ICompletionProposal> getInternalProposals(LuaVariableDetector wordPart) { LuaState L = LuaScriptsSpecs.getDefault().getLuaState(); if (L == null) { return Collections.emptyList(); } try { if (wordPart.getVariable() != null) { L.LdoString("return " + wordPart.getVariable()); } else { L.getGlobal("_G"); } } catch (Throwable e) { e.printStackTrace(); return Collections.emptyList(); } if (!L.isTable(-1)) { L.pop(1); return Collections.emptyList(); } String stem = wordPart.getString(); int wordOffset = wordPart.getOffset(); ImageRegistry imageRegistry = BaseExtsPlugin.getDefault().getImageRegistry(); ArrayList<ICompletionProposal> internalList = new ArrayList<ICompletionProposal>(); L.pushNil(); while (L.next(-2) != 0) { String key = L.toString(-2); if (!key.startsWith(wordPart.getString())) { String contextKey = null; if (wordPart.getVariable() != null) { contextKey = wordPart.getVariable() + "." + key; } else { contextKey = key; } String strLuaType = L.typeName(L.type(-1)); // load function.gif, table.gif or string.gif Image image = imageRegistry.get(strLuaType); int cursorLocation = key.length(); // To functions, use de (). if (FUNCTION_TYPE_NAME.equals(strLuaType)) { key += "()"; cursorLocation += 1; //Put cursor inside "()" } IContextInformation info; info = new ContextInformation(contextKey, getContentInfoString(contextKey)); ICompletionProposal proposal = new CompletionProposal( key, //Replacement string wordOffset, stem.length(), //Replacement offset & length cursorLocation, //Cursor location relative to offset image, //Display image key, //Display string info, //Context information getContentInfoString(key)); //Extra string information internalList.add(proposal); } L.pop(1); // removes `value'; keeps `key' for next iteration } L.pop(1); return internalList; } static final Pattern fLuaFunctionPattern = Pattern.compile("^\\w*function\\s+(\\w+)\\s*\\(.*$", Pattern.MULTILINE); protected ArrayList<ICompletionProposal> getFunctionProposals(String fileContents, LuaVariableDetector wordPart) { ICompletionProposal proposal; String stem = wordPart.getString(); int wordOffset = wordPart.getOffset(); ArrayList<ICompletionProposal> functionList = new ArrayList<ICompletionProposal>(); Matcher matcher = fLuaFunctionPattern.matcher(fileContents); int offset = 0; // int startOffset = 0; while(matcher.find(offset)) { //startOffset = matcher.start(); offset = matcher.end(); String functionName = matcher.group(1); if(!functionName.startsWith(stem)) { continue; } //We can't do this for all completions functionName += "()"; //Put the cursor inside the brackets int cursorLocation = functionName.length() - 1; ImageRegistry imageRegistry = BaseExtsPlugin.getDefault().getImageRegistry(); Image displayImage = imageRegistry.get("function"); String displayName = functionName; proposal = new CompletionProposal(functionName, //Replacement string wordOffset, stem.length(), //Replacement offset & length cursorLocation, //Cursor location relative to offset displayImage, //Display Image displayName, //Display string null, //Context information null); //Extra string information functionList.add(proposal); } return functionList; } private String getContentInfoString(String keyWord) { String resourceKey = "ContextString." + keyWord; String resourceString = resourceKey; if (resourceString == keyWord) resourceString = "No Context Info String"; return resourceString; } public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { return null; } public char[] getCompletionProposalAutoActivationCharacters() { char result[] = new char[] { '.', ':', ' '}; return result; } public char[] getContextInformationAutoActivationCharacters() { char result[] = new char[1]; result[0] = '('; return result; } public String getErrorMessage() { return null; } public IContextInformationValidator getContextInformationValidator() { return null; } }