IntelliJ Platform SDK DevGuide

15. Formatter

格式化程序允许根据代码样式设置自动重新格式化代码.

15.1.

定义一个块

格式化程序使用块来接收每个PSI元素的格式规则.

我们的目标是用这样的块覆盖每个PSI元素. 由于每个块都构建自己的子块,我们可以生成额外的块或跳过任何PSI元素.

package com.simpleplugin; import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.psi.TokenType; import com.intellij.psi.formatter.common.AbstractBlock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; public class SimpleBlock extends AbstractBlock { private SpacingBuilder spacingBuilder; protected SimpleBlock(@NotNull ASTNode node, @Nullable Wrap wrap, @Nullable Alignment alignment, SpacingBuilder spacingBuilder) { super(node, wrap, alignment); this.spacingBuilder = spacingBuilder; } @Override protected List<Block> buildChildren() { List<Block> blocks = new ArrayList<Block>(); ASTNode child = myNode.getFirstChildNode(); while (child != null) { if (child.getElementType() != TokenType.WHITE_SPACE) { Block block = new SimpleBlock(child, Wrap.createWrap(WrapType.NONE, false), Alignment.createAlignment(), spacingBuilder); blocks.add(block); } child = child.getTreeNext(); } return blocks; } @Override public Indent getIndent() { return Indent.getNoneIndent(); } @Nullable @Override public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { return spacingBuilder.getSpacing(this, child1, child2); } @Override public boolean isLeaf() { return myNode.getFirstChildNode() == null; } }

15.2.

定义格式模型构建器

让我们定义一个格式化程序,删除除属性分隔符周围的单个空格之外的额外空格.

package com.simpleplugin; import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.simpleplugin.psi.SimpleTypes; import org.jetbrains.annotations.*; public class SimpleFormattingModelBuilder implements FormattingModelBuilder { @NotNull @Override public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { return FormattingModelProvider .createFormattingModelForPsiFile(element.getContainingFile(), new SimpleBlock(element.getNode(), Wrap.createWrap(WrapType.NONE, false), Alignment.createAlignment(), createSpaceBuilder(settings)), settings); } private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { return new SpacingBuilder(settings, SimpleLanguage.INSTANCE) .around(SimpleTypes.SEPARATOR) .spaceIf(settings.getCommonSettings(SimpleLanguage.INSTANCE.getID()).SPACE_AROUND_ASSIGNMENT_OPERATORS) .before(SimpleTypes.PROPERTY) .none(); } @Nullable @Override public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) { return null; } }

15.3.

注册格式化程序

<lang.formatter language="Simple" implementationClass="com.simpleplugin.SimpleFormattingModelBuilder"/>

15.4.

运行该项目

Now add some extra spaces and reformat the code via Code | Reformat Code.

格式化

Last modified: 11 May 2019