You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eclipse插件开发:如何为自定义IMarker实现鼠标悬停提示?

Eclipse 2019-12 自定义TXT编辑器Marker悬停与快速修复实现

针对你已定义的my.markerType标记,要实现TXT编辑时类似Java错误提示的悬停效果,需从悬停提供者实现、Marker关联、快速修复处理器三个核心部分入手,具体步骤如下:

1. 实现自定义文本悬停提供者

创建ITextHover实现类,用于捕获鼠标悬停位置的Marker并构建提示内容:

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PlatformUI;

public class MyTxtHover implements ITextHover {
    @Override
    public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
        IDocument document = textViewer.getDocument();
        if (document == null) return null;

        // 获取当前激活编辑器对应的文件资源
        IEditorPart activeEditor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
        if (!(activeEditor instanceof IFileEditorInput)) return null;
        IFile file = ((IFileEditorInput) activeEditor.getEditorInput()).getFile();

        // 遍历文件上的自定义Marker,匹配悬停位置
        try {
            IMarker[] markers = file.findMarkers("my.markerType", true, IResource.DEPTH_ZERO);
            for (IMarker marker : markers) {
                int markerStart = marker.getAttribute(IMarker.CHAR_START, -1);
                int markerEnd = marker.getAttribute(IMarker.CHAR_END, -1);
                if (markerStart != -1 && markerEnd != -1 
                    && hoverRegion.getOffset() >= markerStart 
                    && hoverRegion.getOffset() <= markerEnd) {
                    
                    String errorMsg = marker.getAttribute(IMarker.MESSAGE, "未知错误");
                    // 构建带快速修复入口的HTML格式提示内容
                    StringBuilder hoverContent = new StringBuilder();
                    hoverContent.append("<p><b>").append(errorMsg).append("</b></p>");
                    hoverContent.append("<p><a href=\"#\">查看修复建议</a></p>");
                    return hoverContent.toString();
                }
            }
        } catch (CoreException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
        // 返回悬停位置所在的行区域
        try {
            return textViewer.getDocument().getLineInformationOfOffset(offset);
        } catch (BadLocationException e) {
            return new Region(offset, 0);
        }
    }
}

2. 将悬停提供者关联到TXT编辑器

通过IAdapterFactory为默认TXT文本编辑器适配自定义悬停,避免修改编辑器源码:

注册AdapterFactory扩展点

在plugin.xml中添加:

<extension point="org.eclipse.ui.adapters">
   <factory
         adaptableType="org.eclipse.ui.editors.text.TextEditor"
         class="com.yourpackage.MyAdapterFactory">
      <adapter type="org.eclipse.jface.text.ITextHover"/>
   </factory>
</extension>

实现AdapterFactory类

import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.editors.text.TextEditor;

public class MyAdapterFactory implements IAdapterFactory {
    @Override
    public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
        if (adapterType == ITextHover.class && adaptableObject instanceof TextEditor) {
            TextEditor editor = (TextEditor) adaptableObject;
            IEditorInput input = editor.getEditorInput();
            // 仅对TXT文件应用自定义悬停
            if (input instanceof IFileEditorInput) {
                String fileExt = ((IFileEditorInput) input).getFile().getFileExtension();
                if ("txt".equalsIgnoreCase(fileExt)) {
                    return adapterType.cast(new MyTxtHover());
                }
            }
        }
        return null;
    }

    @Override
    public Class<?>[] getAdapterList() {
        return new Class[]{ITextHover.class};
    }
}

3. 实现Marker快速修复处理器

创建IQuickFixProcessor实现类,提供代码补全/修复建议:

实现快速修复处理器类

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.editors.text.FileDocumentProvider;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.texteditor.quickfix.IQuickFixProcessor;
import org.eclipse.ui.texteditor.quickfix.MarkerResolution;

public class MyMarkerQuickFixProcessor implements IQuickFixProcessor {
    @Override
    public boolean hasCorrections(IMarker marker, int position) {
        // 仅处理自定义Marker类型
        return "my.markerType".equals(marker.getType());
    }

    @Override
    public MarkerResolution[] getResolutions(IMarker marker) {
        return new MarkerResolution[]{
            new MarkerResolution() {
                @Override
                public String getLabel() {
                    return "替换为标准文本";
                }

                @Override
                public void run(IMarker marker) {
                    try {
                        IFile file = (IFile) marker.getResource();
                        IDocument document = FileDocumentProvider.getDefault().getDocument(IDE.getEditorInput(file));
                        int start = marker.getAttribute(IMarker.CHAR_START, -1);
                        int end = marker.getAttribute(IMarker.CHAR_END, -1);
                        
                        // 执行修复操作:替换错误文本
                        document.replace(start, end - start, "标准内容");
                        // 修复后删除Marker
                        marker.delete();
                    } catch (CoreException | BadLocationException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    }
}

注册快速修复扩展点

在plugin.xml中添加:

<extension point="org.eclipse.ui.quickFixProcessors">
   <quickFixProcessor
         class="com.yourpackage.MyMarkerQuickFixProcessor"
         markerType="my.markerType"/>
</extension>

关键注意事项

  • 确保创建my.markerType时,为其设置CHAR_START、CHAR_END和MESSAGE属性,否则悬停无法准确定位和展示内容。
  • 悬停内容支持HTML简单标签(如<b>、<p>、<a>),Eclipse会自动解析渲染。
  • 快速修复的链接无需手动处理点击事件,Eclipse会自动关联到对应的MarkerResolution执行逻辑。

内容的提问来源于stack exchange,提问作者liuyue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:37:03