@Override
 @NotNull
 public RangeMarker createRangeMarker(final int startOffset, final int endOffset) {
   ProperTextRange hostRange = injectedToHost(new ProperTextRange(startOffset, endOffset));
   RangeMarker hostMarker = myDelegate.createRangeMarker(hostRange);
   int startShift = Math.max(0, hostToInjected(hostRange.getStartOffset()) - startOffset);
   int endShift = Math.max(0, endOffset - hostToInjected(hostRange.getEndOffset()) - startShift);
   return new RangeMarkerWindow(this, (RangeMarkerEx) hostMarker, startShift, endShift);
 }
  void repaint(int startOffset, int endOffset) {
    markDirtied();

    ProperTextRange range = offsetToYPosition(startOffset, endOffset);

    myEditor
        .getVerticalScrollBar()
        .repaint(0, range.getStartOffset(), PREFERRED_WIDTH, range.getLength() + getMinHeight());
  }
 private void commitToOriginalInner() {
   final String text = myNewDocument.getText();
   final Map<
           PsiLanguageInjectionHost,
           Set<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>>>
       map =
           ContainerUtil.classify(
               myMarkers.iterator(),
               new Convertor<
                   Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>,
                   PsiLanguageInjectionHost>() {
                 @Override
                 public PsiLanguageInjectionHost convert(
                     final Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> o) {
                   final PsiElement element = o.third.getElement();
                   return (PsiLanguageInjectionHost) element;
                 }
               });
   PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
   documentManager.commitDocument(myOrigDocument); // commit here and after each manipulator update
   int localInsideFileCursor = 0;
   for (PsiLanguageInjectionHost host : map.keySet()) {
     if (host == null) continue;
     String hostText = host.getText();
     ProperTextRange insideHost = null;
     StringBuilder sb = new StringBuilder();
     for (Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> entry : map.get(host)) {
       RangeMarker origMarker = entry.first; // check for validity?
       int hostOffset = host.getTextRange().getStartOffset();
       ProperTextRange localInsideHost =
           new ProperTextRange(
               origMarker.getStartOffset() - hostOffset, origMarker.getEndOffset() - hostOffset);
       RangeMarker rangeMarker = entry.second;
       ProperTextRange localInsideFile =
           new ProperTextRange(
               Math.max(localInsideFileCursor, rangeMarker.getStartOffset()),
               rangeMarker.getEndOffset());
       if (insideHost != null) {
         // append unchanged inter-markers fragment
         sb.append(
             hostText.substring(insideHost.getEndOffset(), localInsideHost.getStartOffset()));
       }
       sb.append(
           localInsideFile.getEndOffset() <= text.length() && !localInsideFile.isEmpty()
               ? localInsideFile.substring(text)
               : "");
       localInsideFileCursor = localInsideFile.getEndOffset();
       insideHost = insideHost == null ? localInsideHost : insideHost.union(localInsideHost);
     }
     assert insideHost != null;
     ElementManipulators.getManipulator(host).handleContentChange(host, insideHost, sb.toString());
     documentManager.commitDocument(myOrigDocument);
   }
 }
