blob: d8b5cdd52de723a1cfac344e097fd592ead99afc [file] [log] [blame]
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.formatting;
import org.jetbrains.annotations.NotNull;
/**
* {@link BlockAlignmentProcessor} implementation for {@link Alignment} that
* {@link Alignment.Anchor#RIGHT anchors to the right block edge}.
*
* @author Denis Zhdanov
* @since 4/28/11 4:06 PM
*/
public class RightEdgeAlignmentProcessor extends AbstractBlockAlignmentProcessor {
@Override
protected IndentData calculateAlignmentAnchorIndent(@NotNull Context context) {
LeafBlockWrapper offsetResponsibleBlock = context.alignment.getOffsetRespBlockBefore(context.targetBlock);
if (offsetResponsibleBlock == null) {
return null;
}
final WhiteSpace whiteSpace = offsetResponsibleBlock.getWhiteSpace();
if (whiteSpace.containsLineFeeds()) {
return new IndentData(whiteSpace.getIndentSpaces() + offsetResponsibleBlock.getSymbolsAtTheLastLine(), whiteSpace.getSpaces());
}
else {
final int targetIndent = CoreFormatterUtil.getStartColumn(offsetResponsibleBlock)
+ offsetResponsibleBlock.getSymbolsAtTheLastLine();
final AbstractBlockWrapper prevIndentedBlock = CoreFormatterUtil.getIndentedParentBlock(context.targetBlock);
if (prevIndentedBlock == null) {
return new IndentData(0, targetIndent);
}
else {
final int parentIndent = prevIndentedBlock.getWhiteSpace().getIndentOffset();
return new IndentData(parentIndent, targetIndent - parentIndent);
}
}
}
@Override
protected boolean applyIndentToTheFirstBlockOnLine(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
WhiteSpace whiteSpace = context.targetBlock.getWhiteSpace();
int indentSpaces = alignmentAnchorIndent.getIndentSpaces();
int spaces = alignmentAnchorIndent.getSpaces() - context.targetBlock.getSymbolsAtTheLastLine();
if (spaces < 0) {
indentSpaces += spaces;
spaces = 0;
}
if (indentSpaces >= 0) {
whiteSpace.setSpaces(spaces, indentSpaces);
return true;
}
if (whiteSpace.getTotalSpaces() > 0) {
// The general idea is that there is a possible case that particular block that starts new line is much wider than its
// preceding aligned block and its white space is not empty. We may move it to the left then trying to preserve its
// indent.
//
// Example:
// block11 block12
// test-block-that-has-rather-big-width-and-aligned-to-block12
// Let's say, the last block has indent '10', hence, the result would be:
// block11 block12
// test-block-that-has-rather-big-width-and-aligned-to-block12
CompositeBlockWrapper parent = context.targetBlock.getParent();
if (parent != null) {
IndentData childOffset = CoreFormatterUtil.getIndent(
context.indentOptions, context.targetBlock, context.targetBlock.getStartOffset()
);
if (whiteSpace.getTotalSpaces() > childOffset.getTotalSpaces()) {
int leftShift = whiteSpace.getTotalSpaces() - childOffset.getTotalSpaces();
if (leftShift >= whiteSpace.getSpaces()) {
spaces = 0;
indentSpaces = whiteSpace.getIndentSpaces() - (leftShift - whiteSpace.getSpaces());
}
else {
spaces = whiteSpace.getSpaces() - leftShift;
indentSpaces = whiteSpace.getIndentSpaces();
}
}
whiteSpace.setSpaces(spaces, indentSpaces);
}
}
return false;
}
@Override
protected int getAlignmentIndentDiff(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context) {
IndentData indentBeforeBlock = context.targetBlock.getNumberOfSymbolsBeforeBlock();
int numberOfSymbolsBeforeBlock = indentBeforeBlock.getTotalSpaces() + context.targetBlock.getSymbolsAtTheLastLine();
return alignmentAnchorIndent.getTotalSpaces() - numberOfSymbolsBeforeBlock;
}
}