Home » Modeling » TMF (Xtext) » IAutoWrapFormatter with indent ignores newline under certain conditions
IAutoWrapFormatter with indent ignores newline under certain conditions [message #1755819] |
Wed, 08 March 2017 07:19  |
Eclipse User |
|
|
|
Hello,
I'm trying to implement a formatter which indents lines which are autowrapped. Similiar to slide 128 from de.slideshare.net/meysholdt/xtexts-new-formatter-api. So e.g. a model like
if: "CONDITION" = "VALUE1", "VALUE2", "VALUE3", "VALUE4", "VALUE5", "VALUE6", "VALUE7" ("RESULT")
should be displayed as
if: "CONDITION" = "VALUE1", "VALUE2",
"VALUE3", "VALUE4", "VALUE5",
"VALUE6", "VALUE7"
("RESULT")
Since I don't have any terminating keyword, I use regionForEObject.nextHiddenRegion to get the end hidden region for the indent. Everything works fine as long as the last part of the multi-wrapped line contains more than one element. So e.g. the example above works fine. But if the last part contains only one element, the indentation seems to cause a conflict with the newline for the result element.
E.g.
if: "CONDITION" = "VALUE1", "VALUE2", "VALUE3", "VALUE4", "VALUE5", "VALUE6" ("RESULT1")
if: "CONDITION" = "VALUE7", "VALUE8", "VALUE9", "VALUE10", "VALUE11", "VALUE12" ("RESULT2")
will be displayed as
if: "CONDITION" = "VALUE1", "VALUE2",
"VALUE3", "VALUE4", "VALUE5",
"VALUE6" ("RESULT1")
if: "CONDITION" = "VALUE7", "VALUE8",
"VALUE9", "VALUE10", "VALUE11",
"VALUE12" ("RESULT2")
The instruction for a newline seems to be ignored and the second entry is indented twice.
My DSL is very simple:
Model:
rules+=Rules*;
Rules:
condition = Condition
result = Result
;
Result:
"(" values += STRING ("," values += STRING)* ")"
;
Condition:
"if:" condition = ConditionAtom
;
ConditionAtom:
name = STRING "="
values += STRING ("," values += STRING)*
;
The formatter is also quite simple:
class MyDslFormatter extends AbstractFormatter2 {
@Inject extension MyDslGrammarAccess
def dispatch void format(Model model, extension IFormattableDocument document) {
for (Rules rules : model.getRules()) {
rules.format;
}
}
def dispatch void format(Rules rules, extension IFormattableDocument document) {
rules.getCondition.format;
rules.getResult.format;
}
def dispatch void format(Result result, extension IFormattableDocument document){
result.regionFor.keyword("(").prepend[newLine]
}
def dispatch void format(Condition condition, extension IFormattableDocument document) {
format(condition.condition, document);
}
private static class BooleanWrapper {
boolean first = true;
def isFirst(){
return first;
}
def setIsFirst(boolean value){
first = value;
}
}
def dispatch void format(ConditionAtom conditionatom, extension IFormattableDocument document) {
val firstIndent = new BooleanWrapper() // needed to prevent double indent if line is autowrapped twice
val access = conditionAtomAccess
val IAutowrapFormatter autoWrapIndent = [region, wrapped, doc |
if (firstIndent.isFirst){
firstIndent.isFirst = false
val first = (region as IWhitespace).hiddenRegion
val last = conditionatom.regionForEObject.nextHiddenRegion
println("indent white for " + first.offset + " to " + last.offset + " (" + region.textRegionAccess.regionForDocument.text.substring(first.offset, last.offset) + ") ")
doc.set(first, last, [indent])
}
]
conditionatom.allRegionsFor.keywords(",").forEach[append[autowrap; onAutowrap = autoWrapIndent]]
}
}
I have attached my workspace with the dsl and a simple test to show the problem. The test testLongLastLinePart runs fine but the test testShortLastLinePart has the problem described above.
Any help would be greatly appreciated.
Best regards
Florian Schwarz
|
|
| |
Re: IAutoWrapFormatter with indent ignores newline under certain conditions [message #1756027 is a reply to message #1755819] |
Fri, 10 March 2017 04:10  |
Eclipse User |
|
|
|
Hi Christian,
thank you very much for your reply.
I filed the bug (has you have already noticed).
The workaround you provided works well for the small example project, but my original project involved a boolean condition tree which should be indented correctly, e.g.
if: businessProcessType = APPLICATION_CREATE, PROPOSAL_CREATE, APPLICATION_MODIFY
and: (
entity = ct:DokNwVar, ct:HvGruppe
or: entity = ct:SteuAuftReg
and: dataField = SteuAuftReg.auftlgFormel, SteuAuftReg.beitragsTyp, SteuAuftReg.betragsArt,
SteuAuftReg.kzAktBearb, SteuAuftReg.kzInitialKBF, SteuAuftReg.parAnteil
or: entity = ct:DokNw
and: dataField = ctAttrGroup:DokNwAttrs
)
(RESULT)
From my understanding of your workaround, this wouldn't work for my project as it is not necessarily the last element of my condition that needs a line wrapping (and the rules.result.regionFor.keyword("(") would work only for the last). So I guess I have to live without the indentation of the wrapped line until the bug is fixed.
Best regards
Florian
|
|
|
Goto Forum:
Current Time: Wed May 07 04:46:09 EDT 2025
Powered by FUDForum. Page generated in 0.07007 seconds
|