Eclipse插件开发:使用consoleLineTrackers过滤控制台栈轨迹行失效如何解决
问题根因
你当前实现出现部分行删除失败的核心原因有两个:
- 每次删除行后控制台文档的总长度会发生变化,后续触发
lineAppended回调时拿到的行偏移量是基于修改后的文档计算的,和你删除前的地址不匹配,导致后续替换操作定位错误。 - 硬编码
+2处理换行符的逻辑不兼容不同操作系统的换行格式(Windows下换行\r\n占2个字符,Linux/macOS下换行\n仅占1个字符),会出现多删/少删的情况,导致下一行内容无法匹配过滤规则。
可行解决方案
推荐优先使用前置过滤方案,稳定性更高:
方案1:输出前拦截过滤
通过给控制台添加输出流监听器,在内容写入控制台之前就过滤掉不需要的行,完全避免后续修改文档带来的偏移量问题:
import org.eclipse.ui.console.*; import java.io.IOException; public class StackTraceFilterListener implements IConsoleListener { @Override public void consolesAdded(IConsole[] consoles) { for (IConsole console : consoles) { if (console instanceof IOConsole) { IOConsole ioConsole = (IOConsole) console; ioConsole.getOutputStream().setStreamListener(new IStreamListener() { private final StringBuilder buffer = new StringBuilder(); @Override public void streamAppended(String content, IStreamPrinter printer) { buffer.append(content); int lineEndIndex; // 逐行处理缓冲内容 while ((lineEndIndex = buffer.indexOf("\n")) != -1) { String line = buffer.substring(0, lineEndIndex + 1); // 只输出非栈追踪行 if (!line.trim().startsWith("at ")) { try { printer.print(line); } catch (IOException e) { // 忽略输出异常 } } buffer.delete(0, lineEndIndex + 1); } } }); } } } @Override public void consolesRemoved(IConsole[] consoles) { // 无需额外处理 } }
在插件激活类的start方法中注册监听器即可生效:
ConsolePlugin.getDefault().getConsoleManager().addConsoleListener(new StackTraceFilterListener());
方案2:修正原有consoleLineTrackers实现
如果要继续使用org.eclipse.debug.ui.consoleLineTrackers扩展点,需要新增偏移量修正变量,并且动态计算换行符长度:
// 全局变量,记录已经删除的字符总长度,用于修正后续行的偏移量 private int deletedTotalLength = 0; @Override public void lineAppended(IRegion line) { try { // 计算当前行在修改后文档中的实际偏移量 int actualOffset = line.getOffset() - deletedTotalLength; String lineContent = console.getDocument().get(actualOffset, line.getLength()); if (lineContent.startsWith(" at")) { // 动态判断当前行的换行符长度 int newLineLength = 1; if (actualOffset + line.getLength() < console.getDocument().getLength() && console.getDocument().getChar(actualOffset + line.getLength()) == '\r') { newLineLength = 2; } int needDeleteLength = line.getLength() + newLineLength; console.getDocument().replace(actualOffset, needDeleteLength, ""); // 更新已删除的总长度,用于后续行的偏移修正 deletedTotalLength += needDeleteLength; } } catch (Exception e) { // 异常处理逻辑 } }
内容的提问来源于stack exchange,提问作者user14223135
相关产品推荐
相关产品推荐

