diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index 86fae1651a18..1fb72208c642 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -681,6 +681,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { // deal with width final int width = Math.max(editorSize.width, historySize.width); newEditorSize.width = width + editor.getScrollPane().getHorizontalScrollBar().getHeight(); + editor.getSoftWrapModel().forceAdditionalColumnsUsage(); editor.getSettings().setAdditionalColumnsCount(2 + (width - editorSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, editor)); history.getSettings().setAdditionalColumnsCount(2 + (width - historySize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, history)); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java index fcbfc8262cab..4e8d60bc753a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java @@ -118,4 +118,48 @@ public interface SoftWrapModelEx extends SoftWrapModel { /** Asks the model to completely recalculate soft wraps. */ void recalculate(); + + /** + * IJ editor defines a notion of {@link EditorSettings#getAdditionalColumnsCount() additional columns}. They define additional + * amount of space to be used during editor component's width calculation (IJ editor perform 'preventive UI component expansion' + * when user types near the right edge). + *

+ * The main idea of soft wraps is to avoid horizontal scrolling, however, there is a possible case that particular line + * of text can't be soft-wrapped, i.e. we need to show horizontal scroll bar. So, we have the following use-cases: + *

+   * 
    + *
  1. + * Long line is soft-wrapped. + *

    + * Example: + *

    + * this a long lin[caret] |<-- viewport's edge + *

    + * As soon as 'e' is typed, soft wrapping is performed and 'line' word is displayed at the next visual line, we need + * not to consider {@link EditorSettings#getAdditionalColumnsCount() additional columns} during width recalculation; + *

  2. + *
  3. + * Long line can't be soft-wrapped + *

    + * Example: + * thisisaratherlonglin[caret]|<-- viewport's edge + *

    + * When 'e' is typed we need to increase component's width and use + * {@link EditorSettings#getAdditionalColumnsCount() additional columns} for its calculation; + *

  4. + *
+ *
+ * This method allows to answer if {@link EditorSettings#getAdditionalColumnsCount() additional columns} should be used + * during editor component's width calculation. + * + * @return true if {@link EditorSettings#getAdditionalColumnsCount() additional columns} should be used + * during editor component's width recalculation; + * false otherwise + */ + boolean isRespectAdditionalColumns(); + + /** + * Allows to instruct current model to always return 'true' from {@link #isRespectAdditionalColumns()}. + */ + void forceAdditionalColumnsUsage(); } 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 6ecddea85a1e..98f8edf25419 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 @@ -434,10 +434,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myScrollingModel = new ScrollingModelImpl(this); - if (mySettings.isUseSoftWraps()) { - mySettings.setAdditionalColumnsCount(0); - } - myGutterComponent.updateSize(); Dimension preferredSize = getPreferredSize(); myEditorComponent.setSize(preferredSize); @@ -3108,7 +3104,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } final Dimension draft = getSizeWithoutCaret(); - final int additionalSpace = mySettings.getAdditionalColumnsCount() * EditorUtil.getSpaceWidth(Font.PLAIN, this); + final int additionalSpace = mySoftWrapModel.isRespectAdditionalColumns() + ? mySettings.getAdditionalColumnsCount() * EditorUtil.getSpaceWidth(Font.PLAIN, this) + : 0; if (!myDocument.isInBulkUpdate() && getCaretModel().isUpToDate()) { int caretX = visualPositionToXY(getCaretModel().getVisualPosition()).x; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ScrollingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ScrollingModelImpl.java index a5bd5249b417..5fffa314c808 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ScrollingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ScrollingModelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -173,7 +173,7 @@ public class ScrollingModelImpl implements ScrollingModelEx { hOffset = targetLocation.x - 4 * spaceWidth; hOffset = hOffset > 0 ? hOffset : 0; } - else if (targetLocation.x > viewRect.x + viewRect.width) { + else if (targetLocation.x >= viewRect.x + viewRect.width) { hOffset = targetLocation.x - viewRect.width + xInsets; } 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 74c0dc309a23..e7916cc79493 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 @@ -98,19 +98,6 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi private boolean myUseSoftWraps; private int myTabWidth = -1; - /** - * Standard IJ editor starts showing horizontal scroll bar event when text line ends couple of symbols before the right visual - * area edge (exact value of columns to use for such preliminary scrolling is identified by - * {@link EditorSettings#getAdditionalColumnsCount() additionalColumnsCount} value). - *

- * However, we want to avoid using horizontal scrolling within soft wraps whenever possible. Hence, we set that additional - * columns property to zero when soft wraps are used and restore it if soft wraps are turned off. - *

- * Current field holds initial 'additional columns count' property value that is to be restored if - * soft wraps are turned off. - */ - private int myAdditionalColumnsCount; - /** * Soft wraps need to be kept up-to-date on all editor modification (changing text, adding/removing/expanding/collapsing fold * regions etc). Hence, we need to react to all types of target changes. However, soft wraps processing uses various information @@ -132,6 +119,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi * Current field serves as a flag for that 'dirty document, need complete soft wraps cache recalculation' state. */ private boolean myDirty; + + private boolean myForceAdditionalColumns; public SoftWrapModelImpl(@NotNull EditorEx editor) { this(editor, new SoftWrapsStorage(), new CompositeSoftWrapPainter(editor)); @@ -183,7 +172,6 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } }); EditorSettings settings = myEditor.getSettings(); - myAdditionalColumnsCount = settings.getAdditionalColumnsCount(); myUseSoftWraps = settings.isUseSoftWraps(); editor.addPropertyChangeListener(this); @@ -200,18 +188,11 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi int tabWidthBefore = myTabWidth; myTabWidth = getCurrentTabWidth(); - if ((myUseSoftWraps && (!softWrapsUsedBefore || settings.getAdditionalColumnsCount() > 0)) - || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore)) - { + if ((myUseSoftWraps ^ softWrapsUsedBefore) || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore)) { myApplianceManager.reset(); myDeferredFoldRegions.clear(); - myAdditionalColumnsCount = settings.getAdditionalColumnsCount(); - settings.setAdditionalColumnsCount(0); + myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); } - else if (!myUseSoftWraps && softWrapsUsedBefore) { - settings.setAdditionalColumnsCount(myAdditionalColumnsCount); - } - myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); } /** @@ -227,7 +208,17 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi final CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(file.getFileType()); return indentOptions.TAB_SIZE; } - + + @Override + public boolean isRespectAdditionalColumns() { + return myForceAdditionalColumns || myApplianceManager.hasLinesWithFailedWrap(); + } + + @Override + public void forceAdditionalColumnsUsage() { + myForceAdditionalColumns = true; + } + @Override public boolean isSoftWrappingEnabled() { if (!myUseSoftWraps || myEditor.isOneLineMode()) { 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 a7c9172c552d..b9d800cbafb8 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 @@ -97,6 +97,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume private int myCustomIndentValueUsedLastTime; private int myVisibleAreaWidth; private boolean myInProgress; + private boolean myHasLinesWithFailedWrap; public SoftWrapApplianceManager(@NotNull SoftWrapsStorage storage, @NotNull EditorEx editor, @@ -111,6 +112,15 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume myWidthProvider = new DefaultVisibleAreaWidthProvider(editor); } + /** + * @return true if soft wraps processing detected line(s) that exceeds viewport's size but can't be soft-wrapped; + * i.e. part of it lays outside of the screen; + * false otherwise + */ + public boolean hasLinesWithFailedWrap() { + return myHasLinesWithFailedWrap; + } + public void registerSoftWrapIfNecessary() { recalculateIfNecessary(); } @@ -163,6 +173,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume myActiveEvents.addAll(events); myEventsStorage.release(); myInProgress = true; + myHasLinesWithFailedWrap = false; try { for (IncrementalCacheUpdateEvent event : events) { recalculateSoftWraps(event); @@ -457,6 +468,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume ); if (softWrap == null) { myContext.tryToShiftToNextLine(); + myHasLinesWithFailedWrap = true; return; }