public void testNonSmartHome() throws IOException { String text = " this is a string that starts with white space and is long enough to be soft-wrapped\n" + " this is a 'prefix' text before collapsed multi-line folding that is long enough to be soft-wrapped first fold line\n" + "second fold line"; init(30, text); addCollapsedFoldRegion(text.indexOf("first fold line"), text.length(), "..."); List<? extends SoftWrap> softWraps = getSoftWrapModel().getRegisteredSoftWraps(); assertTrue(!softWraps.isEmpty()); CaretModel caretModel = myEditor.getCaretModel(); SoftWrap softWrap = softWraps.get(0); // Test non-smart home myEditor.getSettings().setSmartHome(false); caretModel.moveToOffset(softWrap.getStart() + 1); int visLine = caretModel.getVisualPosition().line; home(); assertEquals(new VisualPosition(visLine, 0), caretModel.getVisualPosition()); caretModel.moveToOffset(text.length()); home(); visLine = caretModel.getVisualPosition().line; assertEquals(new VisualPosition(visLine, 0), caretModel.getVisualPosition()); }
private static TIntHashSet collectSoftWrapStartOffsets(int documentLine) { TIntHashSet result = new TIntHashSet(); for (SoftWrap softWrap : myEditor.getSoftWrapModel().getSoftWrapsForLine(documentLine)) { result.add(softWrap.getStart()); } return result; }
public void testHomeProcessing() throws IOException { String text = "class Test {\n" + " public String s = \"this is a long string literal that is expected to be soft-wrapped into multiple visual lines\";\n" + "}"; init(30, text); myEditor.getCaretModel().moveToOffset(text.indexOf("}") - 1); List<? extends SoftWrap> softWraps = new ArrayList<SoftWrap>(getSoftWrapModel().getRegisteredSoftWraps()); assertTrue(!softWraps.isEmpty()); CaretModel caretModel = myEditor.getCaretModel(); int expectedVisualLine = caretModel.getVisualPosition().line; while (!softWraps.isEmpty()) { SoftWrap softWrap = softWraps.get(softWraps.size() - 1); int caretOffsetBefore = caretModel.getOffset(); home(); // Expecting the caret to be moved at the nearest soft wrap start offset. int caretOffset = caretModel.getOffset(); assertTrue(caretOffset < caretOffsetBefore); assertEquals(softWrap.getStart(), caretOffset); assertEquals( new VisualPosition(expectedVisualLine, softWrap.getIndentInColumns()), caretModel.getVisualPosition()); // Expected that caret is moved to visual line start when it's located on soft wrap start // offset at the moment. home(); assertEquals(softWrap.getStart(), caretModel.getOffset()); assertEquals(new VisualPosition(expectedVisualLine, 0), caretModel.getVisualPosition()); softWraps.remove(softWraps.size() - 1); expectedVisualLine--; } // Expecting caret to be located on the first non-white space symbol of non-soft wrapped line. home(); assertEquals(text.indexOf("public"), caretModel.getOffset()); assertEquals( new VisualPosition(expectedVisualLine, text.indexOf("public") - text.indexOf("{\n") - 2), caretModel.getVisualPosition()); }
/** @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; }
/** * Calculates difference in columns between current editor caret position and end of the logical * line fragment displayed on a current visual line. * * @param editor target editor * @return difference in columns between current editor caret position and end of the logical line * fragment displayed on a current visual line */ public static int calcAfterLineEnd(Editor editor) { Document document = editor.getDocument(); CaretModel caretModel = editor.getCaretModel(); LogicalPosition logicalPosition = caretModel.getLogicalPosition(); int lineNumber = logicalPosition.line; int columnNumber = logicalPosition.column; if (lineNumber >= document.getLineCount()) { return columnNumber; } int caretOffset = caretModel.getOffset(); int anchorLineEndOffset = document.getLineEndOffset(lineNumber); List<? extends SoftWrap> softWraps = editor.getSoftWrapModel().getSoftWrapsForLine(logicalPosition.line); for (SoftWrap softWrap : softWraps) { if (!editor.getSoftWrapModel().isVisible(softWrap)) { continue; } int softWrapOffset = softWrap.getStart(); if (softWrapOffset == caretOffset) { // There are two possible situations: // *) caret is located on a visual line before soft wrap-introduced line feed; // *) caret is located on a visual line after soft wrap-introduced line feed; VisualPosition position = editor.offsetToVisualPosition(caretOffset - 1); VisualPosition visualCaret = caretModel.getVisualPosition(); if (position.line == visualCaret.line) { return visualCaret.column - position.column - 1; } } if (softWrapOffset > caretOffset) { anchorLineEndOffset = softWrapOffset; break; } // Same offset corresponds to all soft wrap-introduced symbols, however, current method should // behave differently in // situations when the caret is located just before the soft wrap and at the next visual line. if (softWrapOffset == caretOffset) { boolean visuallyBeforeSoftWrap = caretModel.getVisualPosition().line < editor.offsetToVisualPosition(caretOffset).line; if (visuallyBeforeSoftWrap) { anchorLineEndOffset = softWrapOffset; break; } } } int lineEndColumnNumber = editor.offsetToLogicalPosition(anchorLineEndOffset).column; return columnNumber - lineEndColumnNumber; }
@Override public boolean isVisible(SoftWrap softWrap) { FoldingModel foldingModel = myEditor.getFoldingModel(); int start = softWrap.getStart(); if (foldingModel.isOffsetCollapsed(start)) { return false; } // There is a possible case that soft wrap and collapsed folding region share the same offset, // i.e. soft wrap is represented // before the folding. We need to return 'true' in such situation. Hence, we check if offset // just before the soft wrap // is collapsed as well. return start <= 0 || !foldingModel.isOffsetCollapsed(start - 1); }
@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); }
public void testEndProcessing() throws IOException { String text = "class Test {\n" + " public String s = \"this is a long string literal that is expected to be soft-wrapped into multiple visual lines\"; \n" + "}"; init(30, text); myEditor.getCaretModel().moveToOffset(text.indexOf("\n") + 1); List<? extends SoftWrap> softWraps = new ArrayList<SoftWrap>(getSoftWrapModel().getRegisteredSoftWraps()); assertTrue(!softWraps.isEmpty()); CaretModel caretModel = myEditor.getCaretModel(); int expectedVisualLine = caretModel.getVisualPosition().line; while (!softWraps.isEmpty()) { SoftWrap softWrap = softWraps.get(0); int caretOffsetBefore = caretModel.getOffset(); end(); // Expecting the caret to be moved at the last non-white space symbol on the current visual // line. int caretOffset = caretModel.getOffset(); assertTrue(caretOffset > caretOffsetBefore); assertFalse(caretOffset > softWrap.getStart()); if (caretOffset < softWrap.getStart()) { // There is a possible case that there are white space symbols between caret position // applied on 'end' processing and // soft wrap. Let's check that and emulate one more 'end' typing in order to move caret // right before soft wrap. for (int i = caretOffset; i < softWrap.getStart(); i++) { char c = text.charAt(i); assertTrue(c == ' ' || c == '\t'); } caretOffsetBefore = caretOffset; end(); caretOffset = caretModel.getOffset(); assertTrue(caretOffset > caretOffsetBefore); } assertEquals(softWrap.getStart(), caretOffset); assertEquals( new VisualPosition( expectedVisualLine, myEditor.offsetToVisualPosition(softWrap.getStart() - 1).column + 1), caretModel.getVisualPosition()); softWraps.remove(0); expectedVisualLine++; } // Check that caret is placed on a last non-white space symbol on current logical line. end(); int lastNonWhiteSpaceSymbolOffset = text.indexOf("\";") + 2; assertEquals(lastNonWhiteSpaceSymbolOffset, caretModel.getOffset()); assertEquals( myEditor.offsetToVisualPosition(lastNonWhiteSpaceSymbolOffset), caretModel.getVisualPosition()); assertEquals(expectedVisualLine, caretModel.getVisualPosition().line); // Check that caret is place to the very end of the logical line. end(); int lastSymbolOffset = myEditor.getDocument().getLineEndOffset(caretModel.getLogicalPosition().line); assertEquals(lastSymbolOffset, caretModel.getOffset()); assertEquals(myEditor.offsetToVisualPosition(lastSymbolOffset), caretModel.getVisualPosition()); assertEquals(expectedVisualLine, caretModel.getVisualPosition().line); }