diff --git a/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java b/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java index 27ebf3d3d4a5..3d35e35e2022 100644 --- a/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java +++ b/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java @@ -15,18 +15,44 @@ */ package com.intellij.psi.formatter; -import com.intellij.openapi.editor.LineWrapPositionStrategy; -import com.intellij.openapi.editor.PsiAwareDefaultLineWrapPositionStrategy; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.project.Project; import com.intellij.psi.TokenType; import com.intellij.psi.xml.XmlElementType; import com.intellij.psi.xml.XmlTokenType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * {@link LineWrapPositionStrategy} for markup languages like XML, HTML etc. */ public class MarkupLineWrapPositionStrategy extends PsiAwareDefaultLineWrapPositionStrategy { + private final DefaultLineWrapPositionStrategy myDefaultStrategy = new DefaultLineWrapPositionStrategy(); + public MarkupLineWrapPositionStrategy() { super(true, XmlElementType.XML_TEXT, XmlElementType.HTML_RAW_TEXT, XmlTokenType.XML_COMMENT_CHARACTERS, TokenType.WHITE_SPACE); + + myDefaultStrategy.addRule(new GenericLineWrapPositionStrategy.Rule('<', GenericLineWrapPositionStrategy.WrapCondition.BEFORE)); + myDefaultStrategy.addRule(new GenericLineWrapPositionStrategy.Rule('/', GenericLineWrapPositionStrategy.WrapCondition.AFTER, + GenericLineWrapPositionStrategy.Rule.DEFAULT_WEIGHT - 2)); + } + + @Override + public int calculateWrapPosition(@NotNull Document document, + @Nullable Project project, + int startOffset, + int endOffset, + int maxPreferredOffset, + boolean allowToBeyondMaxPreferredOffset, + boolean isSoftWrap) { + if (isSoftWrap) { + return myDefaultStrategy.calculateWrapPosition( + document, project, startOffset, endOffset, maxPreferredOffset, allowToBeyondMaxPreferredOffset, isSoftWrap); + } + else { + return super.calculateWrapPosition( + document, project, startOffset, endOffset, maxPreferredOffset, allowToBeyondMaxPreferredOffset, isSoftWrap); + } } } diff --git a/xml/tests/src/com/intellij/psi/formatter/HtmlLineWrapPositionStrategyTest.kt b/xml/tests/src/com/intellij/psi/formatter/HtmlLineWrapPositionStrategyTest.kt new file mode 100644 index 000000000000..3427203ea618 --- /dev/null +++ b/xml/tests/src/com/intellij/psi/formatter/HtmlLineWrapPositionStrategyTest.kt @@ -0,0 +1,49 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.psi.formatter + +import com.intellij.openapi.editor.AbstractLineWrapPositionStrategyTest +import com.intellij.openapi.editor.LineWrapPositionStrategy +import org.junit.Before +import org.junit.Test + +class HtmlLineWrapPositionStrategyTest : AbstractLineWrapPositionStrategyTest() { + + private lateinit var myStrategy: LineWrapPositionStrategy + + @Before + override fun prepare() { + super.prepare() + myStrategy = MarkupLineWrapPositionStrategy() + } + + @Test + fun doNotWrapWithinClosingTagStart1() { + doTest(myStrategy, + ">") + } + + @Test + fun doNotWrapWithinClosingTagStart2() { + doTest(myStrategy, + "a>") + } + + @Test + fun doNotWrapWithinClosingTagStart3() { + doTest(myStrategy, + "</a>") + } + + @Test + fun doNotWrapWithinClosingTagStart4() { + doTest(myStrategy, + "") + } + + @Test + fun wrapAfterSlash() { + val document = + "MUIFAHGA2fUufYYM4ynBfdgdfgdsfffffffffffffff5Bc\">" + doTest(myStrategy, document) + } +} \ No newline at end of file