diff --git a/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareDefaultLineWrapPositionStrategy.java b/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareDefaultLineWrapPositionStrategy.java
index f10ddc670f76..47462ad878c7 100644
--- a/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareDefaultLineWrapPositionStrategy.java
+++ b/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareDefaultLineWrapPositionStrategy.java
@@ -23,15 +23,15 @@ import org.jetbrains.annotations.Nullable;
/**
* {@link LineWrapPositionStrategy} implementation that uses
* {@link LanguageLineWrapPositionStrategy#getDefaultImplementation() default line wrap strategy} but restricts its scope
- * by {@link #PsiAwareDefaultLineWrapPositionStrategy(IElementType...) target tokens/elements}.
+ * by {@link #PsiAwareDefaultLineWrapPositionStrategy(boolean, IElementType...) target tokens/elements}.
*
* @author Denis Zhdanov
* @since 5/12/11 12:50 PM
*/
public class PsiAwareDefaultLineWrapPositionStrategy extends PsiAwareLineWrapPositionStrategy {
- public PsiAwareDefaultLineWrapPositionStrategy(@NotNull IElementType ... enabledTypes) {
- super(enabledTypes);
+ public PsiAwareDefaultLineWrapPositionStrategy(boolean nonVirtualOnly, @NotNull IElementType ... enabledTypes) {
+ super(nonVirtualOnly, enabledTypes);
}
@Override
@@ -40,10 +40,11 @@ public class PsiAwareDefaultLineWrapPositionStrategy extends PsiAwareLineWrapPos
int startOffset,
int endOffset,
int maxPreferredOffset,
- boolean allowToBeyondMaxPreferredOffset)
+ boolean allowToBeyondMaxPreferredOffset,
+ boolean virtual)
{
LineWrapPositionStrategy implementation = LanguageLineWrapPositionStrategy.INSTANCE.getDefaultImplementation();
return implementation.calculateWrapPosition(document, project, startOffset, endOffset, maxPreferredOffset,
- allowToBeyondMaxPreferredOffset);
+ allowToBeyondMaxPreferredOffset, virtual);
}
}
diff --git a/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareLineWrapPositionStrategy.java b/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareLineWrapPositionStrategy.java
index 3daa6e646cd8..a59da3c70e69 100644
--- a/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareLineWrapPositionStrategy.java
+++ b/platform/lang-api/src/com/intellij/openapi/editor/PsiAwareLineWrapPositionStrategy.java
@@ -39,14 +39,17 @@ public abstract class PsiAwareLineWrapPositionStrategy implements LineWrapPositi
private static final Logger LOG = Logger.getInstance("#" + PsiAwareLineWrapPositionStrategy.class.getName());
private final TokenSet myEnabledTypes;
+ private final boolean myNonVirtualOnly;
/**
* Creates new PsiAwareLineWrapPositionStrategy object.
*
+ * @param nonVirtualOnly defines if current PSI-aware logic should be exploited only for 'real wrap' position requests
* @param enabledTypes target element/token types where line wrapping is allowed
*/
- public PsiAwareLineWrapPositionStrategy(@NotNull IElementType ... enabledTypes) {
+ public PsiAwareLineWrapPositionStrategy(boolean nonVirtualOnly, @NotNull IElementType ... enabledTypes) {
myEnabledTypes = TokenSet.create(enabledTypes);
+ myNonVirtualOnly = nonVirtualOnly;
if (enabledTypes.length <= 0) {
LOG.warn(String.format("%s instance is created with empty token/element types. That will lead to inability to perform line wrap",
getClass().getName()));
@@ -59,11 +62,19 @@ public abstract class PsiAwareLineWrapPositionStrategy implements LineWrapPositi
int startOffset,
int endOffset,
int maxPreferredOffset,
- boolean allowToBeyondMaxPreferredOffset) {
+ boolean allowToBeyondMaxPreferredOffset,
+ boolean virtual) {
+ if (virtual && myNonVirtualOnly) {
+ LineWrapPositionStrategy implementation = LanguageLineWrapPositionStrategy.INSTANCE.getDefaultImplementation();
+ return implementation.calculateWrapPosition(
+ document, project, startOffset, endOffset, maxPreferredOffset, allowToBeyondMaxPreferredOffset, virtual
+ );
+ }
+
if (project == null) {
return -1;
}
-
+
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
if (documentManager == null) {
return -1;
@@ -84,7 +95,7 @@ public abstract class PsiAwareLineWrapPositionStrategy implements LineWrapPositi
TextRange textRange = element.getTextRange();
int start = Math.max(textRange.getStartOffset(), startOffset);
int end = Math.min(textRange.getEndOffset(), endOffset);
- int result = doCalculateWrapPosition(document, project, start, end, end, false);
+ int result = doCalculateWrapPosition(document, project, start, end, end, false, virtual);
if (result >= 0) {
return result;
}
@@ -96,15 +107,15 @@ public abstract class PsiAwareLineWrapPositionStrategy implements LineWrapPositi
if (start > startOffset) {
return start;
- }
+ }
}
}
return -1;
}
/**
- * Serves for the same purposes as {@link #calculateWrapPosition(Document, Project, int, int, int, boolean)} but ensures that given
- * offsets target {@link #PsiAwareLineWrapPositionStrategy(IElementType...) enabled token/element types}.
+ * Serves for the same purposes as {@link #calculateWrapPosition(Document, Project, int, int, int, boolean, boolean)} but ensures
+ * that given offsets target {@link #PsiAwareLineWrapPositionStrategy(boolean, IElementType...) enabled token/element types}.
*
* @param document target document which text is being processed
* @param project target project
@@ -117,12 +128,13 @@ public abstract class PsiAwareLineWrapPositionStrategy implements LineWrapPositi
* @param allowToBeyondMaxPreferredOffset indicates if it's allowed to return value from
* (maxPreferredOffset; endOffset] interval in case of inability to
* find appropriate offset from (startOffset; maxPreferredOffset] interval
+ * @param virtual identifies if current request is for virtual wrap (soft wrap) position
* @return offset from (startOffset; endOffset] interval where
* target line should be wrapped OR -1 if no wrapping should be performed
*/
protected abstract int doCalculateWrapPosition(
@NotNull Document document, @Nullable Project project, int startOffset, int endOffset, int maxPreferredOffset,
- boolean allowToBeyondMaxPreferredOffset
+ boolean allowToBeyondMaxPreferredOffset, boolean virtual
);
/**
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java
index 656992640479..6fe03bbcde46 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java
@@ -150,7 +150,7 @@ public class AutoHardWrapHandler {
new VisualPosition(caretModel.getVisualPosition().line, margin - FormatConstants.RESERVED_LINE_WRAP_WIDTH_IN_COLUMNS)
));
- int wrapOffset = strategy.calculateWrapPosition(document, project, startOffset, endOffset, maxPreferredOffset, true);
+ int wrapOffset = strategy.calculateWrapPosition(document, project, startOffset, endOffset, maxPreferredOffset, true, false);
if (wrapOffset < 0) {
return;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
index 4841db5a70c1..8b99608be6de 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
@@ -381,7 +381,7 @@ public class CodeFormatterFacade {
// We know that current line exceeds right margin if control flow reaches this place, so, wrap it.
int wrapOffset = strategy.calculateWrapPosition(
document, editor.getProject(), Math.max(startLineOffset, startOffsetToUse), Math.min(endLineOffset, endOffsetToUse),
- preferredWrapPosition, false
+ preferredWrapPosition, false, false
);
if (wrapOffset < 0) {
continue;
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java
index 21757e3af59f..d39cad7af87c 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorSettings.java
@@ -104,7 +104,9 @@ public interface EditorSettings {
void setUseSoftWraps(boolean use);
boolean isAllSoftWrapsShown();
boolean isUseCustomSoftWrapIndent();
+ void setUseCustomSoftWrapIndent(boolean useCustomSoftWrapIndent);
int getCustomSoftWrapIndent();
+ void setCustomSoftWrapIndent(int indent);
boolean isAllowSingleLogicalLineFolding();
void setAllowSingleLogicalLineFolding(boolean allow);
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/GenericLineWrapPositionStrategy.java b/platform/platform-api/src/com/intellij/openapi/editor/GenericLineWrapPositionStrategy.java
index 93289b0caddd..a3d5988effc3 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/GenericLineWrapPositionStrategy.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/GenericLineWrapPositionStrategy.java
@@ -48,7 +48,8 @@ public class GenericLineWrapPositionStrategy implements LineWrapPositionStrategy
int startOffset,
int endOffset,
int maxPreferredOffset,
- boolean allowToBeyondMaxPreferredOffset)
+ boolean allowToBeyondMaxPreferredOffset,
+ boolean virtual)
{
if (endOffset <= startOffset) {
return endOffset;
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LineWrapPositionStrategy.java b/platform/platform-api/src/com/intellij/openapi/editor/LineWrapPositionStrategy.java
index 958db895b793..2e13a3fb8f09 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LineWrapPositionStrategy.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LineWrapPositionStrategy.java
@@ -45,11 +45,12 @@ public interface LineWrapPositionStrategy {
* @param allowToBeyondMaxPreferredOffset indicates if it's allowed to return value from
* (maxPreferredOffset; endOffset] interval in case of inability to
* find appropriate offset from (startOffset; maxPreferredOffset] interval
+ * @param virtual identifies if current request is for virtual wrap (soft wrap) position
* @return offset from (startOffset; endOffset] interval where
* target line should be wrapped OR -1 if no wrapping should be performed
*/
int calculateWrapPosition(
@NotNull Document document, @Nullable Project project, int startOffset, int endOffset, int maxPreferredOffset,
- boolean allowToBeyondMaxPreferredOffset
+ boolean allowToBeyondMaxPreferredOffset, boolean virtual
);
}
diff --git a/platform/platform-api/testSrc/com/intellij/openapi/editor/DefaultLineWrapPositionStrategyTest.java b/platform/platform-api/testSrc/com/intellij/openapi/editor/DefaultLineWrapPositionStrategyTest.java
index 8d5ba9fa4e19..a4b8ddf29bab 100644
--- a/platform/platform-api/testSrc/com/intellij/openapi/editor/DefaultLineWrapPositionStrategyTest.java
+++ b/platform/platform-api/testSrc/com/intellij/openapi/editor/DefaultLineWrapPositionStrategyTest.java
@@ -85,7 +85,8 @@ public class DefaultLineWrapPositionStrategyTest {
final Context context = new Context(document);
context.init();
int actual = myStrategy.calculateWrapPosition(
- createMockDocument(context.document), myProject, 0, context.document.length(), context.edgeIndex, allowToBeyondMaxPreferredOffset
+ createMockDocument(context.document), myProject, 0, context.document.length(), context.edgeIndex,
+ allowToBeyondMaxPreferredOffset, true
);
assertSame(context.wrapIndex, actual);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java
index e00b6928ebaf..ae5672dd1f95 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java
@@ -77,6 +77,8 @@ public class SettingsImpl implements EditorSettings {
private Boolean myIsRefrainFromScrolling = null;
private Boolean myUseSoftWraps = null;
private Boolean myIsAllSoftWrapsShown = null;
+ private Boolean myUseCustomSoftWrapIndent = null;
+ private Integer myCustomSoftWrapIndent = null;
public boolean isRightMarginShown() {
return myIsRightMarginShown != null
@@ -206,8 +208,6 @@ public class SettingsImpl implements EditorSettings {
public void reinitSettings() {
myCachedTabSize = null;
- //TODO den check
- //myUseSoftWraps = null;
}
public int getTabSize(Project project) {
@@ -419,12 +419,23 @@ public class SettingsImpl implements EditorSettings {
@Override
public boolean isUseCustomSoftWrapIndent() {
- return EditorSettingsExternalizable.getInstance().isUseCustomSoftWrapIndent();
+ return myUseCustomSoftWrapIndent == null ? EditorSettingsExternalizable.getInstance().isUseCustomSoftWrapIndent()
+ : myUseCustomSoftWrapIndent;
+ }
+
+ @Override
+ public void setUseCustomSoftWrapIndent(boolean useCustomSoftWrapIndent) {
+ myUseCustomSoftWrapIndent = useCustomSoftWrapIndent;
}
@Override
public int getCustomSoftWrapIndent() {
- return EditorSettingsExternalizable.getInstance().getCustomSoftWrapIndent();
+ return myCustomSoftWrapIndent == null ? EditorSettingsExternalizable.getInstance().getCustomSoftWrapIndent() : myCustomSoftWrapIndent;
+ }
+
+ @Override
+ public void setCustomSoftWrapIndent(int indent) {
+ myCustomSoftWrapIndent = indent;
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
index 1a27b73d43de..083c0f47f817 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
@@ -517,10 +517,14 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
myLineWrapPositionStrategy = LanguageLineWrapPositionStrategy.INSTANCE.forEditor(myEditor);
}
- softWrapOffset = myLineWrapPositionStrategy.calculateWrapPosition(document, myEditor.getProject(), minOffset, maxOffset, preferredOffset, true);
+ softWrapOffset = myLineWrapPositionStrategy.calculateWrapPosition(
+ document, myEditor.getProject(), minOffset, maxOffset, preferredOffset, true, true
+ );
}
- if (softWrapOffset >= lineData.endLineOffset || softWrapOffset < 0) {
+ if (softWrapOffset >= lineData.endLineOffset || softWrapOffset < 0
+ || (myCustomIndentUsedLastTime && softWrapOffset == lineData.nonWhiteSpaceSymbolOffset))
+ {
return null;
}
@@ -787,8 +791,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
public int indentInColumns;
public int indentInPixels;
public int endLineOffset;
-
- private int myNonWhiteSpaceSymbolOffset;
+ public int nonWhiteSpaceSymbolOffset;
public void update(int logicalLine, int spaceWidth, Editor editor) {
Document document = myEditor.getDocument();
@@ -803,7 +806,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
CharSequence text = document.getCharsSequence();
indentInColumns = 0;
indentInPixels = 0;
- myNonWhiteSpaceSymbolOffset = -1;
+ nonWhiteSpaceSymbolOffset = -1;
for (int i = startLineOffset; i < endLineOffset; i++) {
char c = text.charAt(i);
@@ -814,7 +817,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
indentInColumns += calculateWidthInColumns(c, x - indentInPixels, spaceWidth);
indentInPixels = x;
break;
- default: myNonWhiteSpaceSymbolOffset = i; return;
+ default: nonWhiteSpaceSymbolOffset = i; return;
}
}
}
@@ -828,7 +831,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
* @param softWrapOffset offset of the soft wrap that occurred on document line which data is stored at the current object
*/
public void update(int softWrapOffset) {
- if (myNonWhiteSpaceSymbolOffset >= 0 && softWrapOffset > myNonWhiteSpaceSymbolOffset) {
+ if (nonWhiteSpaceSymbolOffset >= 0 && softWrapOffset > nonWhiteSpaceSymbolOffset) {
return;
}
indentInColumns = 0;
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
index ff8f09b3ee29..26ab633d80ca 100644
--- a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
+++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
@@ -17,6 +17,7 @@ package com.intellij.openapi.editor.impl.softwrap.mapping;
import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.SoftWrapModelEx;
import com.intellij.openapi.editor.impl.AbstractEditorProcessingOnDocumentModificationTest;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
@@ -793,6 +794,21 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP
assertEquals(new VisualPosition(1, 8), getEditor().offsetToVisualPosition(getEditor().getDocument().getTextLength() - 1));
}
+ public void testNoWrapAtFirstNonWsSymbolWithCustomIndent() throws IOException {
+ String text =
+ " 1111111111111111111111111111111";
+ init(70, text);
+ getEditor().getSettings().setCustomSoftWrapIndent(0);
+ getEditor().getSettings().setUseCustomSoftWrapIndent(true);
+ int textLength = getEditor().getDocument().getTextLength();
+ //Trigger soft wraps recalculation.
+ assertEquals(new LogicalPosition(0, textLength), myEditor.offsetToLogicalPosition(textLength));
+
+ // Don't expect soft wraps to be registered as there is no point in wrapping at the first non-white space symbol position
+ // in all cases when soft wrap is located at the left screen edge.
+ assertEmpty(getSoftWrapModel().getRegisteredSoftWraps());
+ }
+
public void testXmlWithLongCdata() throws IOException {
String text =
"\n" +
diff --git a/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java b/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java
index 1f3c21bc9960..7fb5d9a9f821 100644
--- a/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java
+++ b/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java
@@ -30,6 +30,6 @@ import com.intellij.psi.xml.XmlTokenType;
public class MarkupLineWrapPositionStrategy extends PsiAwareDefaultLineWrapPositionStrategy {
public MarkupLineWrapPositionStrategy() {
- super(XmlElementType.XML_TEXT, TokenType.WHITE_SPACE);
+ super(true, XmlElementType.XML_TEXT, TokenType.WHITE_SPACE);
}
}