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
相关产品推荐
相关产品推荐

