Search in sources :

Example 26 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class ShowIntentionsPass method addAvailableFixesForGroups.

private static void addAvailableFixesForGroups(@NotNull HighlightInfo info, @NotNull Editor editor, @NotNull PsiFile file, @NotNull List<HighlightInfo.IntentionActionDescriptor> outList, int group, int offset) {
    if (info.quickFixActionMarkers == null)
        return;
    if (group != -1 && group != info.getGroup())
        return;
    boolean fixRangeIsNotEmpty = !info.getFixTextRange().isEmpty();
    Editor injectedEditor = null;
    PsiFile injectedFile = null;
    for (Pair<HighlightInfo.IntentionActionDescriptor, RangeMarker> pair : info.quickFixActionMarkers) {
        HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
        RangeMarker range = pair.second;
        if (!range.isValid() || fixRangeIsNotEmpty && isEmpty(range))
            continue;
        if (DumbService.isDumb(file.getProject()) && !DumbService.isDumbAware(actionInGroup.getAction())) {
            continue;
        }
        int start = range.getStartOffset();
        int end = range.getEndOffset();
        final Project project = file.getProject();
        if (start > offset || offset > end) {
            continue;
        }
        Editor editorToUse;
        PsiFile fileToUse;
        if (info.isFromInjection()) {
            if (injectedEditor == null) {
                injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, offset);
                injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
            }
            editorToUse = injectedEditor;
            fileToUse = injectedFile;
        } else {
            editorToUse = editor;
            fileToUse = file;
        }
        if (actionInGroup.getAction().isAvailable(project, editorToUse, fileToUse)) {
            outList.add(actionInGroup);
        }
    }
}
Also used : Project(com.intellij.openapi.project.Project) PsiFile(com.intellij.psi.PsiFile) RangeMarker(com.intellij.openapi.editor.RangeMarker) Editor(com.intellij.openapi.editor.Editor)

Example 27 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class Bookmark method getLine.

public int getLine() {
    int targetLine = myTarget.getLine();
    if (targetLine == -1)
        return targetLine;
    //What user sees in gutter
    RangeHighlighterEx highlighter = findMyHighlighter();
    if (highlighter != null && highlighter.isValid()) {
        Document document = getDocument();
        if (document != null) {
            return document.getLineNumber(highlighter.getStartOffset());
        }
    }
    RangeMarker marker = myTarget.getRangeMarker();
    if (marker != null && marker.isValid()) {
        Document document = marker.getDocument();
        return document.getLineNumber(marker.getStartOffset());
    }
    return targetLine;
}
Also used : RangeHighlighterEx(com.intellij.openapi.editor.ex.RangeHighlighterEx) RangeMarker(com.intellij.openapi.editor.RangeMarker) Document(com.intellij.openapi.editor.Document)

Example 28 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class PostprocessReformattingAspect method normalizeAndReorderPostponedActions.

