Eclipse RCP下两个IContentAssistProcessor自动激活触发异常问题
问题原因
- 核心是Eclipse 通用编辑器(Generic Editor)的内容辅助自动激活逻辑设计如此:当输入的字符匹配任意一个同contentType下注册的内容辅助处理器的激活字符时,会触发所有
activate="true"的处理器执行computeCompletionProposals方法,而非仅触发定义了匹配激活字符的处理器。 - 你两个处理器的
plugin.xml配置都设置了activate="true",因此只要第一个处理器定义的激活字符被触发,两个处理器都会被调用。第二个处理器的getCompletionProposalAutoActivationCharacters返回null,仅代表该处理器本身不贡献任何自动激活触发字符,不代表它不会被其他处理器的激活逻辑触发执行。
解决方案
根据你的使用场景选择即可:
方案1:不需要自动触发的处理器仅响应手动唤起
如果第二个处理器仅需要在用户手动按Ctrl+Space(内容辅助默认快捷键)时才返回提示,自动激活场景下不生效,可以在第二个处理器的computeCompletionProposals方法开头增加触发原因判断:
@Override public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { // 先获取 invocation context 判断触发原因 IContentAssistInvocationContext context = ContentAssistPlugin.getDefault().getContentAssistManager() .getInvocationContext(viewer, offset); if (context != null && context.getInvocationReason() == ContentAssistInvocationContext.INVOCATION_REASON_AUTO_ACTIVATION) { // 自动激活场景直接返回空结果 return new ICompletionProposal[0]; } // 原有逻辑 ... }
方案2:按文本上下文过滤调用
如果两个处理器分别负责不同位置的提示(比如一个负责关键字提示、一个负责属性值提示),可以在两个computeCompletionProposals开头先判断当前光标位置的文本上下文是否属于自己的负责范围,不属于就直接返回空结果即可,即使被调用也不会产生多余的提示,对性能影响极小。
方案3:拆分内容类型
如果两个处理器的适用场景完全独立,可以拆分为两个子contentType分别绑定对应的处理器,就不会出现跨触发的问题。
内容的提问来源于stack exchange,提问作者steven
相关产品推荐
相关产品推荐

