mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-26 19:06:24 +07:00
java: move soft-wrap calculation to shared module (allow to use it by editor on frontend) IJPL-185110
GitOrigin-RevId: a9912c146eb8394ebe0134cdf91374577e387bf1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a2a6c7c8bc
commit
3f520e829a
@@ -62,6 +62,8 @@
|
||||
|
||||
<lang.rearranger language="JAVA" implementationClass="com.intellij.psi.codeStyle.arrangement.JavaRearranger"/>
|
||||
|
||||
<lang.lineWrapStrategy language="JAVA" implementationClass="com.intellij.psi.formatter.java.JavaLineWrapPositionStrategy"/>
|
||||
|
||||
<registryKey key="java.formatter.chained.calls.pre212.compatibility"
|
||||
defaultValue="false"
|
||||
description="Format chained calls as in versions prior to 2021.2"/>
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.formatter.java;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.PsiAwareDefaultLineWrapPositionStrategy;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.JavaDocTokenType;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class JavaLineWrapPositionStrategy extends PsiAwareDefaultLineWrapPositionStrategy {
|
||||
|
||||
private static final IElementType[] ALLOWED_TYPES = {
|
||||
JavaTokenType.C_STYLE_COMMENT,
|
||||
JavaTokenType.END_OF_LINE_COMMENT,
|
||||
JavaTokenType.STRING_LITERAL,
|
||||
JavaDocTokenType.DOC_COMMENT_DATA,
|
||||
JavaTokenType.EQ,
|
||||
JavaTokenType.COMMA,
|
||||
JavaTokenType.QUEST,
|
||||
JavaTokenType.COLON
|
||||
};
|
||||
|
||||
public static final String A_LINK_START = "<a";
|
||||
public static final String A_LINK_END = "</a>";
|
||||
|
||||
public static final String PRE_TAG_START = "<pre";
|
||||
public static final String PRE_TAG_END = "</pre>";
|
||||
|
||||
public JavaLineWrapPositionStrategy() {
|
||||
super(true, ALLOWED_TYPES);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doCalculateWrapPosition(@NotNull Document document,
|
||||
@Nullable Project project,
|
||||
@NotNull PsiElement element,
|
||||
int startOffset,
|
||||
int endOffset,
|
||||
int maxPreferredOffset,
|
||||
boolean isSoftWrap) {
|
||||
if (element.getNode().getElementType() == JavaDocTokenType.DOC_COMMENT_DATA) {
|
||||
CharSequence docChars = document.getCharsSequence();
|
||||
if (isInsidePreTag(element, docChars, startOffset) || isInsidePreTag(element, docChars, endOffset)) {
|
||||
return NO_LINE_WRAP;
|
||||
}
|
||||
int refStart = CharArrayUtil.indexOf(docChars, A_LINK_START, startOffset, endOffset);
|
||||
if (refStart >= 0 && refStart < maxPreferredOffset) {
|
||||
int refEnd = CharArrayUtil.indexOf(docChars, A_LINK_END, refStart, endOffset);
|
||||
if (refEnd >= 0 && refEnd < maxPreferredOffset) return refEnd + A_LINK_END.length();
|
||||
return refStart;
|
||||
}
|
||||
}
|
||||
int wrapPos = super.doCalculateWrapPosition(document, project, element, startOffset, endOffset, maxPreferredOffset, isSoftWrap);
|
||||
if (element.getNode().getElementType() == JavaTokenType.STRING_LITERAL) {
|
||||
TextRange range = element.getTextRange();
|
||||
if (range.getEndOffset() - wrapPos <= 1) {
|
||||
wrapPos = range.getEndOffset();
|
||||
}
|
||||
else if (wrapPos - range.getStartOffset() <= 1) {
|
||||
wrapPos = range.getStartOffset();
|
||||
}
|
||||
}
|
||||
else if (element.getNode().getElementType() == JavaTokenType.END_OF_LINE_COMMENT) {
|
||||
CharSequence docChars = document.getCharsSequence();
|
||||
TextRange range = element.getTextRange();
|
||||
int urlOffset = getUrlOffset(docChars, startOffset, endOffset);
|
||||
if (urlOffset >= 0) {
|
||||
int urlEnd = urlOffset;
|
||||
while (urlEnd < range.getEndOffset()) {
|
||||
if (StringUtil.isWhiteSpace(docChars.charAt(urlEnd))) {
|
||||
break;
|
||||
}
|
||||
urlEnd ++;
|
||||
}
|
||||
if (urlEnd > wrapPos)
|
||||
return urlEnd < range.getEndOffset() ? urlEnd : NO_LINE_WRAP;
|
||||
}
|
||||
}
|
||||
return wrapPos;
|
||||
}
|
||||
|
||||
private static int getUrlOffset(@NotNull CharSequence chars, int startOffset, int endOffset) {
|
||||
@SuppressWarnings("HttpUrlsUsage") final String[] URL_PREFIX = { "http://", "https://", "ftp://"};
|
||||
for (String urlPrefix : URL_PREFIX) {
|
||||
int urlOffset = CharArrayUtil.indexOf(chars, urlPrefix, startOffset, endOffset);
|
||||
if (urlOffset >= 0) {
|
||||
return urlOffset;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static boolean isInsidePreTag(@NotNull PsiElement element, @NotNull CharSequence chars, int offset) {
|
||||
PsiElement parent = PsiTreeUtil.findFirstParent(
|
||||
element, e -> e.getNode().getElementType() == JavaDocElementType.DOC_COMMENT);
|
||||
if (parent != null) {
|
||||
int preStart = CharArrayUtil.lastIndexOf(chars, PRE_TAG_START, offset);
|
||||
if (preStart >= 0) {
|
||||
int preEnd = CharArrayUtil.indexOf(chars, PRE_TAG_END, preStart, chars.length());
|
||||
return preEnd > offset;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user