コード例 #1
0
  public static void typeInStringAtCaretHonorBlockSelection(
      final Editor editor, final String str, final boolean toProcessOverwriteMode)
      throws ReadOnlyFragmentModificationException {
    Document doc = editor.getDocument();
    final SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasBlockSelection()) {
      RangeMarker guard = selectionModel.getBlockSelectionGuard();
      if (guard != null) {
        DocumentEvent evt = new MockDocumentEvent(doc, editor.getCaretModel().getOffset());
        ReadOnlyFragmentModificationException e =
            new ReadOnlyFragmentModificationException(evt, guard);
        EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
      } else {
        final LogicalPosition start = selectionModel.getBlockStart();
        final LogicalPosition end = selectionModel.getBlockEnd();
        assert start != null;
        assert end != null;

        int column = Math.min(start.column, end.column);
        int startLine = Math.min(start.line, end.line);
        int endLine = Math.max(start.line, end.line);
        deleteBlockSelection(editor);
        for (int i = startLine; i <= endLine; i++) {
          editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, column));
          insertStringAtCaret(editor, str, toProcessOverwriteMode, true);
        }
        selectionModel.setBlockSelection(
            new LogicalPosition(startLine, column + str.length()),
            new LogicalPosition(endLine, column + str.length()));
      }
    } else {
      insertStringAtCaret(editor, str, toProcessOverwriteMode, true);
    }
  }
コード例 #2
0
  public static void pasteTransferableAsBlock(
      Editor editor, @Nullable Producer<Transferable> producer) {
    String text = getStringContent(producer);
    if (text == null) return;

    int caretLine = editor.getCaretModel().getLogicalPosition().line;
    int originalCaretLine = caretLine;
    int selectedLinesCount = 0;

    final SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasBlockSelection()) {
      final LogicalPosition start = selectionModel.getBlockStart();
      final LogicalPosition end = selectionModel.getBlockEnd();
      assert start != null;
      assert end != null;
      LogicalPosition caret =
          new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column));
      selectedLinesCount = Math.abs(end.line - start.line);
      caretLine = caret.line;

      deleteSelectedText(editor);
      editor.getCaretModel().moveToLogicalPosition(caret);
    }

    LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition();

    String[] lines = LineTokenizer.tokenize(text.toCharArray(), false);
    if (lines.length > 1 || selectedLinesCount == 0) {
      int longestLineLength = 0;
      for (int i = 0; i < lines.length; i++) {
        String line = lines[i];
        longestLineLength = Math.max(longestLineLength, line.length());
        editor
            .getCaretModel()
            .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
        insertStringAtCaret(editor, line, false, true);
      }
      caretToRestore =
          new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength);
    } else {
      for (int i = 0; i <= selectedLinesCount; i++) {
        editor
            .getCaretModel()
            .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
        insertStringAtCaret(editor, text, false, true);
      }
      caretToRestore =
          new LogicalPosition(originalCaretLine, caretToRestore.column + text.length());
    }

    editor.getCaretModel().moveToLogicalPosition(caretToRestore);
    zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount);
  }
コード例 #3
0
  public static void deleteSelectedText(Editor editor) {
    SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasBlockSelection()) deleteBlockSelection(editor);
    if (!selectionModel.hasSelection()) return;

    int selectionStart = selectionModel.getSelectionStart();
    int selectionEnd = selectionModel.getSelectionEnd();

    editor.getCaretModel().moveToOffset(selectionStart);
    selectionModel.removeSelection();
    editor.getDocument().deleteString(selectionStart, selectionEnd);
    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
  }
コード例 #4
0
  public void performReplaceAll(Editor e) {
    if (!ReadonlyStatusHandler.ensureDocumentWritable(e.getProject(), e.getDocument())) return;
    if (mySearchResults.getFindModel() != null) {
      final FindModel copy = new FindModel();
      copy.copyFrom(mySearchResults.getFindModel());

      final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel();

      final int offset;
      if ((!selectionModel.hasSelection() && !selectionModel.hasBlockSelection())
          || copy.isGlobal()) {
        copy.setGlobal(true);
        offset = 0;
      } else {
        offset = selectionModel.getBlockSelectionStarts()[0];
      }
      FindUtil.replace(e.getProject(), e, offset, copy, this);
    }
  }
コード例 #5
0
  public static void deleteBlockSelection(Editor editor) {
    SelectionModel selectionModel = editor.getSelectionModel();
    if (!selectionModel.hasBlockSelection()) return;

    LogicalPosition blockStart = selectionModel.getBlockStart();
    LogicalPosition blockEnd = selectionModel.getBlockEnd();
    if (blockStart == null || blockEnd == null) {
      return;
    }

    int startLine = blockStart.line;
    int endLine = blockEnd.line;

    int[] starts = selectionModel.getBlockSelectionStarts();
    int[] ends = selectionModel.getBlockSelectionEnds();

    for (int i = starts.length - 1; i >= 0; i--) {
      editor.getDocument().deleteString(starts[i], ends[i]);
    }

    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);

    zeroWidthBlockSelectionAtCaretColumn(editor, startLine, endLine);
  }
