package com.siberika.idea.pascal.editor.formatter; import com.intellij.formatting.Block; import com.intellij.formatting.FormattingModel; import com.intellij.formatting.FormattingModelBuilder; import com.intellij.formatting.FormattingModelProvider; import com.intellij.formatting.SpacingBuilder; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.tree.TokenSet; import com.siberika.idea.pascal.PascalLanguage; import com.siberika.idea.pascal.lang.psi.PasTypes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Author: George Bakhtadze * Date: 01/10/2013 */ public class PascalFormatter implements FormattingModelBuilder { private static final TokenSet TOKENS_CLASS_DECL = TokenSet.create(PasTypes.CLASS_FIELD, PasTypes.EXPORTED_ROUTINE, PasTypes.CLASS_PROPERTY, PasTypes.CLASS_METHOD_RESOLUTION, PasTypes.VISIBILITY); /*static final TokenSet TOKENS_USED = TokenSet.create( PasTypes.COMMA, PasTypes.NAMED_IDENT, PasTypes.LPAREN, PasTypes.ASSIGN_OP, PasTypes.ASSIGN_PART, PasTypes.BEGIN, PasTypes.COMPOUND_STATEMENT, PasTypes.VAR, PasTypes.CONST, PasTypes.TYPE, PasTypes.VAR_SECTION, PasTypes.CONST_SECTION, PasTypes.TYPE_SECTION, PasTypes.COLON, PasTypes.TYPE_DECL, PasTypes.BLOCK_BODY, PasTypes.STATEMENT, PasTypes.END, PasTypes.INTERFACE, PasTypes.IMPLEMENTATION, PasTypes.BLOCK_BODY );*/ @NotNull @Override public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { Block block = new PascalBlock(element.getContainingFile().getNode(), settings, null, null); return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), block, settings); } @Nullable @Override public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) { return null; //To change body of implemented methods use File | Settings | File Templates. } static SpacingBuilder createSpacingBuilder(CodeStyleSettings settings) { return new SpacingBuilder(settings, PascalLanguage.INSTANCE) .between(PasTypes.COMMA, PasTypes.NAMED_IDENT).spacing(1, 1, 0, true, 1) .between(PasTypes.COMMA, PasTypes.EXPRESSION).spacing(1, 1, 0, true, 1) .between(PasTypes.REF_NAMED_IDENT, PasTypes.LPAREN).spacing(0, 0, 0, true, 1) .after(PasTypes.ASSIGN_OP).spacing(1, 1, 0, true, 1) .before(PasTypes.ASSIGN_PART).spacing(1, 1, 0, true, 1) .after(PasTypes.ADD_OP).spacing(1, 1, 0, true, 1) .before(PasTypes.ADD_OP).spacing(1, 1, 0, true, 1) .after(PasTypes.REL_OP).spacing(1, 1, 0, true, 1) .before(PasTypes.REL_OP).spacing(1, 1, 0, true, 1) .after(PasTypes.MUL_OP).spacing(1, 1, 0, true, 1) .before(PasTypes.MUL_OP).spacing(1, 1, 0, true, 1) .afterInside(PasTypes.BEGIN, PasTypes.COMPOUND_STATEMENT).lineBreakInCode() .afterInside(PasTypes.VAR, PasTypes.VAR_SECTION).lineBreakInCode() .afterInside(PasTypes.CONST, PasTypes.CONST_SECTION).lineBreakInCode() .afterInside(PasTypes.TYPE, PasTypes.TYPE_SECTION).lineBreakInCode() .beforeInside(PasTypes.VAR, PasTypes.VAR_SECTION).blankLines(1) .beforeInside(PasTypes.CONST, PasTypes.CONST_SECTION).blankLines(1) .beforeInside(PasTypes.TYPE, PasTypes.TYPE_SECTION).blankLines(1) .between(TOKENS_CLASS_DECL, TOKENS_CLASS_DECL).lineBreakInCode() .between(PasTypes.COLON, PasTypes.TYPE_DECL).spacing(1, 1, 0, true, 1) .before(PasTypes.BLOCK_BODY).lineBreakInCode() .before(PasTypes.COMPOUND_STATEMENT).lineBreakInCode() .after(PasTypes.COMPOUND_STATEMENT).lineBreakInCode() .between(PasTypes.STATEMENT, PasTypes.END).lineBreakInCode() .afterInside(PasTypes.INTERFACE, PasTypes.UNIT_MODULE_HEAD).blankLines(1) .after(PasTypes.IMPLEMENTATION).blankLines(1) .after(PasTypes.BLOCK_BODY).blankLines(1) .after(PasTypes.EQ).spacing(1, 1, 0, true, 1) .before(PasTypes.EQ).spacing(0, 1, 0, true, 1) ; } }