简体   繁体   English

如何在自定义Eclipse编辑器中为语法错误创建错误悬停

[英]How to create an Error Hover for Syntax Errors in a custom Eclipse Editor

im currently writing an Eclipse editor plugin for a custom transformation language. 我目前正在为自定义转换语言编写Eclipse编辑器插件。 I can already display syntax errors by a curly red line underneath the error like this: 1 and they are also displayed in the PRoblems view. 我已经可以通过如下所示的错误下方的红色粗线显示语法错误: 1 ,它们也显示在PRoblems视图中。 Now Im trying to implement a hover for syntax errors like it is here: 2 . 现在,我正在尝试为语法错误实现悬停,例如: 2 Any ideas or tutorials you got how to do this? 您有任何想法或教程,如何做到这一点? Is it mandatory the add the exact line Number to the Marker? 将确切的行号添加到标记是否是强制性的? I know there are probably dozens of tutorials out there, but non of them explains it in complete detail, so please help me out!=) The code which displays the syntax errors at the moment is this one: 我知道那里可能有几十个教程,但是没有一个教程详细地解释了它,所以请帮我!=)当前显示语法错误的代码是这个:

package de.se_rwth.langeditor.texteditor.errorhighlighting;

import java.io.IOException;
import java.util.Set;

import javax.annotation.Nullable;

import org.antlr.v4.runtime.misc.Interval;
import org.apache.commons.io.IOUtils;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.swt.widgets.Display;

import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.inject.Inject;

import de.se_rwth.langeditor.injection.TextEditorScoped;
import de.se_rwth.langeditor.modelstates.ModelState;
import de.se_rwth.langeditor.modelstates.ObservableModelStates;

@TextEditorScoped
public class ErrorHighlighter {

  private final IAnnotationModel annotationModel;

  private String content = "";


  private final Set<Annotation> annotations = Sets.newConcurrentHashSet();

  private static final String MARKERID  = "org.eclipse.rwth.syntaxerror";

  @Inject
  public ErrorHighlighter(@Nullable IAnnotationModel annotationModel, IStorage storage,
      ObservableModelStates observableModelStates) {
    this.annotationModel = annotationModel;
    if (annotationModel != null) {
      observableModelStates.getModelStates().stream()
          .filter(modelState -> modelState.getStorage().equals(storage))
          .forEach(this::acceptModelState);
      observableModelStates.addStorageObserver(storage, this::acceptModelState);
    }
  }

  public void acceptModelState(ModelState modelState) {
    for (Annotation annotation : annotations) {
      annotationModel.removeAnnotation(annotation);
      annotations.remove(annotation);
    }
    IMarker[] problems = null;
    int depth = IResource.DEPTH_INFINITE;
    IWorkspace workspace = ResourcesPlugin.getWorkspace(); 
    try { //Remove all problem Markers when rebuilding the Model
       problems = workspace.getRoot().findMarkers(IMarker.PROBLEM, true, depth);
       for(IMarker m: problems){
           m.delete();
       }
    } catch (CoreException e) {
       e.printStackTrace();
    }
    try {
        content = IOUtils.toString(modelState.getStorage().getContents(), "UTF-8");
    } catch (IOException e) {
        e.printStackTrace();
    } catch (CoreException e) {
        e.printStackTrace();
    }
    displaySyntaxErrors(modelState);
    displayAdditionalErrors(modelState);
  }

  private void displaySyntaxErrors(ModelState modelState) {
    ImmutableMultimap<Interval, String> syntaxErrors = modelState.getSyntaxErrors();
    for (Interval interval: syntaxErrors.keys()) {
      for (String message : syntaxErrors.get(interval)) {
        Display.getDefault().asyncExec(() -> displayError(interval, message));
      }
    }
  }

  private void displayAdditionalErrors(ModelState modelState) {
    Multimap<Interval, String> additionalErrors = modelState.getAdditionalErrors();
    for (Interval interval: additionalErrors.keys()) {
      for (String message : additionalErrors.get(interval)) {
        Display.getDefault().asyncExec(() -> displayError(interval, message));
      }
    }
  }

  private void displayError(Interval interval, String message) {
    int startIndex = interval.a;
    int stopIndex = interval.b + 1;
    Annotation annotation =
        new Annotation("org.eclipse.ui.workbench.texteditor.error", false, message);
    annotations.add(annotation);
    annotationModel.addAnnotation(annotation, new Position(startIndex, stopIndex - startIndex));
    IWorkspace workspace = ResourcesPlugin.getWorkspace(); 
    IMarker marker;
    try { //create Marker to display Syntax Errors in Problems View
        marker = workspace.getRoot().createMarker(MARKERID);
        marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
        marker.setAttribute(IMarker.MESSAGE, message);
        marker.setAttribute(IMarker.CHAR_START, startIndex);
        marker.setAttribute(IMarker.CHAR_END, stopIndex);
        marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
        int lineNumber = 0;
        if(!content.isEmpty()){ //Convert StartIndex to Line Number
            String[] lines = content.substring(0, startIndex).split("\r\n|\r|\n");
            lineNumber = lines.length;
        }
        marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
    } catch (CoreException e) {
        e.printStackTrace();
    }

  }
}

To answer my own question: I missed overriding the 要回答我自己的问题:我错过了覆盖

ITextHover getTextHover(ISourceViewer sourceViewer, String contentType)

method. 方法。 So after inserting 所以在插入之后

public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
      return new DefaultTextHover(sourceViewer);
  }

into the SourceViewerConfiguration the Hover appears. 进入SourceViewerConfiguration,将出现悬停。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM