quickfix format using xtext

937 views Asked by At

I am reading from the book "Implementing DSL with xtext and xtend" it says that formatter is invoked when of course the Format from the context menu is used or the shortcut for it "Ctrl + Shift + F" is used. It also says that "If you provide a custom formatter this will be used not only when the format menu is invoked but also when xtext needs to update the editor contents after a manual modification of the AST model( for example a quickfix performing a semantic modification".

With that said I am having a problem that when my quickfix is invoked the formatter doesn't get invoked resulting in a terrible looking text. Example:

----1-----

---Text before quickfix---

entity myentity {
    FooBar s;
} entity second{}

----2-----

---Quickfix add unimplemented entity---

entity myentity {
    FooBar s;
} entity FooBar {
} entity second{}

----3-----

---invoking the formatter MANUALLY(How it should look like)---

entity myentity {
    FooBar s;
}

entity FooBar {
}

entity second {
}

QuickFix implementation:

@Fix(Diagnostic::LINKING_DIAGNOSTIC)
def CreateMissingEntity(Issue issue, IssueResolutionAcceptor acceptor)
{
    acceptor.accept(issue,"Create missing entity.","Create missing entity.", "" ,
        [element, context | 
            val currentEntity = element.getContainerOfType(typeof(Entity))
            val model = currentEntity.eContainer as Model
            model.entities.add(model.entities.indexOf(currentEntity)+1, EntitiesFactory::eINSTANCE.createEntity() => [name = context.xtextDocument.get(issue.offset,issue.length)])
        ]
    );
}

Formatter implementation:

@Inject extension EntitiesGrammarAccess g

override protected void configureFormatting(FormattingConfig c) {
    //entitites
    val e = g.entityAccess
    // indentation between {}
    c.setIndentation(e.leftCurlyBracketKeyword_3,e.rightCurlyBracketKeyword_5)
    // newline after {
    c.setLinewrap.after(e.leftCurlyBracketKeyword_3)
    // newlines after }
    c.setLinewrap(2).after(e.rightCurlyBracketKeyword_5)
    //attributes
    val a = g.attributeAccess
    // newline after ;
    c.setLinewrap.after(a.semicolonKeyword_2)
    // remove spaces before ;
    c.setNoSpace.before(a.semicolonKeyword_2)

    c.setLinewrap(0, 1, 2).before(SL_COMMENTRule)
    c.setLinewrap(0, 1, 2).before(ML_COMMENTRule)
    c.setLinewrap(0, 1, 1).after(ML_COMMENTRule)
}

I have been searching a lot if the formatter is actually invoked as the book says after a quickfix but found nothing. Is this real? and if not how can I invoke the formatter programmatically from the quickfix code.

1

There are 1 answers

5
Christian Dietrich On BEST ANSWER

That is rather a can that an is point

public class MyDslUiModule extends org.xtext.example.mydsl1.ui.AbstractMyDslUiModule {
    public MyDslUiModule(AbstractUIPlugin plugin) {
        super(plugin);
    }

    public Class<? extends ITextEditComposer> bindITextEditComposer() {
        return MyDslTextEditComposer.class;
    }
}


public class MyDslTextEditComposer extends DefaultTextEditComposer {

    @Override
    protected SaveOptions getSaveOptions() {
        return SaveOptions.newBuilder().format().getOptions();
    }

}