mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Support line indent calculation after case/default
This commit is contained in:
+12
-7
@@ -26,19 +26,24 @@ import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.psi.impl.source.codeStyle.JavaLikeLangLineIndentProvider.JavaLikeElement.*;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class JavaLineIndentProvider extends JavaLikeLangLineIndentProvider {
|
||||
private final static HashMap<IElementType, SemanticEditorPosition.SyntaxElement> SYNTAX_MAP = new HashMap<>();
|
||||
static {
|
||||
SYNTAX_MAP.put(TokenType.WHITE_SPACE, JavaLikeElement.Whitespace);
|
||||
SYNTAX_MAP.put(JavaTokenType.SEMICOLON, JavaLikeElement.Semicolon);
|
||||
SYNTAX_MAP.put(JavaTokenType.LBRACE, JavaLikeElement.BlockOpeningBrace);
|
||||
SYNTAX_MAP.put(JavaTokenType.RBRACE, JavaLikeElement.BlockClosingBrace);
|
||||
SYNTAX_MAP.put(JavaTokenType.LBRACKET, JavaLikeElement.ArrayOpeningBracket);
|
||||
SYNTAX_MAP.put(JavaTokenType.RPARENTH, JavaLikeElement.RightParenthesis);
|
||||
SYNTAX_MAP.put(JavaTokenType.LPARENTH, JavaLikeElement.LeftParenthesis);
|
||||
SYNTAX_MAP.put(TokenType.WHITE_SPACE, Whitespace);
|
||||
SYNTAX_MAP.put(JavaTokenType.SEMICOLON, Semicolon);
|
||||
SYNTAX_MAP.put(JavaTokenType.LBRACE, BlockOpeningBrace);
|
||||
SYNTAX_MAP.put(JavaTokenType.RBRACE, BlockClosingBrace);
|
||||
SYNTAX_MAP.put(JavaTokenType.LBRACKET, ArrayOpeningBracket);
|
||||
SYNTAX_MAP.put(JavaTokenType.RPARENTH, RightParenthesis);
|
||||
SYNTAX_MAP.put(JavaTokenType.LPARENTH, LeftParenthesis);
|
||||
SYNTAX_MAP.put(JavaTokenType.COLON, Colon);
|
||||
SYNTAX_MAP.put(JavaTokenType.CASE_KEYWORD, SwitchCase);
|
||||
SYNTAX_MAP.put(JavaTokenType.DEFAULT_KEYWORD, SwitchDefault);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+28
-19
@@ -34,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.formatting.Indent.Type;
|
||||
import static com.intellij.formatting.Indent.Type.*;
|
||||
import static com.intellij.psi.impl.source.codeStyle.JavaLikeLangLineIndentProvider.JavaLikeElement.*;
|
||||
|
||||
/**
|
||||
* A base class Java-like language line indent provider. If JavaLikeLangLineIndentProvider is unable to calculate
|
||||
@@ -41,14 +42,17 @@ import static com.intellij.formatting.Indent.Type.*;
|
||||
*/
|
||||
public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineIndentProvider {
|
||||
|
||||
protected enum JavaLikeElement implements SyntaxElement {
|
||||
public enum JavaLikeElement implements SyntaxElement {
|
||||
Whitespace,
|
||||
Semicolon,
|
||||
BlockOpeningBrace,
|
||||
BlockClosingBrace,
|
||||
ArrayOpeningBracket,
|
||||
RightParenthesis,
|
||||
LeftParenthesis
|
||||
LeftParenthesis,
|
||||
Colon,
|
||||
SwitchCase,
|
||||
SwitchDefault
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -66,25 +70,30 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI
|
||||
if (offset > 0) {
|
||||
offset--;
|
||||
if (getPosition(editor, offset).matchesRule(
|
||||
position -> position.isAt(JavaLikeElement.Whitespace) &&
|
||||
position -> position.isAt(Whitespace) &&
|
||||
position.isAtMultiline())) {
|
||||
if (getPosition(editor, offset).matchesRule(
|
||||
position -> position
|
||||
.before()
|
||||
.beforeOptional(JavaLikeElement.Semicolon)
|
||||
.beforeOptional(JavaLikeElement.Whitespace)
|
||||
.isAt(JavaLikeElement.BlockClosingBrace))) {
|
||||
return createIndentData(getBlockIndentType(project, language), JavaLikeElement.BlockClosingBrace);
|
||||
.beforeOptional(Semicolon)
|
||||
.beforeOptional(Whitespace)
|
||||
.isAt(BlockClosingBrace))) {
|
||||
return createIndentData(getBlockIndentType(project, language), BlockClosingBrace);
|
||||
}
|
||||
else if (getPosition(editor, offset).matchesRule(
|
||||
position -> position.before().isAt(JavaLikeElement.ArrayOpeningBracket)
|
||||
position -> position.before().isAt(ArrayOpeningBracket)
|
||||
)) {
|
||||
return createIndentData(CONTINUATION, JavaLikeElement.ArrayOpeningBracket);
|
||||
return createIndentData(CONTINUATION, ArrayOpeningBracket);
|
||||
}
|
||||
else if (getPosition(editor, offset).matchesRule(
|
||||
position -> position.before().isAt(JavaLikeElement.BlockOpeningBrace)
|
||||
position -> position.before().isAt(BlockOpeningBrace)
|
||||
)) {
|
||||
return createIndentData(getIndentTypeInBlock(project, language), JavaLikeElement.BlockOpeningBrace);
|
||||
return createIndentData(getIndentTypeInBlock(project, language), BlockOpeningBrace);
|
||||
}
|
||||
else if (getPosition(editor, offset).matchesRule(
|
||||
position -> position.before().isAt(Colon) && position.isAfterOnSameLine(SwitchCase, SwitchDefault)
|
||||
)) {
|
||||
return createIndentData(NORMAL, SwitchCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +161,7 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI
|
||||
@NotNull CharSequence docChars,
|
||||
@NotNull SyntaxElement afterElement,
|
||||
int offset) {
|
||||
if (JavaLikeElement.BlockOpeningBrace.equals(afterElement) && !isOnSeparateLine(editor, afterElement, offset)) {
|
||||
if (BlockOpeningBrace.equals(afterElement) && !isOnSeparateLine(editor, afterElement, offset)) {
|
||||
return findStatementStart(editor, afterElement, offset);
|
||||
}
|
||||
return CharArrayUtil.shiftBackward(docChars, offset, " \t\n\r");
|
||||
@@ -161,10 +170,10 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI
|
||||
|
||||
private boolean isOnSeparateLine(@NotNull Editor editor, @NotNull SyntaxElement element, int offset) {
|
||||
SemanticEditorPosition position = getPosition(editor, offset);
|
||||
position.beforeOptional(JavaLikeElement.Whitespace);
|
||||
position.beforeOptional(Whitespace);
|
||||
if (position.isAt(element)) {
|
||||
position.before();
|
||||
if (position.isAtEnd() || position.isAt(JavaLikeElement.Whitespace) && position.isAtMultiline()) return true;
|
||||
if (position.isAtEnd() || position.isAt(Whitespace) && position.isAtMultiline()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -173,14 +182,14 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI
|
||||
private int findStatementStart(@NotNull Editor editor, @NotNull SyntaxElement afterElement, int offset) {
|
||||
SemanticEditorPosition position = getPosition(editor, offset);
|
||||
position
|
||||
.beforeOptional(JavaLikeElement.Whitespace)
|
||||
.beforeOptional(Whitespace)
|
||||
.beforeOptional(afterElement)
|
||||
.beforeOptional(JavaLikeElement.Whitespace);
|
||||
if (position.isAt(JavaLikeElement.RightParenthesis)) {
|
||||
position.beforeParentheses(JavaLikeElement.LeftParenthesis, JavaLikeElement.RightParenthesis);
|
||||
.beforeOptional(Whitespace);
|
||||
if (position.isAt(RightParenthesis)) {
|
||||
position.beforeParentheses(LeftParenthesis, RightParenthesis);
|
||||
}
|
||||
while (!position.isAtEnd()) {
|
||||
if (position.isAt(JavaLikeElement.Whitespace) && position.isAtMultiline()) {
|
||||
if (position.isAt(Whitespace) && position.isAtMultiline()) {
|
||||
return position.after().getStartOffset();
|
||||
}
|
||||
position.before();
|
||||
|
||||
+12
@@ -81,6 +81,18 @@ public abstract class SemanticEditorPosition {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isAfterOnSameLine(@NotNull SyntaxElement... syntaxElements) {
|
||||
myIterator.retreat();
|
||||
while (!myIterator.atEnd() && !isAtMultiline()) {
|
||||
SyntaxElement currElement = map(myIterator.getTokenType());
|
||||
for (SyntaxElement element : syntaxElements) {
|
||||
if (element.equals(currElement)) return true;
|
||||
}
|
||||
myIterator.retreat();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAt(@NotNull SyntaxElement syntaxElement) {
|
||||
return !myIterator.atEnd() && syntaxElement.equals(map(myIterator.getTokenType()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user