Being able to define formatting based on the actual state of the model (and parse tree) is an excellent idea.
Feel free to add your 2 cents.
Cheers, Sven On May 18, 2010, at 9:24 AM, d green wrote: It would be nice to have the current AbstractNode in method FormattingConfigBasedStream::addLineEntry available. The grammarElement and the string value isn't enough for context sensitiv formatting. The current workaround looks like a function eg interface in a subclass of FormattingConfigBasedStream protected AbstractNode node = null; public void setNodeHint(AbstractNode node) { this.node = node; } This is called in a function override in a subclass of DefaultNodeModelFormatter, eg
@Override public IFormattedRegion format(CompositeNode root, int offset, int length) { List<AbstractNode> nodes = getLeafs(root, offset, offset + length); if (nodes.size() == 0) return null;
String indent = getIndentation(root, offset); TokenStringBuffer buf = new TokenStringBuffer(); ITokenStream fmt = formatter.createFormatterStream(indent, buf, false); // this is xcl XclFormattingConfigBasedStream xcl = null; if ( fmt instanceof XclFormattingConfigBasedStream ) xcl = (XclFormattingConfigBasedStream) fmt; try { for (AbstractNode n : nodes) { // this is xcl if ( null != xcl) xcl.setNodeHint(n); ...
No you can do context sensitive formatting eg leave the linebreaks out for an xml-like grammar just for <i>-tags in the subclass of FormattingConfigBasedStream protected boolean cleanNext = false;
@Override protected void addLineEntry(EObject grammarElement, String value, boolean isHidden) throws IOException { Set<ElementLocator> locators = collectLocators(last, grammarElement); // System.out.println(loc + " --> " + value.replaceAll("\n", "\\n")); if (cleanNext) { locators = normalizeLinebreaks(locators); cleanNext = false; } if (value.equals("<") || value.equals("</")) { // we ar on Start or Stop if (node.eContainer() instanceof CompositeNode) { EObject obj = ((CompositeNode) node.eContainer()).getElement(); if (obj instanceof Start) { Start start = (Start) obj; if ("em".equals(start.getStart())) { locators = normalizeLinebreaks(locators); } } else if (obj instanceof Stop) { Stop stop = (Stop) obj; if ("em".equals(stop.getStop())) { locators = normalizeLinebreaks(locators); } } } } else if (value.equals(">") || value.equals("/>")) { // we are on the element if (node.eContainer() instanceof CompositeNode) { EObject obj = ((CompositeNode) node.eContainer()).getElement(); if (obj instanceof Start) { Start start = (Start) obj; if ("em".equals(start.getStart())) { cleanNext = true; } } else if (obj instanceof Stop) { Stop elem = ((Stop) obj); if ("em".equals(elem.getStop())) { cleanNext = true; } } } } last = grammarElement; LineEntry e = new LineEntry(grammarElement, value, true, locators, preservedWS, indentationLevel); preservedWS = null; if (currentLine == null) currentLine = new Line(); Line newLine = currentLine.add(e); if (newLine != null) currentLine = newLine; } protected Set<ElementLocator> normalizeLinebreaks( Set<ElementLocator> locators) { Set<ElementLocator> locs = Sets.newHashSet();
for (ElementLocator elm : locators) { if (!(elm instanceof LinewrapLocator || elm instanceof IndentationLocatorStart || elm instanceof IndentationLocatorEnd)) locs.add(elm); } return locs; } Having AbstractNode availiable in FormattingConfigBasedStream would do this in a standard way, at the best in a new overrideable function like normalizeCurrent with the content of the bold part.
_______________________________________________ xtext-dev mailing list xtext-dev@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/xtext-dev
|