@NotNull
private List<PostponedAction> normalizeAndReorderPostponedActions(@NotNull Set<PostprocessFormattingTask> rangesToProcess, @NotNull Document document) {
    final List<PostprocessFormattingTask> freeFormattingActions = new ArrayList<>();
    final List<ReindentTask> indentActions = new ArrayList<>();
    PostprocessFormattingTask accumulatedTask = null;
    Iterator<PostprocessFormattingTask> iterator = rangesToProcess.iterator();
    while (iterator.hasNext()) {
        final PostprocessFormattingTask currentTask = iterator.next();
        if (accumulatedTask == null) {
            accumulatedTask = currentTask;
            iterator.remove();
        } else if (accumulatedTask.getStartOffset() > currentTask.getEndOffset() || accumulatedTask.getStartOffset() == currentTask.getEndOffset() && !canStickActionsTogether(accumulatedTask, currentTask)) {
            // action can be pushed
            if (accumulatedTask instanceof ReindentTask) {
                indentActions.add((ReindentTask) accumulatedTask);
            } else {
                freeFormattingActions.add(accumulatedTask);
            }
            accumulatedTask = currentTask;
            iterator.remove();
        } else if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReindentTask) {
            // split accumulated reformat range into two
            if (accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
                final RangeMarker endOfRange = document.createRangeMarker(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
                // add heading reformat part
                rangesToProcess.add(new ReformatTask(endOfRange));
                // and manage heading whitespace because formatter does not edit it in previous action
                iterator = rangesToProcess.iterator();
                //noinspection StatementWithEmptyBody
                while (iterator.next().getRange() != currentTask.getRange()) ;
            }
            final RangeMarker rangeToProcess = document.createRangeMarker(currentTask.getEndOffset(), accumulatedTask.getEndOffset());
            freeFormattingActions.add(new ReformatWithHeadingWhitespaceTask(rangeToProcess));
            accumulatedTask = currentTask;
            iterator.remove();
        } else {
            if (!(accumulatedTask instanceof ReindentTask)) {
                iterator.remove();
                boolean withLeadingWhitespace = accumulatedTask instanceof ReformatWithHeadingWhitespaceTask;
                if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReformatWithHeadingWhitespaceTask && accumulatedTask.getStartOffset() == currentTask.getStartOffset()) {
                    withLeadingWhitespace = true;
                } else if (accumulatedTask instanceof ReformatWithHeadingWhitespaceTask && currentTask instanceof ReformatTask && accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
                    withLeadingWhitespace = false;
                }
                int newStart = Math.min(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
                int newEnd = Math.max(accumulatedTask.getEndOffset(), currentTask.getEndOffset());
                RangeMarker rangeMarker;
                if (accumulatedTask.getStartOffset() == newStart && accumulatedTask.getEndOffset() == newEnd) {
                    rangeMarker = accumulatedTask.getRange();
                } else if (currentTask.getStartOffset() == newStart && currentTask.getEndOffset() == newEnd) {
                    rangeMarker = currentTask.getRange();
                } else {
                    rangeMarker = document.createRangeMarker(newStart, newEnd);
                }
                if (withLeadingWhitespace) {
                    accumulatedTask = new ReformatWithHeadingWhitespaceTask(rangeMarker);
                } else {
                    accumulatedTask = new ReformatTask(rangeMarker);
                }
            } else if (currentTask instanceof ReindentTask) {
                iterator.remove();
            }
        // TODO[ik]: need to be fixed to correctly process indent inside indent
        }
    }
    if (accumulatedTask != null) {
        if (accumulatedTask instanceof ReindentTask) {
            indentActions.add((ReindentTask) accumulatedTask);
        } else {
            freeFormattingActions.add(accumulatedTask);
        }
    }
    final List<PostponedAction> result = new ArrayList<>();
    Collections.reverse(freeFormattingActions);
    Collections.reverse(indentActions);
    if (!freeFormattingActions.isEmpty()) {
        FormatTextRanges ranges = new FormatTextRanges();
        for (PostprocessFormattingTask action : freeFormattingActions) {
            TextRange range = TextRange.create(action);
            ranges.add(range, action instanceof ReformatWithHeadingWhitespaceTask);
        }
        result.add(new ReformatRangesAction(ranges));
    }
    if (!indentActions.isEmpty()) {
        ReindentRangesAction reindentRangesAction = new ReindentRangesAction();
        for (ReindentTask action : indentActions) {
            reindentRangesAction.add(action.getRange(), action.getOldIndent());
        }
        result.add(reindentRangesAction);
    }
    return result;
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) FormatTextRanges(com.intellij.formatting.FormatTextRanges) NotNull(org.jetbrains.annotations.NotNull)

Example 29 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class JavaCompletionUtil method insertTemporary.

public static RangeMarker insertTemporary(final int endOffset, final Document document, final String temporary) {
    final CharSequence chars = document.getCharsSequence();
    final int length = chars.length();
    final RangeMarker toDelete;
    if (endOffset < length && Character.isJavaIdentifierPart(chars.charAt(endOffset))) {
        document.insertString(endOffset, temporary);
        toDelete = document.createRangeMarker(endOffset, endOffset + 1);
    } else if (endOffset >= length) {
        toDelete = document.createRangeMarker(length, length);
    } else {
        toDelete = document.createRangeMarker(endOffset, endOffset);
    }
    toDelete.setGreedyToLeft(true);
    toDelete.setGreedyToRight(true);
    return toDelete;
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) ElementClassHint(com.intellij.psi.scope.ElementClassHint) NameHint(com.intellij.psi.scope.NameHint)

Example 30 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class JavaQualifiedNameProvider method insertQualifiedName.