コード例 #6
0
  @Nullable
  @Override
  public TextBlockTransferableData collectTransferableData(
      PsiFile file, Editor editor, int[] startOffsets, int[] endOffsets) {
    if (!Registry.is("editor.richcopy.enable")) {
      return null;
    }

    try {
      for (TextWithMarkupBuilder builder : myBuilders) {
        builder.reset();
      }
      SelectionModel selectionModel = editor.getSelectionModel();
      if (selectionModel.hasBlockSelection()) {
        return null; // unsupported legacy mode
      }

      RichCopySettings settings = RichCopySettings.getInstance();
      List<Caret> carets = editor.getCaretModel().getAllCarets();
      Caret firstCaret = carets.get(0);
      final int indentSymbolsToStrip;
      final int firstLineStartOffset;
      if (settings.isStripIndents() && carets.size() == 1) {
        Pair<Integer, Integer> p =
            calcIndentSymbolsToStrip(
                editor.getDocument(), firstCaret.getSelectionStart(), firstCaret.getSelectionEnd());
        firstLineStartOffset = p.first;
        indentSymbolsToStrip = p.second;
      } else {
        firstLineStartOffset = firstCaret.getSelectionStart();
        indentSymbolsToStrip = 0;
      }
      logInitial(editor, startOffsets, endOffsets, indentSymbolsToStrip, firstLineStartOffset);
      CharSequence text = editor.getDocument().getCharsSequence();
      EditorColorsScheme schemeToUse = settings.getColorsScheme(editor.getColorsScheme());
      EditorHighlighter highlighter =
          HighlighterFactory.createHighlighter(
              file.getVirtualFile(), schemeToUse, file.getProject());
      highlighter.setText(text);
      MarkupModel markupModel =
          DocumentMarkupModel.forDocument(editor.getDocument(), file.getProject(), false);
      Context context = new Context(text, schemeToUse, indentSymbolsToStrip);
      int shift = 0;
      int endOffset = 0;
      Caret prevCaret = null;

      for (Caret caret : carets) {
        int caretSelectionStart = caret.getSelectionStart();
        int caretSelectionEnd = caret.getSelectionEnd();
        int startOffsetToUse;
        if (caret == firstCaret) {
          startOffsetToUse = firstLineStartOffset;
        } else {
          startOffsetToUse = caretSelectionStart;
          assert prevCaret != null;
          String prevCaretSelectedText = prevCaret.getSelectedText();
          // Block selection fills short lines by white spaces.
          int fillStringLength =
              prevCaretSelectedText == null
                  ? 0
                  : prevCaretSelectedText.length()
                      - (prevCaret.getSelectionEnd() - prevCaret.getSelectionStart());
          int endLineOffset = endOffset + shift + fillStringLength;
          context.builder.addText(endLineOffset, endLineOffset + 1);
          shift++; // Block selection ends '\n' at line end
          shift += fillStringLength;
        }
        shift += endOffset - caretSelectionStart;
        endOffset = caretSelectionEnd;
        context.reset(shift);
        prevCaret = caret;
        if (endOffset <= startOffsetToUse) {
          continue;
        }
        MarkupIterator markupIterator =
            new MarkupIterator(
                text,
                new CompositeRangeIterator(
                    schemeToUse,
                    new HighlighterRangeIterator(highlighter, startOffsetToUse, endOffset),
                    new MarkupModelRangeIterator(
                        markupModel, schemeToUse, startOffsetToUse, endOffset)),
                schemeToUse);
        try {
          context.iterate(markupIterator, endOffset);
        } finally {
          markupIterator.dispose();
        }
      }
      SyntaxInfo syntaxInfo = context.finish();
      logSyntaxInfo(syntaxInfo);

      for (TextWithMarkupBuilder builder : myBuilders) {
        builder.build(syntaxInfo);
      }
    } catch (Exception e) {
      // catching the exception so that the rest of copy/paste functionality can still work fine
      LOG.error(e);
    }
    return null;
  }
