@NotNull @Override public List<? extends SoftWrap> getSoftWrapsForRange(int start, int end) { if (!isSoftWrappingEnabled() || end < start) { return Collections.emptyList(); } List<? extends SoftWrap> softWraps = myStorage.getSoftWraps(); int startIndex = myStorage.getSoftWrapIndex(start); if (startIndex < 0) { startIndex = -startIndex - 1; if (startIndex >= softWraps.size() || softWraps.get(startIndex).getStart() > end) { return Collections.emptyList(); } } int endIndex = myStorage.getSoftWrapIndex(end); if (endIndex >= 0) { return softWraps.subList(startIndex, endIndex + 1); } else { endIndex = -endIndex - 1; return softWraps.subList(startIndex, endIndex); } }
/** * We know that there are problems with incremental soft wraps cache update at the moment. Hence, * we may implement full cache reconstruction when the problem is encountered in order to avoid * customer annoyance. * * <p>However, the problems still should be fixed, hence, we report them only if dedicated flag is * set. * * <p>Current method encapsulates the logic mentioned above. * * @param task command object that which execution may trigger incremental update of update soft * wraps cache */ @SuppressWarnings({"UseOfArchaicSystemPropertyAccessors"}) private void executeSafely(SoftWrapAwareTask task) { try { task.run(true); } catch (Throwable e) { if (Boolean.getBoolean(DEBUG_PROPERTY_NAME) || ApplicationManager.getApplication().isUnitTestMode()) { String info = myEditor.dumpState(); LOG.error( String.format("Unexpected exception occurred during performing '%s'", task), e, info); } myEditor.getFoldingModel().rebuild(); myDataMapper.release(); myApplianceManager.reset(); myStorage.removeAll(); myApplianceManager.recalculateIfNecessary(); try { task.run(true); } catch (Throwable e1) { String info = myEditor.dumpState(); LOG.error( String.format("Can't perform %s even with complete soft wraps cache re-parsing", task), e1, info); myEditor.getSettings().setUseSoftWraps(false); task.run(false); } } }
@Override public int getSoftWrapIndex(int offset) { if (myEditor.myUseNewRendering && !isSoftWrappingEnabled()) { return -1; } return myStorage.getSoftWrapIndex(offset); }
public void recalculate() { myApplianceManager.reset(); myStorage.removeAll(); myDeferredFoldRegions.clear(); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); myApplianceManager.recalculateIfNecessary(); }
@Override public List<? extends SoftWrap> getRegisteredSoftWraps() { if (!isSoftWrappingEnabled()) { return Collections.emptyList(); } return myStorage.getSoftWraps(); }
@Override public void release() { myDataMapper.release(); myApplianceManager.release(); myStorage.removeAll(); myDeferredFoldRegions.clear(); }
/** * Called on editor settings change. Current model is expected to drop all cached information * about the settings if any. */ public void reinitSettings() { boolean softWrapsUsedBefore = myUseSoftWraps; myUseSoftWraps = areSoftWrapsEnabledInEditor(); int tabWidthBefore = myTabWidth; myTabWidth = EditorUtil.getTabSize(myEditor); boolean fontsChanged = false; if (!myFontPreferences.equals(myEditor.getColorsScheme().getFontPreferences()) && myEditorTextRepresentationHelper instanceof DefaultEditorTextRepresentationHelper) { fontsChanged = true; myEditor.getColorsScheme().getFontPreferences().copyTo(myFontPreferences); ((DefaultEditorTextRepresentationHelper) myEditorTextRepresentationHelper) .clearSymbolWidthCache(); myPainter.reinit(); } if ((myUseSoftWraps ^ softWrapsUsedBefore) || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore) || fontsChanged) { myApplianceManager.reset(); myDeferredFoldRegions.clear(); myStorage.removeAll(); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); } }
@NotNull @Override public String dumpState() { return String.format( "appliance manager state: %s; soft wraps mapping info: %s; soft wraps: %s", myApplianceManager.dumpState(), myDataMapper.dumpState(), myStorage.dumpState()); }
/** * We know that there are problems with incremental soft wraps cache update at the moment. Hence, * we may implement full cache reconstruction when the problem is encountered in order to avoid * customer annoyance. * * <p>However, the problems still should be fixed, hence, we report them only if dedicated flag is * set. * * <p>Current method encapsulates the logic mentioned above. * * @param task command object that which execution may trigger incremental update of update soft * wraps cache */ @SuppressWarnings({"UseOfArchaicSystemPropertyAccessors"}) private void executeSafely(SoftWrapAwareTask task) { try { task.run(true); } catch (Throwable e) { if (Boolean.getBoolean(DEBUG_PROPERTY_NAME)) { LOG.error( String.format( "Unexpected exception occurred during performing '%s'. Current soft wraps cache: %n" + "%s%nFold regions: %s", task, myDataMapper, Arrays.toString(myEditor.getFoldingModel().fetchTopLevel())), e); } myEditor.getFoldingModel().rebuild(); myDataMapper.release(); myApplianceManager.reset(); myStorage.removeAll(); try { task.run(true); } catch (Throwable e1) { LOG.error( String.format( "Can't perform %s even with complete soft wraps cache re-parsing. Current soft wraps cache: %n" + "%s. Document:%n%s%nFold regions: %s", task, myDataMapper, myEditor.getDocument().getText(), Arrays.toString(myEditor.getFoldingModel().fetchTopLevel())), e1); myEditor.getSettings().setUseSoftWraps(false); task.run(false); } } }
@Nullable public SoftWrap getSoftWrap(int offset) { if (!isSoftWrappingEnabled()) { return null; } return myStorage.getSoftWrap(offset); }
/** @return total number of soft wrap-introduced new visual lines */ public int getSoftWrapsIntroducedLinesNumber() { if (!isSoftWrappingEnabled()) { return 0; } int result = 0; FoldingModel foldingModel = myEditor.getFoldingModel(); for (SoftWrap softWrap : myStorage.getSoftWraps()) { if (!foldingModel.isOffsetCollapsed(softWrap.getStart())) { result++; // Assuming that soft wrap has single line feed all the time } } return result; }
@Override public List<? extends SoftWrap> getRegisteredSoftWraps() { if (!isSoftWrappingEnabled()) { return Collections.emptyList(); } List<SoftWrapImpl> softWraps = myStorage.getSoftWraps(); if (!softWraps.isEmpty() && softWraps.get(softWraps.size() - 1).getStart() >= myEditor.getDocument().getTextLength()) { LOG.error( "Unexpected soft wrap location", new Attachment("editorState.txt", myEditor.dumpState())); } return softWraps; }
@Override public void beforeDocumentChangeAtCaret() { CaretModel caretModel = myEditor.getCaretModel(); VisualPosition visualCaretPosition = caretModel.getVisualPosition(); if (!isInsideSoftWrap(visualCaretPosition)) { return; } SoftWrap softWrap = myStorage.getSoftWrap(caretModel.getOffset()); if (softWrap == null) { return; } myEditor .getDocument() .replaceString(softWrap.getStart(), softWrap.getEnd(), softWrap.getText()); caretModel.moveToVisualPosition(visualCaretPosition); }
/** * Encapsulates preparations for performing document dimension mapping (e.g. visual to logical * position) and answers if soft wraps-aware processing should be used (e.g. there is no need to * consider soft wraps if user configured them not to be used). * * @return <code>true</code> if soft wraps-aware processing should be used; <code>false</code> * otherwise */ public boolean prepareToMapping() { if (myUpdateInProgress || myBulkUpdateInProgress || myActive > 0 || !isSoftWrappingEnabled() || myEditor.getDocument().getTextLength() <= 0) { return false; } if (myDirty) { myStorage.removeAll(); myApplianceManager.reset(); myDeferredFoldRegions.clear(); myDirty = false; } return myApplianceManager.recalculateIfNecessary(); }
@Override public int getSoftWrapIndex(int offset) { return myStorage.getSoftWrapIndex(offset); }
@Override public boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener) { mySoftWrapListeners.add(listener); return myStorage.addSoftWrapChangeListener(listener); }
/** @return total number of soft wrap-introduced new visual lines */ public int getSoftWrapsIntroducedLinesNumber() { return myStorage .getSoftWraps() .size(); // Assuming that soft wrap has single line feed all the time }
public void recalculate() { myApplianceManager.reset(); myStorage.removeAll(); myDeferredFoldRegions.clear(); myApplianceManager.recalculateIfNecessary(); }