Example #1
0
  @Override
  public void execute(
      final Editor editor,
      final DataContext dataContext,
      @Nullable final Producer<Transferable> producer) {
    if (!CodeInsightUtilBase.prepareEditorForWrite(editor)) return;

    final Document document = editor.getDocument();
    if (!FileDocumentManager.getInstance()
        .requestWriting(document, CommonDataKeys.PROJECT.getData(dataContext))) {
      return;
    }

    DataContext context = dataContext;
    if (producer != null) {
      context =
          new DataContext() {
            @Override
            public Object getData(@NonNls String dataId) {
              return PasteAction.TRANSFERABLE_PROVIDER.is(dataId)
                  ? producer
                  : dataContext.getData(dataId);
            }
          };
    }

    final Project project = editor.getProject();
    if (project == null
        || editor.isColumnMode()
        || editor.getSelectionModel().hasBlockSelection()
        || editor.getCaretModel().getCaretCount() > 1) {
      if (myOriginalHandler != null) {
        myOriginalHandler.execute(editor, context);
      }
      return;
    }

    final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
    if (file == null) {
      if (myOriginalHandler != null) {
        myOriginalHandler.execute(editor, context);
      }
      return;
    }

    document.startGuardedBlockChecking();
    try {
      for (PasteProvider provider : Extensions.getExtensions(EP_NAME)) {
        if (provider.isPasteEnabled(context)) {
          provider.performPaste(context);
          return;
        }
      }
      doPaste(editor, project, file, document, producer);
    } catch (ReadOnlyFragmentModificationException e) {
      EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(document).handle(e);
    } finally {
      document.stopGuardedBlockChecking();
    }
  }
  @NotNull
  private LookupImpl obtainLookup(Editor editor) {
    CompletionAssertions.checkEditorValid(editor);
    LookupImpl existing = (LookupImpl) LookupManager.getActiveLookup(editor);
    if (existing != null && existing.isCompletion()) {
      existing.markReused();
      if (!autopopup) {
        existing.setFocusDegree(LookupImpl.FocusDegree.FOCUSED);
      }
      return existing;
    }

    LookupImpl lookup =
        (LookupImpl)
            LookupManager.getInstance(editor.getProject())
                .createLookup(
                    editor, LookupElement.EMPTY_ARRAY, "", new LookupArranger.DefaultArranger());
    if (editor.isOneLineMode()) {
      lookup.setCancelOnClickOutside(true);
      lookup.setCancelOnOtherWindowOpen(true);
    }
    lookup.setFocusDegree(
        autopopup ? LookupImpl.FocusDegree.UNFOCUSED : LookupImpl.FocusDegree.FOCUSED);
    return lookup;
  }
  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);
    }
  }
  /**
   * Emulates pressing <code>Enter</code> at current caret position.
   *
   * @param editor target editor
   * @param project target project
   * @param shifts two-elements array which is expected to be filled with the following info: 1. The
   *     first element holds added lines number; 2. The second element holds added symbols number;
   */
  private static void emulateEnter(
      @NotNull final Editor editor, @NotNull Project project, int[] shifts) {
    final DataContext dataContext = prepareContext(editor.getComponent(), project);
    int caretOffset = editor.getCaretModel().getOffset();
    Document document = editor.getDocument();
    SelectionModel selectionModel = editor.getSelectionModel();
    int startSelectionOffset = 0;
    int endSelectionOffset = 0;
    boolean restoreSelection = selectionModel.hasSelection();
    if (restoreSelection) {
      startSelectionOffset = selectionModel.getSelectionStart();
      endSelectionOffset = selectionModel.getSelectionEnd();
      selectionModel.removeSelection();
    }
    int textLengthBeforeWrap = document.getTextLength();
    int lineCountBeforeWrap = document.getLineCount();

    DataManager.getInstance()
        .saveInDataContext(dataContext, WRAP_LONG_LINE_DURING_FORMATTING_IN_PROGRESS_KEY, true);
    CommandProcessor commandProcessor = CommandProcessor.getInstance();
    try {
      Runnable command =
          new Runnable() {
            @Override
            public void run() {
              EditorActionManager.getInstance()
                  .getActionHandler(IdeActions.ACTION_EDITOR_ENTER)
                  .execute(editor, dataContext);
            }
          };
      if (commandProcessor.getCurrentCommand() == null) {
        commandProcessor.executeCommand(editor.getProject(), command, WRAP_LINE_COMMAND_NAME, null);
      } else {
        command.run();
      }
    } finally {
      DataManager.getInstance()
          .saveInDataContext(dataContext, WRAP_LONG_LINE_DURING_FORMATTING_IN_PROGRESS_KEY, null);
    }
    int symbolsDiff = document.getTextLength() - textLengthBeforeWrap;
    if (restoreSelection) {
      int newSelectionStart = startSelectionOffset;
      int newSelectionEnd = endSelectionOffset;
      if (startSelectionOffset >= caretOffset) {
        newSelectionStart += symbolsDiff;
      }
      if (endSelectionOffset >= caretOffset) {
        newSelectionEnd += symbolsDiff;
      }
      selectionModel.setSelection(newSelectionStart, newSelectionEnd);
    }
    shifts[0] = document.getLineCount() - lineCountBeforeWrap;
    shifts[1] = symbolsDiff;
  }
 @Nullable
 public TextRange performReplace(
     final FindResult occurrence, final String replacement, final Editor editor) {
   if (myReplaceDenied
       || !ReadonlyStatusHandler.ensureDocumentWritable(editor.getProject(), editor.getDocument()))
     return null;
   FindModel findModel = mySearchResults.getFindModel();
   TextRange result =
       FindUtil.doReplace(
           editor.getProject(),
           editor.getDocument(),
           findModel,
           new FindResultImpl(occurrence.getStartOffset(), occurrence.getEndOffset()),
           replacement,
           true,
           new ArrayList<Pair<TextRange, String>>());
   myLivePreview.inSmartUpdate();
   mySearchResults.updateThreadSafe(findModel, true, result, mySearchResults.getStamp());
   return result;
 }
  @Override
  public final void execute(final Editor editor, final DataContext dataContext) {
    if (editor.isViewer()) return;

    if (dataContext != null) {
      Project project = CommonDataKeys.PROJECT.getData(dataContext);
      if (project != null
          && !FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project))
        return;
    }

    ApplicationManager.getApplication()
        .runWriteAction(
            new DocumentRunnable(editor.getDocument(), editor.getProject()) {
              @Override
              public void run() {
                final Document doc = editor.getDocument();
                final SelectionModel selectionModel = editor.getSelectionModel();
                if (selectionModel.hasBlockSelection()) {
                  RangeMarker guard = selectionModel.getBlockSelectionGuard();
                  if (guard != null) {
                    DocumentEvent evt =
                        new MockDocumentEvent(
                            editor.getDocument(), editor.getCaretModel().getOffset());
                    ReadOnlyFragmentModificationException e =
                        new ReadOnlyFragmentModificationException(evt, guard);
                    EditorActionManager.getInstance()
                        .getReadonlyFragmentModificationHandler(doc)
                        .handle(e);
                    return;
                  }
                }

                doc.startGuardedBlockChecking();
                try {
                  executeWriteAction(editor, dataContext);
                } catch (ReadOnlyFragmentModificationException e) {
                  EditorActionManager.getInstance()
                      .getReadonlyFragmentModificationHandler(doc)
                      .handle(e);
                } finally {
                  doc.stopGuardedBlockChecking();
                }
              }
            });
  }
 @Override
 public void run() {
   ApplicationManager.getApplication()
       .runWriteAction(
           new DocumentRunnable(myEditor.getDocument(), myEditor.getProject()) {
             @Override
             public void run() {
               Document doc = myEditor.getDocument();
               doc.startGuardedBlockChecking();
               try {
                 getHandler().execute(myEditor, myCharTyped, myDataContext);
               } catch (ReadOnlyFragmentModificationException e) {
                 EditorActionManager.getInstance()
                     .getReadonlyFragmentModificationHandler(doc)
                     .handle(e);
               } finally {
                 doc.stopGuardedBlockChecking();
               }
             }
           });
 }
  public static String calcStringToFillVirtualSpace(Editor editor, int afterLineEnd) {
    final Project project = editor.getProject();
    StringBuilder buf = new StringBuilder();
    final Document doc = editor.getDocument();
    final int caretOffset = editor.getCaretModel().getOffset();
    boolean atLineStart =
        caretOffset >= doc.getTextLength()
            || doc.getLineStartOffset(doc.getLineNumber(caretOffset)) == caretOffset;
    if (atLineStart && project != null) {
      int offset = editor.getCaretModel().getOffset();
      PsiDocumentManager.getInstance(project)
          .commitDocument(doc); // Sync document and PSI before formatting.
      String properIndent =
          offset >= doc.getTextLength()
              ? ""
              : CodeStyleFacade.getInstance(project).getLineIndent(doc, offset);
      if (properIndent != null) {
        int tabSize = editor.getSettings().getTabSize(project);
        for (int i = 0; i < properIndent.length(); i++) {
          if (properIndent.charAt(i) == ' ') {
            afterLineEnd--;
          } else if (properIndent.charAt(i) == '\t') {
            if (afterLineEnd < tabSize) {
              break;
            }
            afterLineEnd -= tabSize;
          }
          buf.append(properIndent.charAt(i));
          if (afterLineEnd == 0) break;
        }
      }
    }

    for (int i = 0; i < afterLineEnd; i++) {
      buf.append(' ');
    }

    return buf.toString();
  }
  @Override
  public String getStringToReplace(Editor editor, FindResult findResult) {
    if (findResult == null) {
      return null;
    }
    String foundString = editor.getDocument().getText(findResult);
    String documentText = editor.getDocument().getText();
    FindModel currentModel = mySearchResults.getFindModel();
    String stringToReplace = null;

    if (currentModel != null) {
      if (currentModel.isReplaceState()) {
        FindManager findManager = FindManager.getInstance(editor.getProject());
        try {
          stringToReplace =
              findManager.getStringToReplace(
                  foundString, currentModel, findResult.getStartOffset(), documentText);
        } catch (FindManager.MalformedReplacementStringException e) {
          return null;
        }
      }
    }
    return stringToReplace;
  }
 public UsageView showInUsageView() {
   return FindUtil.showInUsageView(
       null, collectNonBinaryElements(), myTitle, myEditor.getProject());
 }
  public void doWrapLongLinesIfNecessary(
      @NotNull final Editor editor,
      @NotNull final Project project,
      @NotNull Document document,
      int startOffset,
      int endOffset) {
    // Normalization.
    int startOffsetToUse = Math.min(document.getTextLength(), Math.max(0, startOffset));
    int endOffsetToUse = Math.min(document.getTextLength(), Math.max(0, endOffset));

    LineWrapPositionStrategy strategy = LanguageLineWrapPositionStrategy.INSTANCE.forEditor(editor);
    CharSequence text = document.getCharsSequence();
    int startLine = document.getLineNumber(startOffsetToUse);
    int endLine = document.getLineNumber(Math.max(0, endOffsetToUse - 1));
    int maxLine = Math.min(document.getLineCount(), endLine + 1);
    int tabSize = EditorUtil.getTabSize(editor);
    if (tabSize <= 0) {
      tabSize = 1;
    }
    int spaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, editor);
    int[] shifts = new int[2];
    // shifts[0] - lines shift.
    // shift[1] - offset shift.

    for (int line = startLine; line < maxLine; line++) {
      int startLineOffset = document.getLineStartOffset(line);
      int endLineOffset = document.getLineEndOffset(line);
      final int preferredWrapPosition =
          calculatePreferredWrapPosition(
              editor, text, tabSize, spaceSize, startLineOffset, endLineOffset, endOffsetToUse);

      if (preferredWrapPosition < 0 || preferredWrapPosition >= endLineOffset) {
        continue;
      }
      if (preferredWrapPosition >= endOffsetToUse) {
        return;
      }

      // We know that current line exceeds right margin if control flow reaches this place, so, wrap
      // it.
      int wrapOffset =
          strategy.calculateWrapPosition(
              document,
              editor.getProject(),
              Math.max(startLineOffset, startOffsetToUse),
              Math.min(endLineOffset, endOffsetToUse),
              preferredWrapPosition,
              false,
              false);
      if (wrapOffset < 0 // No appropriate wrap position is found.
          // No point in splitting line when its left part contains only white spaces, example:
          //    line start -> |                   | <- right margin
          //                  |   aaaaaaaaaaaaaaaa|aaaaaaaaaaaaaaaaaaaa() <- don't want to wrap this
          // line even if it exceeds right margin
          || CharArrayUtil.shiftBackward(text, startLineOffset, wrapOffset - 1, " \t")
              < startLineOffset) {
        continue;
      }

      // Move caret to the target position and emulate pressing <enter>.
      editor.getCaretModel().moveToOffset(wrapOffset);
      emulateEnter(editor, project, shifts);

      // We know that number of lines is just increased, hence, update the data accordingly.
      maxLine += shifts[0];
      endOffsetToUse += shifts[1];
    }
  }