diff --git a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
index 7e11bf4e3554..0ca9958af275 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
@@ -56,9 +56,14 @@ public class CaretModelWindow implements CaretModel {
myDelegate.moveToLogicalPosition(hostPos);
}
- public void moveToOffset(final int offset) {
+ @Override
+ public void moveToOffset(int offset) {
+ moveToOffset(offset, false);
+ }
+
+ public void moveToOffset(final int offset, boolean locateBeforeSoftWrap) {
int hostOffset = myEditorWindow.getDocument().injectedToHost(offset);
- myDelegate.moveToOffset(hostOffset);
+ myDelegate.moveToOffset(hostOffset, locateBeforeSoftWrap);
}
public LogicalPosition getLogicalPosition() {
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CaretModel.java b/platform/platform-api/src/com/intellij/openapi/editor/CaretModel.java
index 0b56a2bad9ff..84c5ad3c2ca3 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/CaretModel.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/CaretModel.java
@@ -55,12 +55,23 @@ public interface CaretModel {
void moveToVisualPosition(VisualPosition pos);
/**
- * Moves the caret to the specified offset in the document.
+ * Short hand for calling {@link #moveToOffset(int, boolean)} with 'false' as a second argument.
*
- * @param offset the offset to move to.
+ * @param offset the offset to move to
*/
void moveToOffset(int offset);
+ /**
+ * Moves the caret to the specified offset in the document.
+ *
+ * @param offset the offset to move to.
+ * @param locateBeforeSoftWrap there is a possible case that there is a soft wrap at the given offset, hence, the same offset
+ * corresponds to two different visual positions - just before soft wrap and just after soft wrap.
+ * We may want to clearly indicate where to put the caret then. Given parameter allows to do that.
+ * Note: it's ignored if there is no soft wrap at the given offset
+ */
+ void moveToOffset(int offset, boolean locateBeforeSoftWrap);
+
/**
* Returns the logical position of the caret.
*
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
index 1371104f5af3..13279c0295c9 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
@@ -81,7 +81,7 @@ public class EditorModificationUtil {
public static int insertStringAtCaret(Editor editor, String s, boolean toProcessOverwriteMode, boolean toMoveCaret) {
final SelectionModel selectionModel = editor.getSelectionModel();
if (selectionModel.hasSelection()) {
- editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart());
+ editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart(), true);
}
// There is a possible case that particular soft wraps become hard wraps if the caret is located at soft wrap-introduced virtual
@@ -114,7 +114,7 @@ public class EditorModificationUtil {
int offset = oldOffset + s.length();
if (toMoveCaret){
- editor.getCaretModel().moveToOffset(offset);
+ editor.getCaretModel().moveToOffset(offset, true);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
selectionModel.removeSelection();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/BackspaceAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/BackspaceAction.java
index 24327465e86e..86b8b771ee11 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/BackspaceAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/BackspaceAction.java
@@ -81,10 +81,10 @@ public class BackspaceAction extends EditorAction {
}
else {
int offset = editor.getCaretModel().getOffset();
- editor.getCaretModel().moveToOffset(offset-1);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().removeSelection();
document.deleteString(offset-1, offset);
+ editor.getCaretModel().moveToOffset(offset - 1, true);
}
}
else if(lineNumber > 0) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteAction.java
index af8466bd9231..6bfb0a282bed 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteAction.java
@@ -97,6 +97,7 @@ public class DeleteAction extends EditorAction {
if(afterLineEnd < 0) {
int offset = editor.getCaretModel().getOffset();
document.deleteString(offset, offset + 1);
+ editor.getCaretModel().moveToOffset(offset);
return;
}
if(lineNumber + 1 >= document.getLineCount())
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
index 2dc7161ef06e..503ff6715dfd 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
@@ -35,6 +35,7 @@ import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.editor.ex.PrioritizedDocumentListener;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
+import com.intellij.openapi.editor.impl.softwrap.SoftWrapHelper;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -133,9 +134,13 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
}
public void moveToOffset(int offset) {
+ moveToOffset(offset, false);
+ }
+
+ public void moveToOffset(int offset, boolean locateBeforeSoftWrap) {
assertIsDispatchThread();
validateCallContext();
- moveToLogicalPosition(myEditor.offsetToLogicalPosition(offset));
+ moveToLogicalPosition(myEditor.offsetToLogicalPosition(offset), locateBeforeSoftWrap);
if (!myEditor.offsetToLogicalPosition(myOffset).equals(myEditor.offsetToLogicalPosition(offset))) {
LOG.error("caret moved to wrong offset. Requested:" + offset + " but actual:" + myOffset);
}
@@ -244,6 +249,10 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
}
public void moveToLogicalPosition(LogicalPosition pos) {
+ moveToLogicalPosition(pos, false);
+ }
+
+ private void moveToLogicalPosition(LogicalPosition pos, boolean locateBeforeSoftWrap) {
assertIsDispatchThread();
validateCallContext();
int column = pos.column;
@@ -325,6 +334,14 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
myEditor.updateCaretCursor();
requestRepaint(oldInfo);
+ if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(myEditor)) {
+ int lineToUse = myVisibleCaret.line - 1;
+ if (lineToUse >= 0) {
+ moveToVisualPosition(new VisualPosition(lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse)));
+ return;
+ }
+ }
+
if (!oldCaretPosition.toVisualPosition().equals(myLogicalCaret.toVisualPosition())) {
CaretEvent event = new CaretEvent(myEditor, oldCaretPosition, myLogicalCaret);
for (CaretListener listener : myCaretListeners) {
@@ -408,15 +425,19 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
DocumentEventImpl event = (DocumentEventImpl)e;
final Document document = myEditor.getDocument();
+ boolean performSoftWrapAdjustment = e.getNewLength() > 0 // We want to put caret just after the last added symbol
+ // There is a possible case that the user removes text just before the soft wrap. We want to keep caret
+ // on a visual line with soft wrap start then.
+ || myEditor.getSoftWrapModel().getSoftWrap(e.getOffset()) != null;
if (event.isWholeTextReplaced()) {
int newLength = document.getTextLength();
if (myOffset == newLength - e.getNewLength() + e.getOldLength() || newLength == 0) {
- moveToOffset(newLength);
+ moveToOffset(newLength, performSoftWrapAdjustment);
}
else {
final int line = event.translateLineViaDiff(myLogicalCaret.line);
- moveToLogicalPosition(new LogicalPosition(line, myLogicalCaret.column));
+ moveToLogicalPosition(new LogicalPosition(line, myLogicalCaret.column), performSoftWrapAdjustment);
}
}
else {
@@ -435,9 +456,8 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
newOffset = Math.min(newOffset, document.getTextLength());
- //TODO:ask max about this code
// if (newOffset != myOffset) {
- moveToOffset(newOffset);
+ moveToOffset(newOffset, performSoftWrapAdjustment);
//}
//else {
// moveToVisualPosition(oldPosition);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index 90778c6723a0..1e07bbfe6381 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -50,6 +50,7 @@ import com.intellij.openapi.editor.highlighter.HighlighterClient;
import com.intellij.openapi.editor.impl.event.MarkupModelEvent;
import com.intellij.openapi.editor.impl.event.MarkupModelListener;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapDrawingType;
+import com.intellij.openapi.editor.impl.softwrap.SoftWrapHelper;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProgressManager;
@@ -294,6 +295,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myDocument.addDocumentListener(myCaretModel);
myDocument.addDocumentListener(mySelectionModel);
myDocument.addDocumentListener(myEditorDocumentAdapter);
+ myDocument.addDocumentListener(mySoftWrapModel);
myIndentsModel = new IndentsModelImpl(this);
myCaretModel.addCaretListener(new CaretListener() {
@@ -522,6 +524,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myDocument.removeDocumentListener(myFoldingModel);
myDocument.removeDocumentListener(myCaretModel);
myDocument.removeDocumentListener(mySelectionModel);
+ myDocument.removeDocumentListener(mySoftWrapModel);
MarkupModelEx markupModel = (MarkupModelEx)myDocument.getMarkupModel(myProject, false);
if (markupModel instanceof MarkupModelImpl) {
@@ -1126,7 +1129,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
// We need to consider 'before soft wrap drawing'.
TextChange softWrap = getSoftWrapModel().getSoftWrap(offset);
- if (softWrap != null) {
+ if (softWrap != null && offset > startOffset) {
column++;
x += getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED);
if (column >= length) {
@@ -1585,6 +1588,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@SuppressWarnings({"StatementWithEmptyBody"})
private void paintBackgrounds(Graphics g, Rectangle clip) {
+ boolean locateBeforeSoftWrap = !SoftWrapHelper.isCaretAfterSoftWrap(this);
Color defaultBackground = getBackgroundColor();
g.setColor(defaultBackground);
g.fillRect(clip.x, clip.y, clip.width, clip.height);
@@ -1702,6 +1706,22 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (lIterator.getLineNumber() >= lastLineIndex && position.y <= clip.y + clip.height) {
paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight, defaultBackground);
}
+
+ // Perform additional activity if soft wrap is added or removed during repainting.
+ if (mySoftWrapsChanged) {
+ mySoftWrapsChanged = false;
+ validateSize();
+
+ // Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction.
+ repaintToScreenBottom(xyToLogicalPosition(position).line);
+
+ // Repaint gutter at all space that is located after active clip in order to ensure that line numbers are correctly redrawn
+ // in accordance with the newly introduced soft wrap(s).
+ myGutterComponent.repaint(0, clip.y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - clip.y);
+
+ // Ask caret model to update visual caret position.
+ getCaretModel().moveToOffset(getCaretModel().getOffset(), locateBeforeSoftWrap);
+ }
}
private void paintRectangularSelection(Graphics g) {
@@ -1756,7 +1776,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (startToUse < softWrapStart) {
position.x = drawBackground(g, backColor, text.subSequence(startToUse, softWrapStart), position, fontType, defaultBackground, clip);
}
- drawSoftWrap(g, backColor, softWrap, position, fontType, defaultBackground, clip);
+ drawSoftWrap(g, softWrap, position, fontType, defaultBackground, clip);
startToUse = softWrapStart;
}
@@ -1766,37 +1786,61 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return position.x;
}
- private void drawSoftWrap(Graphics g, Color backColor, TextChange softWrap, Point position,
- int fontType, Color defaultBackground, Rectangle clip)
- {
- position.x = drawBackground(
- g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED), position,
- defaultBackground, clip
- );
+ private void drawSoftWrap(Graphics g, TextChange softWrap, Point position, int fontType, Color defaultBackground, Rectangle clip) {
+ // The main idea is to to do the following:
+ // *) update given drawing position coordinates in accordance with the current soft wrap;
+ // *) draw 'active line' background at soft wrap-introduced virtual space if necessary;
CharSequence softWrapText = softWrap.getText();
- int start = 0;
- for (
- int end = CharArrayUtil.shiftForwardUntil(softWrapText, start, "\n");
- start < softWrapText.length() && end < softWrapText.length();
- end = CharArrayUtil.shiftForwardUntil(softWrapText, start, "\n"))
- {
- drawBackground(g, backColor, softWrapText.subSequence(start, end), position, fontType, defaultBackground, clip);
- start = end + 1;
- position.x = 0;
- position.y += getLineHeight();
+ int activeRowY = getCaretModel().getVisualPosition().line * getLineHeight();
+ if (position.y == activeRowY) {
+ // Draw 'active line' background after soft wrap.
+ Color caretRowColor = getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR);
+ drawBackground(g, caretRowColor, clip.x + clip.width - position.x, position, defaultBackground, clip);
}
- if (start < softWrapText.length()) {
- position.x = drawBackground(
- g, backColor, softWrapText.subSequence(start, softWrapText.length()), position, fontType, defaultBackground, clip
- );
+ int i = CharArrayUtil.lastIndexOf(softWrapText, "\n", softWrapText.length()) + 1;
+ position.x = getTextSegmentWidth(softWrapText.subSequence(i, softWrapText.length()), 0, fontType, clip);
+ position.x += getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
+ position.y += getLineHeight();
+
+ if (position.y == activeRowY) {
+ // Draw 'active line' background for the soft wrap-introduced virtual space.
+ Color caretRowColor = getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR);
+ drawBackground(g, caretRowColor, position.x, new Point(0, activeRowY), defaultBackground, clip);
}
- position.x = drawBackground(
- g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP), position,
- defaultBackground, clip
- );
+ // The code below draws background for soft wrap-introduced virtual space. It's is considered that we don't want
+ // to do that for now. Uncomment if that decision is changed.
+
+ //position.x = drawBackground(
+ // g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED), position,
+ // defaultBackground, clip
+ //);
+ //
+ //CharSequence softWrapText = softWrap.getText();
+ //int start = 0;
+ //for (
+ // int end = CharArrayUtil.shiftForwardUntil(softWrapText, start, "\n");
+ // start < softWrapText.length() && end < softWrapText.length();
+ // end = CharArrayUtil.shiftForwardUntil(softWrapText, start, "\n"))
+ //{
+ // drawBackground(g, backColor, softWrapText.subSequence(start, end), position, fontType, defaultBackground, clip);
+ // start = end + 1;
+ // position.x = 0;
+ // position.y += getLineHeight();
+ //}
+ //
+ //if (start < softWrapText.length()) {
+ // position.x = drawBackground(
+ // g, backColor, softWrapText.subSequence(start, softWrapText.length()), position, fontType, defaultBackground, clip
+ // );
+ //}
+ //
+ //position.x = drawBackground(
+ // g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP), position,
+ // defaultBackground, clip
+ //);
}
private int drawBackground(Graphics g, Color backColor, CharSequence text, Point position, int fontType, Color defaultBackground,
@@ -1861,7 +1905,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// We use AtomicReference here just as a holder for LogicalPosition
// The main idea is that there is a possible case that we need to perform painting starting from soft-wrapped logical line.
- // We may want to skip necessary of visual lines then. Hence, we remember logical position that corresponds to the starting
+ // We may want to skip necessary number of visual lines then. Hence, we remember logical position that corresponds to the starting
// visual line in order to use it for further processing. As soon as necessary number of visual lines is skipped, logical
// position is expected to be set to null as an indication that no soft wrap-introduced visual lines should be skipped on
// current painting iteration.
@@ -1975,22 +2019,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
flushCachedChars(g);
-
- // Perform additional activity if soft wrap is added or removed during repainting.
- if (mySoftWrapsChanged) {
- mySoftWrapsChanged = false;
- validateSize();
-
- // Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction.
- repaintToScreenBottom(xyToLogicalPosition(position).line);
-
- // Repaint gutter at all space that is located after active clip in order to ensure that line numbers are correctly redrawn
- // in accordance with the newly introduced soft wrap(s).
- myGutterComponent.repaint(0, clip.y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - clip.y);
-
- // Ask caret model to update visual caret position.
- getCaretModel().moveToOffset(getCaretModel().getOffset());
- }
}
private boolean paintSelection() {
@@ -3536,7 +3564,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
super(orientation);
}
- void setPersistendUI(ScrollBarUI ui) {
+ void setPersistentUI(ScrollBarUI ui) {
myPersistentUI = ui;
setUI(ui);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
index 405de6210f6f..0bacaf8c4731 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
@@ -463,10 +463,10 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
public void setErrorStripeVisible(boolean val) {
if (val) {
- myEditor.getVerticalScrollBar().setPersistendUI(new MyErrorPanel());
+ myEditor.getVerticalScrollBar().setPersistentUI(new MyErrorPanel());
}
else {
- myEditor.getVerticalScrollBar().setPersistendUI(ButtonlessScrollBarUI.createNormal());
+ myEditor.getVerticalScrollBar().setPersistentUI(ButtonlessScrollBarUI.createNormal());
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
index c1283a0b4a02..1c8967076f5f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
@@ -16,6 +16,8 @@
package com.intellij.openapi.editor.impl;
import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.SoftWrapChangeListener;
import com.intellij.openapi.editor.ex.SoftWrapModelEx;
@@ -27,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -41,7 +44,9 @@ import java.util.List;
* @author Denis Zhdanov
* @since Jun 8, 2010 12:47:32 PM
*/
-public class SoftWrapModelImpl implements SoftWrapModelEx {
+public class SoftWrapModelImpl implements SoftWrapModelEx, DocumentListener {
+
+ private final List myDocumentListeners = new ArrayList();
private final SoftWrapDataMapper myDataMapper;
private final SoftWrapsStorage myStorage;
@@ -69,6 +74,14 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
);
}
+ public SoftWrapModelImpl(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter,
+ @NotNull DefaultSoftWrapApplianceManager applianceManager, @NotNull SoftWrapDataMapper dataMapper,
+ @NotNull SoftWrapDocumentChangeManager documentChangeManager)
+ {
+ this(editor, storage, painter, (SoftWrapApplianceManager)applianceManager, dataMapper, documentChangeManager);
+ myDocumentListeners.add(applianceManager.getDocumentListener());
+ }
+
public SoftWrapModelImpl(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter,
@NotNull SoftWrapApplianceManager applianceManager, @NotNull SoftWrapDataMapper dataMapper,
@NotNull SoftWrapDocumentChangeManager documentChangeManager)
@@ -79,6 +92,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
myApplianceManager = applianceManager;
myDataMapper = dataMapper;
myDocumentChangeManager = documentChangeManager;
+
+ myDocumentListeners.add(myDocumentChangeManager);
}
public boolean isSoftWrappingEnabled() {
@@ -349,26 +364,35 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
return result;
}
+ @Override
public void beforeDocumentChangeAtCaret() {
CaretModel caretModel = myEditor.getCaretModel();
VisualPosition visualCaretPosition = caretModel.getVisualPosition();
if (!isInsideSoftWrap(visualCaretPosition)) {
return;
}
- int offset = caretModel.getOffset();
- TextChangeImpl softWrap = myStorage.getSoftWrap(offset);
- if (softWrap == null) {
- return;
+ if (myDocumentChangeManager.makeHardWrap(caretModel.getOffset())) {
+ // Restore caret position.
+ caretModel.moveToVisualPosition(visualCaretPosition);
}
-
- myDocumentChangeManager.makeHardWrap(softWrap);
-
- // Restore caret position.
- caretModel.moveToVisualPosition(visualCaretPosition);
}
@Override
public boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener) {
return myStorage.addSoftWrapChangeListener(listener);
}
+
+ @Override
+ public void beforeDocumentChange(DocumentEvent event) {
+ for (DocumentListener listener : myDocumentListeners) {
+ listener.beforeDocumentChange(event);
+ }
+ }
+
+ @Override
+ public void documentChanged(DocumentEvent event) {
+ for (DocumentListener listener : myDocumentListeners) {
+ listener.documentChanged(event);
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/CompositeSoftWrapPainter.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/CompositeSoftWrapPainter.java
index b5eef3985a10..57d9ba6c69bc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/CompositeSoftWrapPainter.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/CompositeSoftWrapPainter.java
@@ -45,10 +45,10 @@ import static java.util.Arrays.asList;
public class CompositeSoftWrapPainter implements SoftWrapPainter {
private static final List