You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Eclipse插件开发:打开XML文件到指定行且不触发资源变更事件

解决Eclipse插件中跳转XML指定行不触发资源变更监听的问题

我之前开发Eclipse插件时也碰到过一模一样的问题——定位到文件指定行号时不小心触发了FileSystemChangesListenerresourceChanged()事件,搅乱了插件里的其他逻辑。设置TRANSIENT参数没用,是因为这个参数主要控制资源的临时状态,而我们常规的打开方式可能还是触发了不必要的资源状态变更。

下面是我摸索出来的纯视图定位、不修改资源本身的解决方案,完全不会触发资源变更监听:

核心思路

跳过任何可能修改资源属性的操作,只做编辑器内部的视图定位:先打开目标XML文件的编辑器,再通过文本编辑器的API直接定位到指定行号,整个过程不会改动文件的内容或元数据。

具体实现代码

import org.eclipse.core.resources.IFile;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;

public void jumpToXmlLine(IFile xmlFile, int targetLine) {
    // 1. 创建编辑器输入(仅关联文件,不修改任何属性)
    IEditorInput editorInput = new FileEditorInput(xmlFile);
    
    try {
        // 2. 获取当前工作台页面并打开XML编辑器
        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        // 这里用WST的XML编辑器ID,也可以替换为DefaultTextEditor的ID:org.eclipse.ui.DefaultTextEditor
        IEditorPart editor = page.openEditor(editorInput, "org.eclipse.wst.xml.ui.internal.editor.XMLEditor");
        
        // 3. 转换为文本编辑器,定位到指定行
        if (editor instanceof ITextEditor) {
            ITextEditor textEditor = (ITextEditor) editor;
            IDocument document = textEditor.getDocumentProvider().getDocument(editorInput);
            
            if (document != null) {
                // 注意:Eclipse文档的行号是0-based,若你的错误行号是1-based,需要减1
                int zeroBasedLine = targetLine - 1;
                int offset = document.getLineOffset(zeroBasedLine);
                int lineLength = document.getLineLength(zeroBasedLine);
                
                // 仅做视图定位,不修改文件
                textEditor.selectAndReveal(offset, lineLength);
            }
        }
    } catch (Exception e) {
        // 根据你的插件需求处理异常
        e.printStackTrace();
    }
}

关键细节说明

  1. 编辑器ID选择

    • 如果是使用Eclipse自带的XML编辑器,用org.eclipse.wst.xml.ui.internal.editor.XMLEditor(需要确保安装了WST插件);
    • 也可以通用文本编辑器IDorg.eclipse.ui.DefaultTextEditor,只要XML文件和该编辑器关联正确。
  2. 行号转换
    Eclipse的IDocument行号是从0开始计数的,如果你的错误信息里的行号是1-based(比如XML校验错误通常是1-based),一定要转换为0-based再传入。

  3. 为什么不会触发资源变更
    selectAndReveal()只是编辑器内部的视图操作,仅改变编辑器的显示位置,不会修改文件的内容、修改时间或任何资源属性,因此FileSystemChangesListener不会收到变更事件。

排查之前的问题

你之前设置TRANSIENT无效,大概率是因为实现中调用了会修改资源状态的方法(比如标记资源为已修改、更新文件元数据等),换成上面的纯视图定位方式就能彻底避免这个问题。

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

火山引擎 最新活动