/* (non-Javadoc) * @see org.cfeclipse.cfml.editors.contentassist.IAssistContributor#getTagProposals(org.cfeclipse.cfml.editors.contentassist.IAssistState) */ public ICompletionProposal[] getTagProposals(IAssistState state) { /* * Only show content assist if the trigger was ( or , * We should probably find a better way than this, but the * content assist is getting in the way right now. */ if (state.getTriggerData() != ',' && state.getTriggerData() != '(') { return null; } if (state.getTriggerData() == ' ' || state.getTriggerData() == '\t') { return null; } if (!checkContext(state)) return null; else { // int length = this.functionName.length(); Set params = ((ISyntaxDictionary) this.sourceDict).getFunctionParams(this.functionName); String helpText = ((ISyntaxDictionary) this.sourceDict).getFunctionHelp(this.functionName); /* * here begins denny's attempt at in-page function argument proposals */ if (params == null) { params = new LinkedHashSet(); CFDocument doc = ((ICFDocument) state.getIDocument()).getCFDocument(); DocItem rootItem = doc.getDocumentRoot(); Matcher matcher; Pattern pattern; String name = "", type = "", required = "", defaultvalue = ""; pattern = Pattern.compile( "(\\w+)[\\s=]+(((\\x22|\\x27)((?!\\4).|\\4{2})*\\4))", Pattern.CASE_INSENSITIVE); // nodes = rootItem.selectNodes("//function[#startpos>=0 and #endpos < 200]"); nodes = rootItem.selectNodes("//cffunction"); Iterator i = nodes.iterator(); while (i.hasNext()) { DocItem currItem = (DocItem) i.next(); if (currItem.getItemData().indexOf(this.functionName) > 0) { // Function newFunk = new Function(this.functionName); // System.out.println(currItem.getItemData()); if (currItem.getFirstChild().getName().equals("cfargument")) { CFNodeList childNodes = currItem.getChildNodes(); int x = 0; DocItem childNode = (DocItem) childNodes.get(x); while (childNode.getName().equals("cfargument")) { matcher = pattern.matcher(childNode.getItemData()); while (matcher.find()) { String value = matcher.group(2).replaceAll("'", "").replaceAll("\"", ""); if (matcher.group(1).toLowerCase().equals("name")) { name = value; } if (matcher.group(1).toLowerCase().equals("type")) { type = value; } if (matcher.group(1).toLowerCase().equals("required")) { required = value; } if (matcher.group(1).toLowerCase().equals("default")) { defaultvalue = value; } } Parameter newParam = new Parameter(name, type, Boolean.valueOf(required), defaultvalue); // Parameter newParam = new Parameter(name,type); params.add(newParam); System.out.println(currItem.getFirstChild().getItemData()); childNode = (DocItem) nodes.get(x); x++; } } } } /* * here endss denny's attempt at in-page function argument proposals */ if (params == null) { return null; } } Parameter[] filteredParams = getFilteredParams(params); int x = 0; String extraInfo = paramIndent + "<b>" + functionName + "</b> (\n"; // CompletionProposal proposal = null; // String usage = ""; Parameter activeParam = null; int paramCount = filteredParams.length; while (x < paramCount) { Parameter p = filteredParams[x]; String delimiter = ""; if (x + 1 < paramCount) { delimiter = " ,"; } extraInfo += paramIndent + paramIndent; if (x == this.paramsSoFar) { activeParam = p; extraInfo += "<b>"; } extraInfo += p.toString() + delimiter; if (x == this.paramsSoFar) { extraInfo += "</b>"; } extraInfo += "\n"; x++; } if (this.paramsSoFar == paramCount) { // System.out.println("End of params"); return null; } extraInfo += paramIndent + ") \n\n"; extraInfo += helpText; return getParamProposals(activeParam, extraInfo, state.getOffset(), paramCount); } }
/* (non-Javadoc) * @see org.cfeclipse.cfml.editors.contentassist.IAssistContributor#getTagProposals(org.cfeclipse.cfml.editors.contentassist.IAssistState) */ public ICompletionProposal[] getTagProposals(IAssistState state) { /* * Only show content assist if the trigger was ( or , * We should probably find a better way than this, but the * content assist is getting in the way right now. */ fState = state; if (!checkContext(state)) return null; else { // int length = this.functionName.length(); Set params = ((ISyntaxDictionary) this.sourceDict).getFunctionParams(this.functionName); String helpText = ((ISyntaxDictionary) this.sourceDict).getFunctionHelp(this.functionName); if (params == null) { Set functions; params = new LinkedHashSet(); CFDocument doc = ((ICFDocument) state.getIDocument()).getCFDocument(); functions = doc.getFunctions(); Iterator it = functions.iterator(); while (it.hasNext()) { Function function = (Function) it.next(); System.out.println(function.getName().split("\\(")[0]); if (function.getName().split("\\(")[0].equals(this.functionName) && function.getParameters() != null) { Iterator funkParams = function.getParameters().iterator(); while (funkParams.hasNext()) { params.add((Parameter) funkParams.next()); } } } if (params.size() == 0) { String allData = state.getDataSoFar(); if (allData.endsWith(".") || allData.endsWith("(")) { allData = allData.substring(0, allData.length() - 1); } variableName = ""; StringBuffer buf = new StringBuffer(); for (int i = allData.length() - 1; i >= 0; i--) { if (!Character.isJavaIdentifierPart(allData.charAt(i))) { for (int j = i - 1; j >= 0; j--) { if (!Character.isJavaIdentifierPart(allData.charAt(j))) { break; } buf.insert(0, allData.charAt(j)); } break; } } variableName = buf.toString(); String CFCName = AssistUtils.getCFCName(this.variableName, state); IFile foundCFC = AssistUtils.findCFC(CFCName); functions = AssistUtils.getFunctions(foundCFC, state.getOffset()); if (functions != null) { it = functions.iterator(); while (it.hasNext()) { Function function = (Function) it.next(); if (function.getName().split("\\(")[0].equals(this.functionName) && function.getParameters() != null) { Iterator funkParams = function.getParameters().iterator(); while (funkParams.hasNext()) { params.add((Parameter) funkParams.next()); } } } } else { System.err.println("Function for " + CFCName + " are null!"); } } } Parameter[] filteredParams = getFilteredParams(params); int x = 0; String extraInfo = paramIndent + "<b>" + functionName + "</b> (\n"; // CompletionProposal proposal = null; // String usage = ""; Parameter activeParam = null; int paramCount = filteredParams.length; while (x < paramCount) { Parameter p = filteredParams[x]; String delimiter = ""; if (x + 1 < paramCount) { delimiter = " ,"; } extraInfo += paramIndent + paramIndent; if (x == this.paramsSoFar) { activeParam = p; extraInfo += "<b>"; } if (p != null) { extraInfo += p.toString() + delimiter; } if (x == this.paramsSoFar) { extraInfo += "</b>"; } extraInfo += "\n"; x++; } if (this.paramsSoFar == paramCount || activeParam == null) { // System.out.println("End of params"); return null; } extraInfo += paramIndent + ") \n\n"; extraInfo += helpText; return getParamProposals(activeParam, extraInfo, state.getOffset(), paramCount); } }
/** * Checks to see if the cursor is at a position in the document where function parameter info * should be displayed. * * @param docText * @param offset * @return */ private boolean checkContext(IAssistState state) { this.paramsSoFar = 0; this.paramList = new ArrayList(); // this.paramPositions = new HashMap(); String docText = state.getIDocument().get(); this.paramText = ""; int offset = state.getOffset(); int newOffset = offset; try { String trigger = docText.substring(offset - 1, offset); // System.out.println("Triggered by ["+trigger+"]"); if (trigger.equals("#")) { newOffset = offset - 1; trigger = docText.substring(offset - 2, offset - 1); if (trigger.equals("'") || trigger.equals("\"")) { newOffset = offset - 2; trigger = docText.substring(offset - 3, offset - 2); } } else if (trigger.equals("'") || trigger.equals("\"")) { newOffset = offset - 1; trigger = docText.substring(offset - 2, offset - 1); } /* * This block checks to see if we're in a parameter already. * If so, it tries to figure out which one and resets the offset and trigger */ if (!trigger.equals("(") && !trigger.equals(",") && !trigger.equals(")")) { int lastOpenParen = state.getDataSoFar().lastIndexOf("("); int lastComma = state.getDataSoFar().lastIndexOf(","); int lastCloseParen = state.getDataSoFar().lastIndexOf(")"); if (lastOpenParen > 0 || lastComma > 0) { if (lastOpenParen > lastComma) { newOffset = state.getOffset() - state.getDataSoFar().length() + lastOpenParen + 1; trigger = docText.substring(newOffset - 1, newOffset); paramText = docText.substring(newOffset, state.getOffset()); } else if (lastComma > lastCloseParen) { newOffset = state.getOffset() - state.getDataSoFar().length() + lastComma + 1; trigger = docText.substring(newOffset - 1, newOffset); paramText = docText.substring(newOffset, state.getOffset()); } else { return false; } // Auto insert closing " or ' docText.substring(state.getOffset(), state.getOffset() + 1); // System.out.println("Start of param text: " + paramText.substring(0,1)); // System.out.println("End of param text " + // docText.substring(state.getOffset(),state.getOffset()+1)); if (docText.length() > state.getOffset() && docText .substring(state.getOffset(), state.getOffset() + 1) .equals(paramText.substring(0, 1))) { paramText += paramText.substring(0, 1); // System.out.println("Param: " + paramText); } } } // Check if we're at the start of a function. if (trigger.equals("(")) { Pattern p = Pattern.compile("\\b\\w+\\($"); Matcher m = p.matcher(docText.substring(0, newOffset)); if (m.find()) { this.functionName = m.group().substring(0, m.group().length() - 1); this.paramsSoFar = 0; return true; } } else if (trigger.equals(",")) { // System.out.println("Yep"); // Pattern p = Pattern.compile("(\\b\\w+)\\(([^,]+,)*$"); // Matcher m = p.matcher(docText.substring(0,offset)); boolean singleQuotesOpen, doubleQuotesOpen, functionStart; singleQuotesOpen = doubleQuotesOpen = functionStart = false; int openFunctionCount = 0; byte[] docBytes = docText.substring(0, newOffset).getBytes(); int lastParamEndedAt = docBytes.length; String functionText = docText.substring(0, newOffset); for (int i = docBytes.length - 1; i >= 0; i--) { byte thisByte = docBytes[i]; // System.out.println("Looking at: " + (char)thisByte); switch (thisByte) { case 34: if (!singleQuotesOpen) { doubleQuotesOpen = !doubleQuotesOpen; // System.out.println("double qoute found. Open? " + doubleQuotesOpen); } break; case 39: if (!doubleQuotesOpen) { singleQuotesOpen = !singleQuotesOpen; // System.out.println("single qoute found. Open? " + singleQuotesOpen); } break; case 40: if (!singleQuotesOpen && !doubleQuotesOpen) { openFunctionCount--; if (openFunctionCount < 0) { String thisParam = functionText.substring(i + 1, lastParamEndedAt); paramList.add(thisParam); lastParamEndedAt = i; functionStart = true; // System.out.println("Function start found."); } else { // System.out.println("Opening parentheses found. Open function count: " + // openFunctionCount); } } break; case 41: if (!singleQuotesOpen && !doubleQuotesOpen) { openFunctionCount++; // System.out.println("Closing parentheses found. Open function count: " + // openFunctionCount); } break; case 44: if (!singleQuotesOpen && !doubleQuotesOpen && openFunctionCount < 1) { String thisParam = functionText.substring(i + 1, lastParamEndedAt); paramList.add(thisParam); lastParamEndedAt = i; this.paramsSoFar++; // System.out.println("Comma found. Params so far " + this.paramsSoFar); } break; // default: System.out.println("Found " + (char)thisByte + ":" + (int)thisByte); } if (functionStart) { offset = i + 1; // System.out.println("Looking in " + docText.substring(0,offset)); Pattern p = Pattern.compile("\\b\\w+\\($"); Matcher m = p.matcher(docText.substring(0, offset)); if (m.find()) { // System.out.println("Found " + m.group()); this.functionName = m.group().substring(0, m.group().length() - 1); // System.out.println(this.functionName); return true; } } } } } catch (Exception e) { e.printStackTrace(); } return false; }
private ICompletionProposal[] getValueProposals( Parameter activeParam, String extraInfo, int offset, int paramCount) { // String value = ""; String docText = fState.getDataSoFar(); char strDelim = (docText.lastIndexOf("'") > docText.lastIndexOf("\"")) ? '\'' : '\"'; String suffix = ","; Set values = activeParam.getValues(); ICompletionProposal[] tmpResult = new ICompletionProposal[values.size()]; if (this.paramsSoFar == paramCount - 1) { suffix = ""; } Iterator i = values.iterator(); Pattern pattern = Pattern.compile("([\"']?)([^\"']*)([\"']?)"); Matcher matcher = pattern.matcher(paramText); String cleanParamText = ""; if (matcher.find()) { cleanParamText = matcher.group(2); if (cleanParamText.equals("\"") || cleanParamText.equals("'")) { cleanParamText = ""; } } int x = 0; while (i.hasNext()) { Object o = i.next(); if (o instanceof Value) { Value val = (Value) o; boolean wee = val.toString().matches("^\""); if (cleanParamText.length() == 0 || val.toString().toLowerCase().startsWith(cleanParamText.toLowerCase())) { String insertion = val.toString().substring(cleanParamText.length(), val.toString().length()); if (activeParam.getType().equalsIgnoreCase("string") && !insertion.matches("^[\"|'].*")) { insertion = strDelim + insertion + strDelim; } int cursorOffset = insertion.length() + suffix.length(); if (!paramText.endsWith("\"") && paramText.startsWith("\"")) { insertion += "\""; cursorOffset++; } else if (paramText.startsWith("\"")) { cursorOffset++; } if (!paramText.endsWith("'") && paramText.startsWith("'")) { insertion += "'"; ; cursorOffset++; } else if (paramText.startsWith("'")) { cursorOffset++; } CompletionProposal proposal = new CompletionProposal( insertion + suffix, offset, 0, cursorOffset, CFPluginImages.get(CFPluginImages.ICON_PARAM), activeParam.toString() + " - " + insertion, null, extraInfo); // System.out.println("Added " + val.toString()); tmpResult[x] = proposal; x++; } } } ICompletionProposal[] result = new ICompletionProposal[x]; // System.out.println("Temp array length: " + x); for (int y = 0; y < x; y++) { result[y] = tmpResult[y]; } return result; }