protected String computeNestedTag( String regionType, String tagName, IStructuredDocumentRegion structuredDocumentRegion, ITextRegion region) { if (regionType.equals(TwigRegionTypes.TWIG_STMT_OPEN)) { try { String text = structuredDocumentRegion.getText(); Object cached = cache.get(text); if (cached != null) { return (String) cached; } CharStream content = new ANTLRStringStream(text); TwigLexer lexer = new TwigLexer(content); TwigParser parser = new TwigParser(new CommonTokenStream(lexer)); parser.setTreeAdaptor(new TwigCommonTreeAdaptor()); TwigParser.twig_source_return root; root = parser.twig_source(); TwigCommonTree tree = (TwigCommonTree) root.getTree(); TwigStatementVisitor visitor = new TwigStatementVisitor(); tree.accept(visitor); if (visitor.getStatementType() == TwigParser.TWIG_TAG) { String tag = visitor.getTag(); cache.put(text, tag); return tag; } } catch (Exception e) { e.printStackTrace(); } return TWIG_STMT_TAG; } else if (regionType.equals(TwigRegionTypes.TWIG_OPEN)) { return TWIG_PRINT_TAG; } return TWIG_STMT_TAG; }
protected void addAttributeValueProposals( ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) { IDOMNode node = (IDOMNode) contentAssistRequest.getNode(); String tagName = node.getNodeName(); IStructuredDocumentRegion open = node.getFirstStructuredDocumentRegion(); ITextRegionList openRegions = open.getRegions(); int i = openRegions.indexOf(contentAssistRequest.getRegion()); if (i < 0) return; ITextRegion nameRegion = null; while (i >= 0) { nameRegion = openRegions.get(i--); if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) break; } // get the attribute in question (first attr name to the left of the cursor) String attributeName = null; if (nameRegion != null) attributeName = open.getText(nameRegion); ProposalType proposalType = resolveProposalType(tagName, attributeName); if (ProposalType.None.equals(proposalType)) { return; } String currentValue = null; if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) currentValue = contentAssistRequest.getText(); else currentValue = ""; String matchString = null; int matchStrLen = contentAssistRequest.getMatchString().length(); int start = contentAssistRequest.getReplacementBeginPosition(); int length = contentAssistRequest.getReplacementLength(); if (currentValue.length() > StringUtils.strip(currentValue).length() && (currentValue.startsWith("\"") || currentValue.startsWith("'")) && matchStrLen > 0) { // Value is surrounded by (double) quotes. matchString = currentValue.substring(1, matchStrLen); start++; length = currentValue.length() - 2; currentValue = currentValue.substring(1, length + 1); } else { matchString = currentValue.substring(0, matchStrLen); } IJavaProject project = getJavaProject(contentAssistRequest); try { switch (proposalType) { case Package: proposePackage(contentAssistRequest, project, matchString, start, length); break; case TypeAlias: addProposals( contentAssistRequest, ProposalComputorHelper.proposeJavaType(project, start, length, false, matchString)); break; case ResultType: addProposals( contentAssistRequest, ProposalComputorHelper.proposeJavaType(project, start, length, true, matchString)); break; case ResultProperty: proposeProperty(contentAssistRequest, matchString, start, length, node); break; case TypeHandlerType: addProposals( contentAssistRequest, ProposalComputorHelper.proposeTypeHandler(project, start, length, matchString)); break; case CacheType: addProposals( contentAssistRequest, ProposalComputorHelper.proposeCacheType(project, start, length, matchString)); break; case SettingName: addProposals( contentAssistRequest, ProposalComputorHelper.proposeSettingName(start, length, matchString)); break; case ObjectFactory: addProposals( contentAssistRequest, ProposalComputorHelper.proposeObjectFactory(project, start, length, matchString)); break; case ObjectWrapperFactory: addProposals( contentAssistRequest, ProposalComputorHelper.proposeObjectWrapperFactory( project, start, length, matchString)); break; case StatementId: proposeStatementId(contentAssistRequest, project, matchString, start, length, node); break; case MapperNamespace: proposeMapperNamespace(contentAssistRequest, project, start, length); break; case ResultMap: String ownId = "resultMap".equals(tagName) && "extends".equals(attributeName) ? XpathUtil.xpathString(node, "@id") : null; addProposals( contentAssistRequest, proposeResultMapReference( project, node.getOwnerDocument(), start, currentValue, matchString.length(), ownId)); break; case Include: addProposals( contentAssistRequest, ProposalComputorHelper.proposeReference( project, node.getOwnerDocument(), matchString, start, length, "sql", null)); break; case SelectId: // TODO: include mapper methods with @Select. addProposals( contentAssistRequest, ProposalComputorHelper.proposeReference( project, node.getOwnerDocument(), matchString, start, length, "select", null)); break; case KeyProperty: String nodeName = node.getNodeName(); Node statementNode = "update".equals(nodeName) || "insert".equals(nodeName) ? node : MybatipseXmlUtil.findEnclosingStatementNode(node.getParentNode()); addProposals( contentAssistRequest, proposeParameter(project, start, length, statementNode, false, matchString)); break; case ParamProperty: addProposals( contentAssistRequest, proposeParameter( project, start, length, MybatipseXmlUtil.findEnclosingStatementNode(node), true, matchString)); break; case ParamPropertyPartial: AttrTextParser parser = new AttrTextParser(currentValue, matchString.length()); addProposals( contentAssistRequest, proposeParameter( project, start + parser.getMatchStringStart(), parser.getReplacementLength(), MybatipseXmlUtil.findEnclosingStatementNode(node.getParentNode()), true, parser.getMatchString())); break; default: break; } } catch (Exception e) { Activator.log(Status.ERROR, e.getMessage(), e); } }
private String getText(ITextRegion region) { return (fParentRegion != null) ? fParentRegion.getText(region) : ""; // $NON-NLS-1$ }
/** nodeRegions must be broken. If you need after, make copy of them. */ private void setupValues( ICSSStyleDeclItem item, ITextRegionList nodeRegions, List propertyValueList) { if (item == null) { return; } ICSSPrimitiveValue value; ITextRegionList regionBuf = new TextRegionListImpl(); String propertyName = item.getPropertyName().toLowerCase(); boolean bFont = (propertyName.equals(PropCMProperty.P_FONT)); // (short-hand) font String propertyValue = null; int status = (propertyName.equals(PropCMProperty.P_VOICE_FAMILY) || propertyName.equals(PropCMProperty.P_FONT_FAMILY)) ? S_COMMA_SEPARATION : S_NORMAL; while (!nodeRegions.isEmpty()) { value = null; ITextRegion region = nodeRegions.remove(0); if (region == null) { continue; } if (propertyValueList != null && !propertyValueList.isEmpty()) { propertyValue = (String) propertyValueList.remove(0); } String type = region.getType(); // if (type == CSSRegionContexts.CSS_DECLARATION_DELIMITER || type // == CSSRegionContexts.CSS_RBRACE) { // break; // } switch (status) { case S_NORMAL: if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION) { regionBuf.add(region); status = S_FUNCTION; } else if (bFont && type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR && fParentRegion.getText(region).equals("/")) { // $NON-NLS-1$ value = createPrimitiveValue(region, propertyValue); status = S_FONT_SLASH; } else if (!isBlank(type)) { value = createPrimitiveValue(region, propertyValue); } break; case S_FUNCTION: if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_PARENTHESIS_CLOSE) { regionBuf.add(region); value = createPrimitiveValue(regionBuf); regionBuf.clear(); status = S_NORMAL; } else if (!isBlank(type)) { regionBuf.add(region); } break; case S_FONT_SLASH: if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_DIMENSION) { value = createPrimitiveValue(region, propertyValue); status = S_COMMA_SEPARATION; } else if (!isBlank(type)) { value = createPrimitiveValue(region, propertyValue); } break; case S_COMMA_SEPARATION: if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR && fParentRegion.getText(region).equals(",")) { // $NON-NLS-1$ value = createPrimitiveValue(regionBuf); regionBuf.clear(); if (value != null) { if (fUpdateContext == null || !fUpdateContext.isActive()) { item.appendValue(value); } } value = createPrimitiveValue(region, propertyValue); } else { regionBuf.add(region); } break; default: break; } if (value != null) { if (fUpdateContext == null || !fUpdateContext.isActive()) { item.appendValue(value); } } } if (!regionBuf.isEmpty()) { value = createPrimitiveValue(regionBuf); if (fUpdateContext == null || !fUpdateContext.isActive()) { item.appendValue(value); } } }
public void customizeDocumentCommand(IDocument document, DocumentCommand c) { if (!isSmartInsertMode()) { return; } if (!(document instanceof IStructuredDocument)) { // This shouldn't happen unless this strategy is used on an invalid document return; } IStructuredDocument doc = (IStructuredDocument) document; // Handle newlines/indentation if (c.length == 0 && c.text != null && TextUtilities.endsWith(doc.getLegalLineDelimiters(), c.text) != -1) { IModelManager modelManager = StructuredModelManager.getModelManager(); IStructuredModel model = modelManager.getModelForRead(doc); if (model != null) { try { final int offset = c.offset; int lineStart = findLineStart(doc, offset); int textStart = findTextStart(doc, lineStart, offset); IStructuredDocumentRegion region = doc.getRegionAtCharacterOffset(textStart); if (region != null && region.getType().equals(XML_TAG_NAME)) { Pair<Integer, Integer> balance = getBalance(doc, textStart, offset); int tagBalance = balance.getFirst(); int bracketBalance = balance.getSecond(); String lineIndent = ""; // $NON-NLS-1$ if (textStart > lineStart) { lineIndent = doc.get(lineStart, textStart - lineStart); } // We only care if tag or bracket balance is greater than 0; // we never *dedent* on negative balances boolean addIndent = false; if (bracketBalance < 0) { // Handle // <foo // ></foo>^ // and // <foo // />^ ITextRegion left = getRegionAt(doc, offset, true /*biasLeft*/); if (left != null && (left.getType().equals(XML_TAG_CLOSE) || left.getType().equals(XML_EMPTY_TAG_CLOSE))) { // Find the corresponding open tag... // The org.eclipse.wst.xml.ui.gotoMatchingTag frequently // doesn't work, it just says "No matching brace found" // (or I would use that here). int targetBalance = 0; ITextRegion right = getRegionAt(doc, offset, false /*biasLeft*/); if (right != null && right.getType().equals(XML_END_TAG_OPEN)) { targetBalance = -1; } int openTag = AndroidXmlCharacterMatcher.findTagBackwards(doc, offset, targetBalance); if (openTag != -1) { // Look up the indentation of the given line lineIndent = AndroidXmlEditor.getIndentAtOffset(doc, openTag); } } } else if (tagBalance > 0 || bracketBalance > 0) { // Add indentation addIndent = true; } StringBuilder sb = new StringBuilder(c.text); sb.append(lineIndent); String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit(); if (addIndent) { sb.append(oneIndentUnit); } // Handle // <foo>^</foo> // turning into // <foo> // ^ // </foo> ITextRegion left = getRegionAt(doc, offset, true /*biasLeft*/); ITextRegion right = getRegionAt(doc, offset, false /*biasLeft*/); if (left != null && right != null && left.getType().equals(XML_TAG_CLOSE) && right.getType().equals(XML_END_TAG_OPEN)) { // Move end tag if (tagBalance > 0 && bracketBalance < 0) { sb.append(oneIndentUnit); } c.caretOffset = offset + sb.length(); c.shiftsCaret = false; sb.append(TextUtilities.getDefaultLineDelimiter(doc)); sb.append(lineIndent); } c.text = sb.toString(); } else if (region != null && region.getType().equals(XML_CONTENT)) { // Indenting in text content. If you're in the middle of editing // text, just copy the current line indentation. // However, if you're editing in leading whitespace (e.g. you press // newline on a blank line following say an element) then figure // out the indentation as if the newline had been pressed at the // end of the element, and insert that amount of indentation. // In this case we need to also make sure to subtract any existing // whitespace on the current line such that if we have // // <foo> // ^ <bar/> // </foo> // // you end up with // // <foo> // // ^<bar/> // </foo> // String text = region.getText(); int regionStart = region.getStartOffset(); int delta = offset - regionStart; boolean inWhitespacePrefix = true; for (int i = 0, n = Math.min(delta, text.length()); i < n; i++) { char ch = text.charAt(i); if (!Character.isWhitespace(ch)) { inWhitespacePrefix = false; break; } } if (inWhitespacePrefix) { IStructuredDocumentRegion previous = region.getPrevious(); if (previous != null && previous.getType() == XML_TAG_NAME) { ITextRegionList subRegions = previous.getRegions(); ITextRegion last = subRegions.get(subRegions.size() - 1); if (last.getType() == XML_TAG_CLOSE || last.getType() == XML_EMPTY_TAG_CLOSE) { int begin = AndroidXmlCharacterMatcher.findTagBackwards( doc, previous.getStartOffset() + last.getStart(), 0); int prevLineStart = findLineStart(doc, begin); int prevTextStart = findTextStart(doc, prevLineStart, begin); String lineIndent = ""; // $NON-NLS-1$ if (prevTextStart > prevLineStart) { lineIndent = doc.get(prevLineStart, prevTextStart - prevLineStart); } StringBuilder sb = new StringBuilder(c.text); sb.append(lineIndent); String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit(); // See if there is whitespace on the insert line that // we should also remove for (int i = delta, n = text.length(); i < n; i++) { char ch = text.charAt(i); if (ch == ' ') { c.length++; } else { break; } } boolean onClosingTagLine = false; if (text.indexOf('\n', delta) == -1) { IStructuredDocumentRegion next = region.getNext(); if (next != null && next.getType() == XML_TAG_NAME) { String nextType = next.getRegions().get(0).getType(); if (nextType == XML_END_TAG_OPEN) { onClosingTagLine = true; } } } boolean addIndent = (last.getType() == XML_TAG_CLOSE) && !onClosingTagLine; if (addIndent) { sb.append(oneIndentUnit); } c.text = sb.toString(); return; } } } copyPreviousLineIndentation(doc, c); } else { copyPreviousLineIndentation(doc, c); } } catch (BadLocationException e) { AdtPlugin.log(e, null); } finally { model.releaseFromRead(); } } } }