[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[xtext-dev] context dependend formatting
|
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.