/** * Copyright (C) 2005 - 2011 Eric Van Dewoestine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.eclim.plugin.jdt.command.complete; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import org.eclim.annotation.Command; import org.eclim.command.CommandLine; import org.eclim.command.Options; import org.eclim.plugin.core.command.complete.AbstractCodeCompleteCommand; import org.eclim.plugin.core.command.complete.CodeCompleteResult; import org.eclim.plugin.jdt.util.JavaUtils; import org.eclipse.jdt.core.CompletionProposal; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal; import org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; /** * Command to handle java code completion requests. * * @author Eric Van Dewoestine */ @Command( name = "java_complete", options = "REQUIRED p project ARG," + "REQUIRED f file ARG," + "REQUIRED o offset ARG," + "REQUIRED e encoding ARG," + "REQUIRED l layout ARG" ) public class CodeCompleteCommand extends AbstractCodeCompleteCommand { private static final Comparator<CodeCompleteResult> COMPLETION_COMPARATOR = new CompletionComparator(); private static String COMPACT = "compact"; //private static String STANDARD = "standard"; /** * {@inheritDoc} */ public Object execute(CommandLine commandLine) throws Exception { String project = commandLine.getValue(Options.PROJECT_OPTION); String file = commandLine.getValue(Options.FILE_OPTION); int offset = getOffset(commandLine); ICompilationUnit src = JavaUtils.getCompilationUnit(project, file); CompletionProposalCollector collector = new CompletionProposalCollector(src); src.codeComplete(offset, collector); IJavaCompletionProposal[] proposals = collector.getJavaCompletionProposals(); ArrayList<CodeCompleteResult> results = new ArrayList<CodeCompleteResult>(); for(int ii = 0; ii < proposals.length; ii++){ results.add( createCompletionResult(collector, ii, proposals[ii])); } Collections.sort(results, COMPLETION_COMPARATOR); String layout = commandLine.getValue(Options.LAYOUT_OPTION); if(COMPACT.equals(layout) && results.size() > 0){ results = compact(results); } return results; } /** * Create a CodeCompleteResult from the supplied CompletionProposal. * * @param collector The completion collector. * @param index The index of the proposal in the results. * @param proposal The proposal. * * @return The result. */ protected CodeCompleteResult createCompletionResult( CompletionProposalCollector collector, int index, IJavaCompletionProposal proposal) { String completion = null; String menu = proposal.getDisplayString(); if(proposal instanceof JavaCompletionProposal){ JavaCompletionProposal lazy = (JavaCompletionProposal)proposal; completion = lazy.getReplacementString(); }else if(proposal instanceof LazyJavaCompletionProposal){ LazyJavaCompletionProposal lazy = (LazyJavaCompletionProposal)proposal; completion = lazy.getReplacementString(); } int kind = collector.getProposal(index).getKind(); switch(kind){ case CompletionProposal.METHOD_REF: // trim off the trailing paren if the method takes any arguments. if (menu.lastIndexOf(')') > menu.lastIndexOf('(') + 1 && (completion.length() > 0 && completion.charAt(completion.length() - 1) == ')')) { completion = completion.substring(0, completion.length() - 1); } break; case CompletionProposal.TYPE_REF: // trim off package info. int idx = completion.lastIndexOf('.'); if(idx != -1){ completion = completion.substring(idx + 1); } break; } if("class".equals(completion)){ kind = CompletionProposal.KEYWORD; } String type = ""; switch(kind){ case CompletionProposal.TYPE_REF: type = CodeCompleteResult.TYPE; break; case CompletionProposal.FIELD_REF: case CompletionProposal.LOCAL_VARIABLE_REF: type = CodeCompleteResult.VARIABLE; type = CodeCompleteResult.VARIABLE; break; case CompletionProposal.METHOD_REF: type = CodeCompleteResult.FUNCTION; break; case CompletionProposal.KEYWORD: type = CodeCompleteResult.KEYWORD; break; } // TODO: // hopefully Bram will take my advice to add lazy retrieval of // completion 'info' so that I can provide this text without the // overhead involved with retrieving it for every completion regardless // of whether the user ever views it. /*return new CodeCompleteResult( kind, completion, menu, proposal.getAdditionalProposalInfo());*/ return new CodeCompleteResult(completion, menu, menu, type); } }