public void insertQualifiedName(String fqn, final PsiElement element, final Editor editor, final Project project) {
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    Document document = editor.getDocument();
    final PsiFile file = documentManager.getPsiFile(document);
    final int offset = editor.getCaretModel().getOffset();
    PsiElement elementAtCaret = file.findElementAt(offset);
    fqn = fqn.replace('#', '.');
    String toInsert;
    String suffix = "";
    if (!(element instanceof PsiMember)) {
        toInsert = fqn;
    } else if (elementAtCaret != null && (element instanceof PsiMethod || element instanceof PsiField) && PsiUtil.isInsideJavadocComment(elementAtCaret)) {
        // use fqn#methodName(ParamType)
        PsiMember member = (PsiMember) element;
        PsiClass aClass = member.getContainingClass();
        String className = aClass == null ? "" : aClass.getQualifiedName();
        toInsert = className == null ? "" : className;
        if (toInsert.length() != 0)
            toInsert += "#";
        toInsert += member.getName();
        if (member instanceof PsiMethod) {
            toInsert += getParameterString((PsiMethod) member, true);
        }
    } else if (elementAtCaret == null || PsiTreeUtil.getNonStrictParentOfType(elementAtCaret, PsiLiteralExpression.class, PsiComment.class) != null || PsiTreeUtil.getNonStrictParentOfType(elementAtCaret, PsiJavaFile.class) == null) {
        toInsert = fqn;
    } else {
        PsiMember targetElement = (PsiMember) element;
        toInsert = targetElement.getName();
        if (targetElement instanceof PsiMethod) {
            if (!fqn.contains("(")) {
                suffix = "()";
            }
            if (((PsiMethod) targetElement).isConstructor()) {
                targetElement = targetElement.getContainingClass();
                fqn = StringUtil.getPackageName(fqn);
            }
        } else if (targetElement instanceof PsiClass) {
            if (isAfterNew(file, elementAtCaret)) {
                // pasting reference to default constructor of the class after new
                suffix = "()";
            } else if (toInsert != null && toInsert.length() != 0 && Character.isJavaIdentifierPart(toInsert.charAt(toInsert.length() - 1)) && Character.isJavaIdentifierPart(elementAtCaret.getText().charAt(0))) {
                //separate identifiers with space
                suffix = " ";
            }
        }
        final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
        final PsiExpression expression;
        try {
            expression = factory.createExpressionFromText(toInsert + suffix, elementAtCaret);
            final PsiReferenceExpression referenceExpression = expression instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression) expression).getMethodExpression() : expression instanceof PsiReferenceExpression ? (PsiReferenceExpression) expression : null;
            if (referenceExpression == null || !referenceExpression.isValid()) {
                toInsert = fqn;
            } else if (!isReferencedTo(referenceExpression, targetElement)) {
                try {
                    referenceExpression.bindToElement(targetElement);
                } catch (IncorrectOperationException e) {
                // failed to bind
                }
                if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
                    toInsert = fqn;
                }
            }
        } catch (IncorrectOperationException ignored) {
        }
    }
    if (toInsert == null)
        toInsert = "";
    document.insertString(offset, toInsert + suffix);
    documentManager.commitAllDocuments();
    int endOffset = offset + toInsert.length() + suffix.length();
    RangeMarker rangeMarker = document.createRangeMarker(endOffset, endOffset);
    elementAtCaret = file.findElementAt(offset);
    if (elementAtCaret != null && elementAtCaret.isValid()) {
        try {
            shortenReference(elementAtCaret);
        } catch (IncorrectOperationException e) {
            LOG.error(e);
        }
    }
    CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file);
    try {
        CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
    } catch (IncorrectOperationException e) {
        LOG.error(e);
    }
    int caretOffset = rangeMarker.getEndOffset();
    if (element instanceof PsiMethod && ((PsiMethod) element).getParameterList().getParametersCount() != 0 && StringUtil.endsWithChar(suffix, ')')) {
        caretOffset--;
    }
    editor.getCaretModel().moveToOffset(caretOffset);
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) Document(com.intellij.openapi.editor.Document) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Aggregations

RangeMarker (com.intellij.openapi.editor.RangeMarker)111 Document (com.intellij.openapi.editor.Document)33 TextRange (com.intellij.openapi.util.TextRange)20 Project (com.intellij.openapi.project.Project)19 PsiFile (com.intellij.psi.PsiFile)14 PsiElement (com.intellij.psi.PsiElement)13 IncorrectOperationException (com.intellij.util.IncorrectOperationException)13 Editor (com.intellij.openapi.editor.Editor)11 Nullable (org.jetbrains.annotations.Nullable)11 NotNull (org.jetbrains.annotations.NotNull)10 Template (com.intellij.codeInsight.template.Template)8 TemplateBuilderImpl (com.intellij.codeInsight.template.TemplateBuilderImpl)7 TemplateEditingAdapter (com.intellij.codeInsight.template.TemplateEditingAdapter)6 PsiDocumentManager (com.intellij.psi.PsiDocumentManager)6 RangeHighlighterEx (com.intellij.openapi.editor.ex.RangeHighlighterEx)5 THashMap (gnu.trove.THashMap)5 GutterMark (com.intellij.codeInsight.daemon.GutterMark)4 HighlightSeverity (com.intellij.lang.annotation.HighlightSeverity)4 ApplicationManager (com.intellij.openapi.application.ApplicationManager)4 RelativePoint (com.intellij.ui.awt.RelativePoint)4