Eclipse插件:实现快速修复建议,将鼠标悬停在错误之上 [英] Eclipse Plugin: Implement Quick Fix proposals on hovering over errors

查看:384
本文介绍了Eclipse插件:实现快速修复建议,将鼠标悬停在错误之上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有什么:我在编辑器中显示错误,作为红色下划线和问题视图中的als。我使用标记,但也通过此代码创建注释:

What i have: I display errors in the editor as a red underline and als in the problems view. I use markers for that, but also create annotations by this code:

@TextEditorScoped
public class ErrorHighlighter {

  private final IAnnotationModel annotationModel;

  private String content = "";


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

  private static final String ERRORMARKERID  = "org.eclipse.rwth.syntaxerror";
  private static final String WARNINGMARKERID = "org.eclipse.rwth.syntaxwarning"; 

  @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;
    IFile file = Misc.getEditorInput(modelState.getStorage()).getAdapter(IFile.class);
    try { //Remove all problem Markers when rebuilding the Model
       problems = file.findMarkers(ERRORMARKERID, true, depth);
       for(IMarker m: problems){
           m.delete();
       }
       problems = file.findMarkers(WARNINGMARKERID, 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 = null;
//    Annotation annotation =
//        new Annotation("org.eclipse.ui.workbench.texteditor.error", false, message);
//    annotations.add(annotation);
//    annotationModel.addAnnotation(annotation, new Position(startIndex, stopIndex - startIndex));
    IMarker marker = null;
    try { //create Marker to display Syntax Errors in Problems View
        IFile file = (IFile) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getEditorInput().getAdapter(IFile.class);
        if (file != null) {
            if(message.charAt(message.length()-1) == 'W'){
                marker = file.createMarker(WARNINGMARKERID);
                marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
            } else {
                marker = file.createMarker(ERRORMARKERID);
                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() && content.length()>=stopIndex){  //Convert StartIndex to Line Number
                String[] lines = content.substring(0, stopIndex).split("\r\n|\r|\n");
                lineNumber = lines.length;
            }
            marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
        }
    } catch (CoreException e) {
        e.printStackTrace();
    }
    IMarker[] problems = null;
    int depth = IResource.DEPTH_INFINITE;
    IFile file = (IFile) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getEditorInput().getAdapter(IFile.class);
    try { //Remove all problem Markers when rebuilding the Model
       problems = file.findMarkers(ERRORMARKERID, true, depth);
       for(IMarker m: problems){
           for(IMarker n: problems){
               if(MarkerUtilities.getCharStart(m) == MarkerUtilities.getCharStart(n) && m != n && MarkerUtilities.getMessage(m).equals(MarkerUtilities.getMessage(n))){
                   m.delete();
               }
           }
       }
    } catch (CoreException e) {
       e.printStackTrace();
    }
    if(marker != null){
        Annotation a = new MarkerAnnotation(marker);
        annotations.add(a);
        annotationModel.addAnnotation(a, new Position(startIndex, stopIndex - startIndex));
    }

  }
}

在我的SourceViewerConfiguration我用以下代码覆盖getTextHover和getAnnotationHover:

In my SourceViewerConfiguration I overwrite getTextHover and getAnnotationHover with this code:

@Override
  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
      return new DefaultAnnotationHover(true);
  }

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

我还用以下代码覆盖getQuickAssistAssistant:

I also overwrite getQuickAssistAssistant with this code:

public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
      IQuickAssistAssistant quickAssist = new QuickAssistAssistant();
      quickAssist.setQuickAssistProcessor(new TFQuickAssistProcessor());
      quickAssist.setInformationControlCreator(getInformationControlCreator(sourceViewer));
      return quickAssist;
}

有了这个我可以正确的选择代码中的错误,并选择QuickFix,其中将导致一个Box出现,显示我的快速修正提案。

With this i can right klick on errors in the code and select QuickFix, which will result in a Box appearing, which displays my Quick Fix Proposals.

我想要的:如何在我悬停时显示此Box以上的错误?
提前感谢

What I want: How do I make this Box appear whenever I hover above the error? Thanks in advance

推荐答案

回答我自己的问题:
我更换了 getTextHover 方法:

To answer my own question: I replaced the getTextHover method by this one:

public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {      
      return new AbstractAnnotationHover(true) {
          public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
              IAnnotationModel model = ((SourceViewer) textViewer).getAnnotationModel();
              @SuppressWarnings("unchecked")
              Iterator<Annotation> parent = 
                      ((IAnnotationModelExtension2)model).getAnnotationIterator(hoverRegion.getOffset(), 
                              hoverRegion.getLength(), true, true);
              Iterator<?> iter = new JavaAnnotationIterator(parent, false); 
              Annotation annotation = null;
              Position position = null;
              while (iter.hasNext()) {
                  Annotation a = (Annotation) iter.next();
                  Position p = model.getPosition(a);
                  annotation = a;
                  position = p;
              }
              return new AnnotationInfo(annotation, position, textViewer) {
                  public ICompletionProposal[] getCompletionProposals() {
                      ICompletionProposal proposal1 = null;
                      IMarkerResolution [] resolutions = null;
                      ICompletionProposal [] com = null;
                      if (annotation instanceof MarkerAnnotation) {
                          resolutions = new ErrorResolution().getResolutions(((MarkerAnnotation) annotation).getMarker());
                          if(resolutions.length != 0){
                              proposal1 = new MarkerResolutionProposal(resolutions[0], 
                                      ((MarkerAnnotation) annotation).getMarker());
                              return new ICompletionProposal[] { proposal1 };
                          }
                      }
                      return com ;
                  }
              };
          } 
    };
}

这将导致一个悬停框出现在提供快速修复的错误。希望这有帮助!

which will result in a hovering box appearing over the errors offering a quick fix. Hope this helps!

这篇关于Eclipse插件:实现快速修复建议,将鼠标悬停在错误之上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