使用 xtext 的 quickfix 格式

quickfix format using xtext

我正在读一本书 "Implementing DSL with xtext and xtend",它说当使用上下文菜单中的格式或使用它的快捷方式 "Ctrl + Shift + F" 时,会调用格式化程序。它还说 "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".

话虽如此,我遇到了一个问题,即当我的 quickfix 被调用时,格式化程序不会被调用,导致文本看起来很糟糕。 示例:

----1-----

---快速修复前的文字---

entity myentity {
    FooBar s;
} entity second{}

----2-----

---Quickfix 添加未实现的实体---

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

----3-----

---手动调用格式化程序(它应该是什么样子)---

entity myentity {
    FooBar s;
}

entity FooBar {
}

entity second {
}

QuickFix 实施:

@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)])
        ]
    );
}

格式化程序实现:

@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)
}

我一直在搜索格式化程序是否真的像书上所说的那样在快速修复后调用但一无所获。这是真的吗?如果不是,我如何从 quickfix 代码以编程方式调用格式化程序。

可以

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();
    }

}

发现这个帖子很有用,我想问一下有没有办法做到这一点,只要用户完成编写代码,它就会自动漂亮格式化(或在运行时)而无需 (ctrl+shift+f)。以上建议只适用于 quickfix。