public void invoke(
      @NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();

    final LookupEx lookup = LookupManagerImpl.getActiveLookup(editor);
    if (lookup != null) {
      lookup.showElementActions();
      return;
    }

    if (HintManagerImpl.getInstanceImpl().performCurrentQuestionAction()) return;

    // intentions check isWritable before modification: if (!file.isWritable()) return;
    if (file instanceof PsiCodeFragment) return;

    TemplateState state = TemplateManagerImpl.getTemplateState(editor);
    if (state != null && !state.isFinished()) {
      return;
    }

    final DaemonCodeAnalyzerImpl codeAnalyzer =
        (DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(project);
    codeAnalyzer.autoImportReferenceAtCursor(editor, file); // let autoimport complete

    ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
    ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);

    if (!intentions.isEmpty()) {
      IntentionHintComponent.showIntentionHint(project, file, editor, intentions, true);
    }
  }
 public void stopIntroduce(Editor editor) {
   final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
   if (templateState != null) {
     final Runnable runnable = () -> templateState.gotoEnd(true);
     CommandProcessor.getInstance()
         .executeCommand(myProject, runnable, getCommandName(), getCommandName());
   }
 }
 public Result calculateResult(ExpressionContext context) {
   TemplateState templateState = TemplateManagerImpl.getTemplateState(context.getEditor());
   final TextResult insertedValue =
       templateState != null
           ? templateState.getVariableValue(InplaceRefactoring.PRIMARY_VARIABLE_NAME)
           : null;
   if (insertedValue != null) {
     if (!insertedValue.getText().isEmpty()) return insertedValue;
   }
   return new TextResult(myName);
 }
  @Override
  protected void doAction(
      @NotNull String text, boolean actionShouldBeAvailable, String testFullPath, String testName)
      throws Exception {
    TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
    super.doAction(text, actionShouldBeAvailable, testFullPath, testName);

    if (actionShouldBeAvailable) {
      TemplateState state = TemplateManagerImpl.getTemplateState(getEditor());
      if (state != null) {
        state.gotoEnd(false);
      }
    }
  }
  private void doTestWithTemplateFinish(
      @NotNull String fileName, Surrounder surrounder, @Nullable String textToType) {
    TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
    configureByFile(BASE_PATH + fileName + ".java");
    SurroundWithHandler.invoke(getProject(), getEditor(), getFile(), surrounder);

    if (textToType != null) {
      type(textToType);
    }
    TemplateState templateState = TemplateManagerImpl.getTemplateState(getEditor());
    assertNotNull(templateState);
    templateState.nextTab();
    checkResultByFile(BASE_PATH + fileName + "_after.java");
  }
 public void restartInplaceIntroduceTemplate() {
   Runnable restartTemplateRunnable =
       () -> {
         final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
         if (templateState != null) {
           myEditor.putUserData(INTRODUCE_RESTART, true);
           try {
             final TextRange range = templateState.getCurrentVariableRange();
             if (range != null) {
               final TextResult inputText = templateState.getVariableValue(PRIMARY_VARIABLE_NAME);
               final String inputName = inputText != null ? inputText.getText() : null;
               final V variable = getVariable();
               if (inputName == null
                   || variable == null
                   || !isIdentifier(inputName, variable.getLanguage())) {
                 final String[] names =
                     suggestNames(isReplaceAllOccurrences(), getLocalVariable());
                 ApplicationManager.getApplication()
                     .runWriteAction(
                         () ->
                             myEditor
                                 .getDocument()
                                 .replaceString(
                                     range.getStartOffset(), range.getEndOffset(), names[0]));
               }
             }
             templateState.gotoEnd(true);
             try {
               myShouldSelect = false;
               startInplaceIntroduceTemplate();
             } finally {
               myShouldSelect = true;
             }
           } finally {
             myEditor.putUserData(INTRODUCE_RESTART, false);
           }
         }
         updateTitle(getVariable());
       };
   CommandProcessor.getInstance()
       .executeCommand(myProject, restartTemplateRunnable, getCommandName(), getCommandName());
 }
  public void performAction(IntroduceOperation operation) {
    final PsiFile file = operation.getFile();
    if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) {
      return;
    }
    final Editor editor = operation.getEditor();
    if (editor.getSettings().isVariableInplaceRenameEnabled()) {
      final TemplateState templateState =
          TemplateManagerImpl.getTemplateState(operation.getEditor());
      if (templateState != null && !templateState.isFinished()) {
        return;
      }
    }

    PsiElement element1 = null;
    PsiElement element2 = null;
    final SelectionModel selectionModel = editor.getSelectionModel();
    boolean singleElementSelection = false;
    if (selectionModel.hasSelection()) {
      element1 = file.findElementAt(selectionModel.getSelectionStart());
      element2 = file.findElementAt(selectionModel.getSelectionEnd() - 1);
      if (element1 instanceof PsiWhiteSpace) {
        int startOffset = element1.getTextRange().getEndOffset();
        element1 = file.findElementAt(startOffset);
      }
      if (element2 instanceof PsiWhiteSpace) {
        int endOffset = element2.getTextRange().getStartOffset();
        element2 = file.findElementAt(endOffset - 1);
      }
      if (element1 == element2) {
        singleElementSelection = true;
      }
    } else {
      if (smartIntroduce(operation)) {
        return;
      }
      final CaretModel caretModel = editor.getCaretModel();
      final Document document = editor.getDocument();
      int lineNumber = document.getLineNumber(caretModel.getOffset());
      if ((lineNumber >= 0) && (lineNumber < document.getLineCount())) {
        element1 = file.findElementAt(document.getLineStartOffset(lineNumber));
        element2 = file.findElementAt(document.getLineEndOffset(lineNumber) - 1);
      }
    }
    final Project project = operation.getProject();
    if (element1 == null || element2 == null) {
      showCannotPerformError(project, editor);
      return;
    }

    element1 = PyRefactoringUtil.getSelectedExpression(project, file, element1, element2);
    if (element1 == null) {
      showCannotPerformError(project, editor);
      return;
    }

    if (singleElementSelection && element1 instanceof PyStringLiteralExpression) {
      final PyStringLiteralExpression literal = (PyStringLiteralExpression) element1;
      // Currently introduce for substrings of a multi-part string literals is not supported
      if (literal.getStringNodes().size() > 1) {
        showCannotPerformError(project, editor);
        return;
      }
      final int offset = element1.getTextOffset();
      final TextRange selectionRange =
          TextRange.create(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
      final TextRange elementRange = element1.getTextRange();
      if (!elementRange.equals(selectionRange) && elementRange.contains(selectionRange)) {
        final TextRange innerRange = literal.getStringValueTextRange();
        final TextRange intersection = selectionRange.shiftRight(-offset).intersection(innerRange);
        final TextRange finalRange = intersection != null ? intersection : selectionRange;
        final String text = literal.getText();
        if (getFormatValueExpression(literal) != null && breaksStringFormatting(text, finalRange)
            || getNewStyleFormatValueExpression(literal) != null
                && breaksNewStyleStringFormatting(text, finalRange)
            || breaksStringEscaping(text, finalRange)) {
          showCannotPerformError(project, editor);
          return;
        }
        element1.putUserData(
            PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE, Pair.create(element1, finalRange));
      }
    }

    if (!checkIntroduceContext(file, editor, element1)) {
      return;
    }
    operation.setElement(element1);
    performActionOnElement(operation);
  }