Being able to define formatting based on the actual state of the model
(and parse tree) is an excellent idea.
I've filed a bugzilla https://bugs.eclipse.org/bugs/show_bug.cgi?id=313289
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
[email protected]
https://dev.eclipse.org/mailman/listinfo/xtext-dev
_______________________________________________
xtext-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/xtext-dev