Example #4
0
  protected void changedUpdateImpl(@NotNull DocumentEvent e) {
    if (!isValid()) return;

    ProperTextRange newRange =
        applyChange(e, intervalStart(), intervalEnd(), isGreedyToLeft(), isGreedyToRight());
    if (newRange == null) {
      invalidate(e);
      return;
    }

    setIntervalStart(newRange.getStartOffset());
    setIntervalEnd(newRange.getEndOffset());
  }
  private boolean showToolTipByMouseMove(final MouseEvent e, final double width) {
    MouseEvent me = e;

    Set<RangeHighlighter> highlighters = new THashSet<RangeHighlighter>();

    getNearestHighlighters(this, me, width, highlighters);
    getNearestHighlighters(
        (MarkupModelEx) myEditor.getDocument().getMarkupModel(getEditor().getProject()),
        me,
        width,
        highlighters);

    if (highlighters.isEmpty()) return false;

    int minDelta = Integer.MAX_VALUE;
    int y = e.getY();

    for (RangeHighlighter each : highlighters) {
      ProperTextRange range = offsetToYPosition(each.getStartOffset(), each.getEndOffset());
      int eachStartY = range.getStartOffset();
      int eachEndY = range.getEndOffset();
      int eachY = eachStartY + (eachEndY - eachStartY) / 2;
      if (Math.abs(e.getY() - eachY) < minDelta) {
        y = eachY;
      }
    }

    me =
        new MouseEvent(
            (Component) e.getSource(),
            e.getID(),
            e.getWhen(),
            e.getModifiers(),
            e.getX(),
            y + 1,
            e.getClickCount(),
            e.isPopupTrigger());

    TooltipRenderer bigRenderer = myTooltipRendererProvider.calcTooltipRenderer(highlighters);
    if (bigRenderer != null) {
      showTooltip(
          me,
          bigRenderer,
          new HintHint(me).setAwtTooltip(true).setPreferredPosition(Balloon.Position.atLeft));
      return true;
    }
    return false;
  }
 @Override
 @NotNull
 public RangeMarker createRangeMarker(
     final int startOffset, final int endOffset, final boolean surviveOnExternalChange) {
   if (!surviveOnExternalChange) {
     return createRangeMarker(startOffset, endOffset);
   }
   ProperTextRange hostRange = injectedToHost(new ProperTextRange(startOffset, endOffset));
   // todo persistent?
   RangeMarker hostMarker =
       myDelegate.createRangeMarker(
           hostRange.getStartOffset(), hostRange.getEndOffset(), surviveOnExternalChange);
   int startShift = Math.max(0, hostToInjected(hostRange.getStartOffset()) - startOffset);
   int endShift = Math.max(0, endOffset - hostToInjected(hostRange.getEndOffset()) - startShift);
   return new RangeMarkerWindow(this, (RangeMarkerEx) hostMarker, startShift, endShift);
 }
  private static void highlightTodos(
      @NotNull PsiFile file,
      @NotNull CharSequence text,
      int startOffset,
      int endOffset,
      @NotNull ProgressIndicator progress,
      @NotNull ProperTextRange priorityRange,
      @NotNull Collection<HighlightInfo> result,
      @NotNull Collection<HighlightInfo> outsideResult) {
    PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(file.getProject());
    TodoItem[] todoItems = helper.findTodoItems(file, startOffset, endOffset);
    if (todoItems.length == 0) return;

    for (TodoItem todoItem : todoItems) {
      progress.checkCanceled();
      TextRange range = todoItem.getTextRange();
      String description =
          text.subSequence(range.getStartOffset(), range.getEndOffset()).toString();
      TextAttributes attributes = todoItem.getPattern().getAttributes().getTextAttributes();
      HighlightInfo info =
          HighlightInfo.createHighlightInfo(
              HighlightInfoType.TODO, range, description, description, attributes);
      assert info != null;
      if (priorityRange.containsRange(info.getStartOffset(), info.getEndOffset())) {
        result.add(info);
      } else {
        outsideResult.add(info);
      }
    }
  }
  public static void renameNonCodeUsages(
      @NotNull Project project, @NotNull NonCodeUsageInfo[] usages) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();
    Map<Document, List<UsageOffset>> docsToOffsetsMap = new HashMap<Document, List<UsageOffset>>();
    final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
    for (NonCodeUsageInfo usage : usages) {
      PsiElement element = usage.getElement();

      if (element == null) continue;
      element = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element, true);
      if (element == null) continue;

      final ProperTextRange rangeInElement = usage.getRangeInElement();
      if (rangeInElement == null) continue;

      final PsiFile containingFile = element.getContainingFile();
      final Document document = psiDocumentManager.getDocument(containingFile);

      final Segment segment = usage.getSegment();
      LOG.assertTrue(segment != null);
      int fileOffset = segment.getStartOffset();

      List<UsageOffset> list = docsToOffsetsMap.get(document);
      if (list == null) {
        list = new ArrayList<UsageOffset>();
        docsToOffsetsMap.put(document, list);
      }

      list.add(new UsageOffset(fileOffset, fileOffset + rangeInElement.getLength(), usage.newText));
    }

    for (Document document : docsToOffsetsMap.keySet()) {
      List<UsageOffset> list = docsToOffsetsMap.get(document);
      LOG.assertTrue(list != null, document);
      UsageOffset[] offsets = list.toArray(new UsageOffset[list.size()]);
      Arrays.sort(offsets);

      for (int i = offsets.length - 1; i >= 0; i--) {
        UsageOffset usageOffset = offsets[i];
        document.replaceString(usageOffset.startOffset, usageOffset.endOffset, usageOffset.newText);
      }
      PsiDocumentManager.getInstance(project).commitDocument(document);
    }
    PsiDocumentManager.getInstance(project).commitAllDocuments();
  }
 AnchorElementInfo(@NotNull PsiElement anchor, @NotNull PsiFile containingFile) {
   super(
       containingFile.getProject(),
       ProperTextRange.create(anchor.getTextRange()),
       anchor.getClass(),
       containingFile,
       LanguageUtil.getRootLanguage(anchor));
   assert !(anchor instanceof PsiFile) : "FileElementInfo must be used for file: " + anchor;
   myStubElementTypeAndId = pack(-1, null);
 }
 // finds the first nearest text range
 @Nullable("null means invalid")
 private static TextRange findNearestTextRange(
     final DocumentWindow documentWindow, final int startOffset) {
   TextRange textRange = null;
   for (Segment marker : documentWindow.getHostRanges()) {
     TextRange curRange = ProperTextRange.create(marker);
     if (curRange.getStartOffset() > startOffset && textRange != null) break;
     textRange = curRange;
   }
   return textRange;
 }
 // finds the first nearest text range
 private static TextRange findNearestTextRange(
     final DocumentWindow documentWindow, final int startOffset) {
   TextRange textRange = null;
   for (RangeMarker marker : documentWindow.getHostRanges()) {
     TextRange curRange = ProperTextRange.create(marker);
     if (curRange.getStartOffset() > startOffset && textRange != null) break;
     textRange = curRange;
   }
   assert textRange != null;
   return textRange;
 }
 @Override
 @NotNull
 public TextRange injectedToHost(
     @NotNull PsiElement injectedContext, @NotNull TextRange injectedTextRange) {
   ProperTextRange.assertProperRange(injectedTextRange);
   PsiFile file = injectedContext.getContainingFile();
   if (file == null) return injectedTextRange;
   Document document = PsiDocumentManager.getInstance(file.getProject()).getCachedDocument(file);
   if (!(document instanceof DocumentWindowImpl)) return injectedTextRange;
   DocumentWindowImpl documentWindow = (DocumentWindowImpl) document;
   return documentWindow.injectedToHost(injectedTextRange);
 }
 @Override
 public TextRange getHostRange(int hostOffset) {
   synchronized (myLock) {
     for (PsiLanguageInjectionHost.Shred shred : myShreds) {
       Segment currentRange = shred.getHostRangeMarker();
       if (currentRange == null) continue;
       TextRange textRange = ProperTextRange.create(currentRange);
       if (textRange.grown(1).contains(hostOffset)) return textRange;
     }
   }
   return null;
 }
 @Override
 public boolean containsRange(int start, int end) {
   synchronized (myLock) {
     ProperTextRange query = new ProperTextRange(start, end);
     for (PsiLanguageInjectionHost.Shred shred : myShreds) {
       Segment hostRange = shred.getHostRangeMarker();
       if (hostRange == null) continue;
       TextRange textRange = ProperTextRange.create(hostRange);
       if (textRange.contains(query)) return true;
     }
     return false;
   }
 }
 @Override
 public boolean decode(@NotNull final TextRange rangeInsideHost, @NotNull StringBuilder outChars) {
   ProperTextRange.assertProperRange(rangeInsideHost);
   TextRange valueTextRange = myXmlAttribute.getValueTextRange();
   int startInDecoded =
       myXmlAttribute.physicalToDisplay(
           rangeInsideHost.getStartOffset() - valueTextRange.getStartOffset());
   int endInDecoded =
       myXmlAttribute.physicalToDisplay(
           rangeInsideHost.getEndOffset() - valueTextRange.getStartOffset());
   String displayValue = myXmlAttribute.getDisplayValue();
   // todo investigate IIOB http://www.jetbrains.net/jira/browse/IDEADEV-16796
   startInDecoded =
       startInDecoded < 0
           ? 0
           : startInDecoded > displayValue.length() ? displayValue.length() : startInDecoded;
   endInDecoded =
       endInDecoded < 0
           ? 0
           : endInDecoded > displayValue.length() ? displayValue.length() : endInDecoded;
   if (startInDecoded > endInDecoded) endInDecoded = startInDecoded;
   outChars.append(displayValue, startInDecoded, endInDecoded);
   return true;
 }
 @Override
 @NotNull
 public RangeMarker createRangeMarker(@NotNull final TextRange textRange) {
   final ProperTextRange properTextRange = new ProperTextRange(textRange);
   return createRangeMarker(properTextRange.getStartOffset(), properTextRange.getEndOffset());
 }
  @Override
  public RangeMarker getRangeGuard(final int startOffset, final int endOffset) {
    ProperTextRange hostRange = injectedToHost(new ProperTextRange(startOffset, endOffset));

    return myDelegate.getRangeGuard(hostRange.getStartOffset(), hostRange.getEndOffset());
  }
 @Override
 @NotNull
 public RangeMarker createGuardedBlock(final int startOffset, final int endOffset) {
   ProperTextRange hostRange = injectedToHost(new ProperTextRange(startOffset, endOffset));
   return myDelegate.createGuardedBlock(hostRange.getStartOffset(), hostRange.getEndOffset());
 }