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");
  }
  @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);
      }
    }
  }
  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());
   }
 }
  /**
   * Begins the in-place refactoring operation.
   *
   * @return true if the in-place refactoring was successfully started, false if it failed to start
   *     and a dialog should be shown instead.
   */
  public boolean startInplaceIntroduceTemplate() {
    final boolean replaceAllOccurrences = isReplaceAllOccurrences();
    final Ref<Boolean> result = new Ref<>();
    CommandProcessor.getInstance()
        .executeCommand(
            myProject,
            () -> {
              final String[] names = suggestNames(replaceAllOccurrences, getLocalVariable());
              final V variable = createFieldToStartTemplateOn(replaceAllOccurrences, names);
              boolean started = false;
              if (variable != null) {
                int caretOffset = getCaretOffset();
                myEditor.getCaretModel().moveToOffset(caretOffset);
                myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);

                final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<>();
                nameSuggestions.add(variable.getName());
                nameSuggestions.addAll(Arrays.asList(names));
                initOccurrencesMarkers();
                setElementToRename(variable);
                updateTitle(getVariable());
                started = super.performInplaceRefactoring(nameSuggestions);
                if (started) {
                  onRenameTemplateStarted();
                  myDocumentAdapter =
                      new DocumentAdapter() {
                        @Override
                        public void documentChanged(DocumentEvent e) {
                          if (myPreview == null) return;
                          final TemplateState templateState =
                              TemplateManagerImpl.getTemplateState(myEditor);
                          if (templateState != null) {
                            final TextResult value =
                                templateState.getVariableValue(
                                    InplaceRefactoring.PRIMARY_VARIABLE_NAME);
                            if (value != null) {
                              updateTitle(getVariable(), value.getText());
                            }
                          }
                        }
                      };
                  myEditor.getDocument().addDocumentListener(myDocumentAdapter);
                  updateTitle(getVariable());
                  if (TemplateManagerImpl.getTemplateState(myEditor) != null) {
                    myEditor.putUserData(ACTIVE_INTRODUCE, this);
                  }
                }
              }
              result.set(started);
              if (!started) {
                finish(true);
              }
            },
            getCommandName(),
            getCommandName());
    return result.get();
  }
 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);
 }
 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());
 }
 @Override
 public void finish(boolean success) {
   myFinished = true;
   final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
   if (templateState != null) {
     myEditor.putUserData(ACTIVE_INTRODUCE, null);
   }
   if (myDocumentAdapter != null) {
     myEditor.getDocument().removeDocumentListener(myDocumentAdapter);
   }
   if (myBalloon == null) {
     releaseIfNotRestart();
   }
   super.finish(success);
   if (success) {
     PsiDocumentManager.getInstance(myProject).commitAllDocuments();
     final V variable = getVariable();
     if (variable == null) {
       return;
     }
     restoreState(variable);
   }
 }
  @Override
  public void actionPerformed(AnActionEvent e) {
    DataContext dataContext = e.getDataContext();
    final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
    PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext);

    final Project project = file.getProject();
    PsiDocumentManager.getInstance(project).commitAllDocuments();

    final TextRange selection =
        new TextRange(
            editor.getSelectionModel().getSelectionStart(),
            editor.getSelectionModel().getSelectionEnd());
    PsiElement current = file.findElementAt(selection.getStartOffset());
    int startOffset = selection.getStartOffset();
    while (current instanceof PsiWhiteSpace) {
      current = current.getNextSibling();
      if (current == null) break;
      startOffset = current.getTextRange().getStartOffset();
    }

    if (startOffset >= selection.getEndOffset()) startOffset = selection.getStartOffset();

    final PsiElement[] psiElements =
        PsiTreeUtil.collectElements(
            file,
            new PsiElementFilter() {
              @Override
              public boolean isAccepted(PsiElement element) {
                return selection.contains(element.getTextRange())
                    && element.getReferences().length > 0;
              }
            });

    final Document document =
        EditorFactory.getInstance()
            .createDocument(
                editor.getDocument().getText().substring(startOffset, selection.getEndOffset()));
    final boolean isXml = file.getLanguage().is(StdLanguages.XML);
    final int offsetDelta = startOffset;
    new WriteCommandAction.Simple(project, (String) null) {
      @Override
      protected void run() throws Throwable {
        Map<RangeMarker, String> rangeToText = new HashMap<RangeMarker, String>();

        for (PsiElement element : psiElements) {
          for (PsiReference reference : element.getReferences()) {
            if (!(reference instanceof PsiQualifiedReference)
                || ((PsiQualifiedReference) reference).getQualifier() == null) {
              String canonicalText = reference.getCanonicalText();
              LOG.assertTrue(canonicalText != null, reference.getClass());
              TextRange referenceRange = reference.getRangeInElement();
              final TextRange elementTextRange = element.getTextRange();
              LOG.assertTrue(elementTextRange != null, elementTextRange);
              final TextRange range =
                  elementTextRange.cutOut(referenceRange).shiftRight(-offsetDelta);
              final String oldText = document.getText(range);
              // workaround for Java references: canonicalText contains generics, and we need to cut
              // them off because otherwise
              // they will be duplicated
              int pos = canonicalText.indexOf('<');
              if (pos > 0 && !oldText.contains("<")) {
                canonicalText = canonicalText.substring(0, pos);
              }
              if (isXml) { // strip namespace prefixes
                pos = canonicalText.lastIndexOf(':');
                if (pos >= 0 && pos < canonicalText.length() - 1 && !oldText.contains(":")) {
                  canonicalText = canonicalText.substring(pos + 1);
                }
              }
              if (!canonicalText.equals(oldText)) {
                rangeToText.put(document.createRangeMarker(range), canonicalText);
              }
            }
          }
        }

        for (Map.Entry<RangeMarker, String> entry : rangeToText.entrySet()) {
          document.replaceString(
              entry.getKey().getStartOffset(), entry.getKey().getEndOffset(), entry.getValue());
        }
      }
    }.execute();

    final TemplateImpl template =
        new TemplateImpl(
            TemplateListPanel.ABBREVIATION, document.getText(), TemplateSettings.USER_GROUP_NAME);
    template.setToReformat(true);

    PsiFile copy;
    AccessToken token = WriteAction.start();
    try {
      copy = TemplateManagerImpl.insertDummyIdentifier(editor, file);
    } finally {
      token.finish();
    }
    Set<TemplateContextType> applicable =
        TemplateManagerImpl.getApplicableContextTypes(copy, startOffset);

    for (TemplateContextType contextType : TemplateManagerImpl.getAllContextTypes()) {
      template.getTemplateContext().setEnabled(contextType, applicable.contains(contextType));
    }

    final LiveTemplatesConfigurable configurable = new LiveTemplatesConfigurable();
    ShowSettingsUtil.getInstance()
        .editConfigurable(
            project, configurable, () -> configurable.getTemplateListPanel().addTemplate(template));
  }
 @Override
 protected boolean isValidForFile(
     @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
   return EmmetOptions.getInstance().isEmmetEnabled()
       && TemplateManagerImpl.isApplicable(new ZenCodingTemplate(), editor, file, true);
 }
  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);
  }
 public void testSurroundExpressionWithElseIfElse() {
   TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
   doTest(new JavaWithIfElseExpressionSurrounder());
 }
 public void testSurroundExpressionWithNotForBoxedBooleans() {
   TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
   doTest(new JavaWithNotSurrounder());
 }
 public void testSurroundWithNotNullCheck() {
   TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
   doTest(new JavaWithNullCheckSurrounder());
 }
 public void testSurroundAssignmentWithCast() {
   TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
   doTest(new JavaWithCastSurrounder());
 }