Esempio n. 1
0
  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());
  }
Esempio n. 2
0
  public void testSoftWrapToHardWrapConversion() throws IOException {
    String text =
        "this is line 1\n"
            + "this is line 2\n"
            + "this is line 3\n"
            + "this is line 4\n"
            + "this is line 5";

    init(50, text, 7);
    VisualPosition changePosition = new VisualPosition(1, 0);
    myEditor.getCaretModel().moveToVisualPosition(changePosition);

    int logicalLinesBefore = myEditor.offsetToLogicalPosition(text.length()).line;
    int offsetBefore = myEditor.getCaretModel().getOffset();

    LogicalPosition logicalPositionBefore = myEditor.visualToLogicalPosition(changePosition);
    assertEquals(1, logicalPositionBefore.softWrapLinesOnCurrentLogicalLine);
    assertTrue(logicalPositionBefore.column > 0);

    SoftWrap softWrap = getSoftWrapModel().getSoftWrap(offsetBefore);
    assertNotNull(softWrap);

    type('a');

    LogicalPosition logicalPositionAfter = myEditor.visualToLogicalPosition(changePosition);
    assertEquals(new LogicalPosition(1, 0, 0, 0, 0, 0, 0), logicalPositionAfter);
    assertEquals(
        offsetBefore + softWrap.getText().length() + 1, myEditor.getCaretModel().getOffset());
    assertEquals(logicalLinesBefore + 1, myEditor.offsetToLogicalPosition(text.length()).line);
  }
Esempio n. 3
0
 private static TIntHashSet collectSoftWrapStartOffsets(int documentLine) {
   TIntHashSet result = new TIntHashSet();
   for (SoftWrap softWrap : myEditor.getSoftWrapModel().getSoftWrapsForLine(documentLine)) {
     result.add(softWrap.getStart());
   }
   return result;
 }
Esempio n. 4
0
  private VerticalInfo createVerticalInfo(LogicalPosition position) {
    Document document = myEditor.getDocument();
    int logicalLine = position.line;
    if (logicalLine >= document.getLineCount()) {
      logicalLine = Math.max(0, document.getLineCount() - 1);
    }
    int startOffset = document.getLineStartOffset(logicalLine);
    int endOffset = document.getLineEndOffset(logicalLine);

    // There is a possible case that active logical line is represented on multiple lines due to
    // soft wraps processing.
    // We want to highlight those visual lines as 'active' then, so, we calculate 'y' position for
    // the logical line start
    // and height in accordance with the number of occupied visual lines.
    VisualPosition visualPosition =
        myEditor.offsetToVisualPosition(document.getLineStartOffset(logicalLine));
    int y = myEditor.visualPositionToXY(visualPosition).y;
    int lineHeight = myEditor.getLineHeight();
    int height = lineHeight;
    List<? extends SoftWrap> softWraps =
        myEditor.getSoftWrapModel().getSoftWrapsForRange(startOffset, endOffset);
    for (SoftWrap softWrap : softWraps) {
      height += StringUtil.countNewLines(softWrap.getText()) * lineHeight;
    }

    return new VerticalInfo(y, height);
  }
  private boolean isInsideSoftWrap(@NotNull VisualPosition visual, boolean countBeforeSoftWrap) {
    if (!isSoftWrappingEnabled()) {
      return false;
    }
    SoftWrapModel model = myEditor.getSoftWrapModel();
    if (!model.isSoftWrappingEnabled()) {
      return false;
    }
    LogicalPosition logical = myEditor.visualToLogicalPosition(visual);
    int offset = myEditor.logicalPositionToOffset(logical);
    if (offset <= 0) {
      // Never expect to be here, just a defensive programming.
      return false;
    }

    SoftWrap softWrap = model.getSoftWrap(offset);
    if (softWrap == null) {
      return false;
    }

    // We consider visual positions that point after the last symbol before soft wrap and the first
    // symbol after soft wrap to not
    // belong to soft wrap-introduced virtual space.
    VisualPosition visualAfterSoftWrap = myEditor.offsetToVisualPosition(offset);
    if (visualAfterSoftWrap.line == visual.line && visualAfterSoftWrap.column <= visual.column) {
      return false;
    }

    if (myEditor.myUseNewRendering) {
      VisualPosition beforeSoftWrap = myEditor.offsetToVisualPosition(offset, true, true);
      return visual.line > beforeSoftWrap.line
          || visual.column > beforeSoftWrap.column
          || visual.column == beforeSoftWrap.column && countBeforeSoftWrap;
    } else {
      VisualPosition visualBeforeSoftWrap = myEditor.offsetToVisualPosition(offset - 1);
      int x = 0;
      LogicalPosition logLineStart =
          myEditor.visualToLogicalPosition(new VisualPosition(visualBeforeSoftWrap.line, 0));
      if (logLineStart.softWrapLinesOnCurrentLogicalLine > 0) {
        int offsetLineStart = myEditor.logicalPositionToOffset(logLineStart);
        softWrap = model.getSoftWrap(offsetLineStart);
        if (softWrap != null) {
          x = softWrap.getIndentInPixels();
        }
      }
      int width =
          EditorUtil.textWidthInColumns(
              myEditor, myEditor.getDocument().getCharsSequence(), offset - 1, offset, x);
      int softWrapStartColumn = visualBeforeSoftWrap.column + width;
      if (visual.line > visualBeforeSoftWrap.line) {
        return true;
      }
      return countBeforeSoftWrap
          ? visual.column >= softWrapStartColumn
          : visual.column > softWrapStartColumn;
    }
  }
  @Override
  public VisualPosition processSoftWrap(@NotNull EditorPosition position, SoftWrap softWrap) {
    position.visualColumn = softWrap.getIndentInColumns();
    position.softWrapColumnDiff += softWrap.getIndentInColumns();

    if (position.logicalLine < myTargetLogical.line
        || position.logicalColumn != myTargetLogical.column) {
      return null;
    }
    return position.buildVisualPosition();
  }
 /** @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;
  }
Esempio n. 9
0
  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());
  }
  @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);
  }
  @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);
  }
Esempio n. 12
0
  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);
  }