@Nullable
  public Runnable startNonCustomTemplates(
      final Map<TemplateImpl, String> template2argument,
      final Editor editor,
      @Nullable final PairProcessor<String, String> processor) {
    final int caretOffset = editor.getCaretModel().getOffset();
    final Document document = editor.getDocument();
    final CharSequence text = document.getCharsSequence();

    if (template2argument == null || template2argument.isEmpty()) {
      return null;
    }
    if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) {
      return null;
    }

    return () -> {
      if (template2argument.size() == 1) {
        TemplateImpl template = template2argument.keySet().iterator().next();
        String argument = template2argument.get(template);
        int templateStart = getTemplateStart(template, argument, caretOffset, text);
        startTemplateWithPrefix(editor, template, templateStart, processor, argument);
      } else {
        ListTemplatesHandler.showTemplatesLookup(myProject, editor, template2argument);
      }
    };
  }
  private BeforeAfter<Integer> getEditorLines() {
    final Editor editor = ((DiffPanelImpl) getCurrentPanel()).getEditor1();
    Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
    final int offset = editor.getScrollingModel().getVerticalScrollOffset();

    int leftPixels = offset % editor.getLineHeight();

    final Point start = visibleArea.getLocation();
    final LogicalPosition startLp = editor.xyToLogicalPosition(start);
    final Point location = new Point(start.x + visibleArea.width, start.y + visibleArea.height);
    final LogicalPosition lp = editor.xyToLogicalPosition(location);

    int curStartLine =
        startLp.line == (editor.getDocument().getLineCount() - 1)
            ? startLp.line
            : (startLp.line + 1);
    int cutEndLine = lp.line == 0 ? 0 : lp.line - 1;

    boolean commonPartOk = leftPixels == 0 || startLp.line == lp.line;
    return new BeforeAfter<Integer>(
        commonPartOk && startLp.softWrapLinesOnCurrentLogicalLine == 0
            ? startLp.line
            : curStartLine,
        commonPartOk && lp.softWrapLinesOnCurrentLogicalLine == 0 ? lp.line : cutEndLine);
    /*if (leftPixels == 0 || startLp.line == lp.line) {
      return new BeforeAfter<Integer>(startLp.line, lp.line);
    } else {
      return new BeforeAfter<Integer>(curStartLine, cutEndLine);
    }*/
  }
 public void startTemplateWithPrefix(
     final Editor editor,
     final TemplateImpl template,
     final int templateStart,
     @Nullable final PairProcessor<String, String> processor,
     @Nullable final String argument) {
   final int caretOffset = editor.getCaretModel().getOffset();
   final TemplateState templateState = initTemplateState(editor);
   CommandProcessor commandProcessor = CommandProcessor.getInstance();
   commandProcessor.executeCommand(
       myProject,
       () -> {
         editor.getDocument().deleteString(templateStart, caretOffset);
         editor.getCaretModel().moveToOffset(templateStart);
         editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
         editor.getSelectionModel().removeSelection();
         Map<String, String> predefinedVarValues = null;
         if (argument != null) {
           predefinedVarValues = new HashMap<String, String>();
           predefinedVarValues.put(TemplateImpl.ARG, argument);
         }
         templateState.start(template, processor, predefinedVarValues);
       },
       CodeInsightBundle.message("insert.code.template.command"),
       null);
 }
 @Override
 public boolean startTemplate(@NotNull Editor editor, char shortcutChar) {
   Runnable runnable = prepareTemplate(editor, shortcutChar, null);
   if (runnable != null) {
     PsiDocumentManager.getInstance(myProject).commitDocument(editor.getDocument());
     runnable.run();
   }
   return runnable != null;
 }
  /**
   * 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;
  }
 private void setStructureViewSelectionFromPropertiesFile(@NotNull Editor propertiesFileEditor) {
   int line = propertiesFileEditor.getCaretModel().getLogicalPosition().line;
   Document document = propertiesFileEditor.getDocument();
   if (line >= document.getLineCount()) {
     return;
   }
   final String propertyName = getPropertyName(document, line);
   if (propertyName == null) {
     return;
   }
   setStructureViewSelection(propertyName);
 }
  private void setPropertiesFileSelectionFromStructureView(@NotNull Editor propertiesFileEditor) {
    String selectedPropertyName = getSelectedPropertyName();
    if (selectedPropertyName == null) {
      return;
    }

    Document document = propertiesFileEditor.getDocument();
    for (int i = 0; i < document.getLineCount(); i++) {
      String propertyName = getPropertyName(document, i);
      if (selectedPropertyName.equals(propertyName)) {
        propertiesFileEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, 0));
        return;
      }
    }
  }
  @Nullable
  public Runnable prepareTemplate(
      final Editor editor,
      char shortcutChar,
      @Nullable final PairProcessor<String, String> processor) {
    if (editor.getSelectionModel().hasSelection()) {
      return null;
    }

    PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
    if (file == null) return null;

    Map<TemplateImpl, String> template2argument =
        findMatchingTemplates(file, editor, shortcutChar, TemplateSettings.getInstance());

    List<CustomLiveTemplate> customCandidates =
        ContainerUtil.findAll(
            CustomLiveTemplate.EP_NAME.getExtensions(),
            customLiveTemplate ->
                shortcutChar == customLiveTemplate.getShortcut()
                    && (editor.getCaretModel().getCaretCount() <= 1
                        || supportsMultiCaretMode(customLiveTemplate)));
    if (!customCandidates.isEmpty()) {
      int caretOffset = editor.getCaretModel().getOffset();
      PsiFile fileCopy = insertDummyIdentifierIfNeeded(file, caretOffset, caretOffset, "");
      Document document = editor.getDocument();

      for (final CustomLiveTemplate customLiveTemplate : customCandidates) {
        if (isApplicable(customLiveTemplate, editor, fileCopy)) {
          final String key =
              customLiveTemplate.computeTemplateKey(new CustomTemplateCallback(editor, fileCopy));
          if (key != null) {
            int offsetBeforeKey = caretOffset - key.length();
            CharSequence text = document.getImmutableCharSequence();
            if (template2argument == null
                || !containsTemplateStartingBefore(
                    template2argument, offsetBeforeKey, caretOffset, text)) {
              return () -> customLiveTemplate.expand(key, new CustomTemplateCallback(editor, file));
            }
          }
        }
      }
    }

    return startNonCustomTemplates(template2argument, editor, processor);
  }
예제 #9
0
    @Override
    public RelativePoint recalculateLocation(final Balloon object) {
      FindResult cursor = mySearchResults.getCursor();
      if (cursor == null) return null;
      final TextRange cur = cursor;
      int startOffset = cur.getStartOffset();
      int endOffset = cur.getEndOffset();

      if (startOffset >= myEditor.getDocument().getTextLength()) {
        if (!object.isDisposed()) {
          requestBalloonHiding(object);
        }
        return null;
      }
      if (!SearchResults.insideVisibleArea(myEditor, cur)) {
        requestBalloonHiding(object);

        VisibleAreaListener visibleAreaListener =
            new VisibleAreaListener() {
              @Override
              public void visibleAreaChanged(VisibleAreaEvent e) {
                if (SearchResults.insideVisibleArea(myEditor, cur)) {
                  showReplacementPreview();
                  final VisibleAreaListener visibleAreaListener = this;
                  final boolean remove = myVisibleAreaListenersToRemove.remove(visibleAreaListener);
                  if (remove) {
                    myEditor.getScrollingModel().removeVisibleAreaListener(visibleAreaListener);
                  }
                }
              }
            };
        myEditor.getScrollingModel().addVisibleAreaListener(visibleAreaListener);
        myVisibleAreaListenersToRemove.add(visibleAreaListener);
      }

      Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset));
      Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset));
      Point point = new Point((startPoint.x + endPoint.x) / 2, startPoint.y);

      return new RelativePoint(myEditor.getContentComponent(), point);
    }
  public Map<TemplateImpl, String> findMatchingTemplates(
      final PsiFile file,
      Editor editor,
      @Nullable Character shortcutChar,
      TemplateSettings templateSettings) {
    final Document document = editor.getDocument();
    CharSequence text = document.getCharsSequence();
    final int caretOffset = editor.getCaretModel().getOffset();

    List<TemplateImpl> candidatesWithoutArgument =
        findMatchingTemplates(text, caretOffset, shortcutChar, templateSettings, false);

    int argumentOffset = passArgumentBack(text, caretOffset);
    String argument = null;
    if (argumentOffset >= 0) {
      argument = text.subSequence(argumentOffset, caretOffset).toString();
      if (argumentOffset > 0 && text.charAt(argumentOffset - 1) == ' ') {
        if (argumentOffset - 2 >= 0
            && Character.isJavaIdentifierPart(text.charAt(argumentOffset - 2))) {
          argumentOffset--;
        }
      }
    }
    List<TemplateImpl> candidatesWithArgument =
        findMatchingTemplates(text, argumentOffset, shortcutChar, templateSettings, true);

    if (candidatesWithArgument.isEmpty() && candidatesWithoutArgument.isEmpty()) {
      return null;
    }

    candidatesWithoutArgument =
        filterApplicableCandidates(file, caretOffset, candidatesWithoutArgument);
    candidatesWithArgument =
        filterApplicableCandidates(file, argumentOffset, candidatesWithArgument);
    Map<TemplateImpl, String> candidate2Argument = new HashMap<TemplateImpl, String>();
    addToMap(candidate2Argument, candidatesWithoutArgument, null);
    addToMap(candidate2Argument, candidatesWithArgument, argument);
    return candidate2Argument;
  }
  private void writeEditorPropertyValue(
      final Editor editor,
      final PropertiesFile propertiesFile,
      final @Nullable String propertyName) {
    final String currentValue = editor.getDocument().getText();
    final String currentSelectedProperty =
        propertyName == null ? getSelectedPropertyName() : propertyName;
    if (currentSelectedProperty == null) {
      return;
    }

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                WriteCommandAction.runWriteCommandAction(
                    myProject,
                    new Runnable() {
                      @Override
                      public void run() {
                        final IProperty property =
                            propertiesFile.findPropertyByKey(currentSelectedProperty);
                        try {
                          if (property == null) {
                            propertiesFile.addProperty(currentSelectedProperty, currentValue);
                          } else {
                            property.setValue(currentValue);
                          }
                        } catch (final IncorrectOperationException e) {
                          LOG.error(e);
                        }
                      }
                    });
              }
            });
  }
예제 #12
0
 public IndentsPass(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
   super(project, editor.getDocument(), false);
   myEditor = (EditorEx) editor;
   myFile = file;
 }
예제 #13
0
 @Override
 public void editorChanged(SearchResults sr, Editor oldEditor) {
   removeFromEditor();
   oldEditor.getDocument().removeDocumentListener(this);
   mySearchResults.getEditor().getDocument().addDocumentListener(this);
 }
예제 #14
0
  private void dumpEditorMarkupAndSelection(PrintStream dumpStream) {
    dumpStream.println(mySearchResults.getFindModel());
    if (myReplacementPreviewText != null) {
      dumpStream.println("--");
      dumpStream.println("Replacement Preview: " + myReplacementPreviewText);
    }
    dumpStream.println("--");

    Editor editor = mySearchResults.getEditor();

    RangeHighlighter[] highlighters = editor.getMarkupModel().getAllHighlighters();
    List<Pair<Integer, Character>> ranges = new ArrayList<Pair<Integer, Character>>();
    for (RangeHighlighter highlighter : highlighters) {
      ranges.add(new Pair<Integer, Character>(highlighter.getStartOffset(), '['));
      ranges.add(new Pair<Integer, Character>(highlighter.getEndOffset(), ']'));
    }

    SelectionModel selectionModel = editor.getSelectionModel();

    if (selectionModel.getSelectionStart() != selectionModel.getSelectionEnd()) {
      ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionStart(), '<'));
      ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionEnd(), '>'));
    }
    ranges.add(new Pair<Integer, Character>(-1, '\n'));
    ranges.add(new Pair<Integer, Character>(editor.getDocument().getTextLength() + 1, '\n'));
    ContainerUtil.sort(
        ranges,
        new Comparator<Pair<Integer, Character>>() {
          @Override
          public int compare(Pair<Integer, Character> pair, Pair<Integer, Character> pair2) {
            int res = pair.first - pair2.first;
            if (res == 0) {

              Character c1 = pair.second;
              Character c2 = pair2.second;
              if (c1 == '<' && c2 == '[') {
                return 1;
              } else if (c1 == '[' && c2 == '<') {
                return -1;
              }
              return c1.compareTo(c2);
            }
            return res;
          }
        });

    Document document = editor.getDocument();
    for (int i = 0; i < ranges.size() - 1; ++i) {
      Pair<Integer, Character> pair = ranges.get(i);
      Pair<Integer, Character> pair1 = ranges.get(i + 1);
      dumpStream.print(
          pair.second
              + document.getText(
                  TextRange.create(
                      Math.max(pair.first, 0), Math.min(pair1.first, document.getTextLength()))));
    }
    dumpStream.println("\n--");

    if (NotFound) {
      dumpStream.println("Not Found");
      dumpStream.println("--");
      NotFound = false;
    }

    for (RangeHighlighter highlighter : highlighters) {
      dumpStream.println(highlighter + " : " + highlighter.getTextAttributes());
    }
    dumpStream.println("------------");
  }