コード例 #7
0
  public void moveCaretRelatively(
      int columnShift,
      int lineShift,
      boolean withSelection,
      boolean blockSelection,
      boolean scrollToCaret) {
    assertIsDispatchThread();
    SelectionModel selectionModel = myEditor.getSelectionModel();
    int selectionStart = selectionModel.getLeadSelectionOffset();
    LogicalPosition blockSelectionStart =
        selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : getLogicalPosition();
    EditorSettings editorSettings = myEditor.getSettings();
    VisualPosition visualCaret = getVisualPosition();

    int desiredX = myDesiredX;
    if (columnShift == 0) {
      if (myDesiredX < 0) {
        desiredX = myEditor.visualPositionToXY(visualCaret).x;
      }
    } else {
      myDesiredX = desiredX = -1;
    }

    int newLineNumber = visualCaret.line + lineShift;
    int newColumnNumber = visualCaret.column + columnShift;
    if (desiredX >= 0 && !ApplicationManager.getApplication().isUnitTestMode()) {
      newColumnNumber =
          myEditor.xyToVisualPosition(
                  new Point(desiredX, Math.max(0, newLineNumber) * myEditor.getLineHeight()))
              .column;
    }

    Document document = myEditor.getDocument();
    if (!editorSettings.isVirtualSpace()
        && columnShift == 0
        && getLogicalPosition().softWrapLinesOnCurrentLogicalLine <= 0) {
      newColumnNumber = myEditor.getLastColumnNumber();
    } else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == 1) {
      int lastLine = document.getLineCount() - 1;
      if (lastLine < 0) lastLine = 0;
      if (EditorModificationUtil.calcAfterLineEnd(myEditor) >= 0
          && newLineNumber
              < myEditor.logicalToVisualPosition(new LogicalPosition(lastLine, 0)).line) {
        newColumnNumber = 0;
        newLineNumber++;
      }
    } else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == -1) {
      if (newColumnNumber < 0 && newLineNumber > 0) {
        newLineNumber--;
        newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber);
      }
    }

    if (newColumnNumber < 0) newColumnNumber = 0;

    // There is a possible case that caret is located at the first line and user presses 'Shift+Up'.
    // We want to select all text
    // from the document start to the current caret position then. So, we have a dedicated flag for
    // tracking that.
    boolean selectToDocumentStart = false;
    if (newLineNumber < 0) {
      selectToDocumentStart = true;
      newLineNumber = 0;

      // We want to move caret to the first column if it's already located at the first line and
      // 'Up' is pressed.
      newColumnNumber = 0;
      desiredX = -1;
    }

    VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber);
    int lastColumnNumber = newColumnNumber;
    if (!editorSettings.isCaretInsideTabs() && !myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
      LogicalPosition log =
          myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber));
      int offset = myEditor.logicalPositionToOffset(log);
      if (offset >= document.getTextLength()) {
        int lastOffsetColumn = myEditor.offsetToVisualPosition(document.getTextLength()).column;
        // We want to move caret to the last column if if it's located at the last line and 'Down'
        // is pressed.
        newColumnNumber = lastColumnNumber = Math.max(lastOffsetColumn, newColumnNumber);
        desiredX = -1;
      }
      CharSequence text = document.getCharsSequence();
      if (offset >= 0 && offset < document.getTextLength()) {
        if (text.charAt(offset) == '\t' && (columnShift <= 0 || offset == myOffset)) {
          if (columnShift <= 0) {
            newColumnNumber = myEditor.offsetToVisualPosition(offset).column;
          } else {
            SoftWrap softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset + 1);
            // There is a possible case that tabulation symbol is the last document symbol
            // represented on a visual line before
            // soft wrap. We can't just use column from 'offset + 1' because it would point on a
            // next visual line.
            if (softWrap == null) {
              newColumnNumber = myEditor.offsetToVisualPosition(offset + 1).column;
            } else {
              newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber);
            }
          }
        }
      }
    }

    pos = new VisualPosition(newLineNumber, newColumnNumber);
    if (columnShift != 0 && lineShift == 0 && myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
      LogicalPosition logical = myEditor.visualToLogicalPosition(pos);
      int softWrapOffset = myEditor.logicalPositionToOffset(logical);
      if (columnShift >= 0) {
        moveToOffset(softWrapOffset);
      } else {
        int line = myEditor.offsetToVisualLine(softWrapOffset - 1);
        moveToVisualPosition(
            new VisualPosition(line, EditorUtil.getLastVisualLineColumnNumber(myEditor, line)));
      }
    } else {
      moveToVisualPosition(pos);
      if (!editorSettings.isVirtualSpace() && columnShift == 0) {
        myEditor.setLastColumnNumber(lastColumnNumber);
      }
    }

    if (withSelection) {
      if (blockSelection) {
        selectionModel.setBlockSelection(blockSelectionStart, getLogicalPosition());
      } else {
        if (selectToDocumentStart) {
          selectionModel.setSelection(selectionStart, 0);
        } else if (pos.line >= myEditor.getVisibleLineCount()) {
          if (selectionStart < document.getTextLength()) {
            selectionModel.setSelection(selectionStart, document.getTextLength());
          }
        } else {
          selectionModel.setSelection(selectionStart, getVisualPosition(), getOffset());
        }
      }
    } else {
      selectionModel.removeSelection();
    }

    if (scrollToCaret) {
      myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
    }

    if (desiredX >= 0) {
      myDesiredX = desiredX;
    }

    EditorActionUtil.selectNonexpandableFold(myEditor);
  }