如何从外部插件(View)程序化访问Xtext编辑器的CompletionProposal?
嘿,我来帮你梳理下从View插件访问已打开Xtext/Xbase编辑器CompletionProposal的实现思路,既然你已经拿到了MyEditor、XbaseDocumentProvider和XtextDocument这些关键对象,核心就是找到Xtext的补全服务并构建正确的请求上下文:
核心实现步骤
1. 获取Xtext补全服务实例
Xtext的补全逻辑由ICompletionProposalProvider统一处理,你可以通过已有的对象获取Xtext依赖注入器,再拿到这个服务:
// 方式1:从XtextDocument获取 XtextLanguages languages = xtextDocument.getLanguages().iterator().next(); Injector injector = languages.getInjector(); ICompletionProposalProvider completionProvider = injector.getInstance(ICompletionProposalProvider.class); // 方式2:从MyEditor获取(如果MyEditor是XtextEditor子类) Injector injector = ((XtextEditor) myEditor).getInjector(); ICompletionProposalProvider completionProvider = injector.getInstance(ICompletionProposalProvider.class);
2. 构建补全请求上下文
补全需要光标位置、文档解析结果等上下文信息,得先创建CompletionProposalRequest对象:
// 获取当前编辑器的光标偏移量 ITextSelection selection = (ITextSelection) myEditor.getSite().getSelectionProvider().getSelection(); int cursorOffset = selection.getOffset(); // 确保文档已完成解析,拿到ParseResult ParseResult<?> parseResult = xtextDocument.getParseResult(); if (parseResult == null) { // 主动触发同步解析 parseResult = xtextDocument.readOnly(state -> state.getParseResult()); } // 构建补全请求 CompletionProposalRequest request = new CompletionProposalRequest.Builder() .setOffset(cursorOffset) .setLength(0) // 若要替换选中内容,这里填选中长度即可 .setContent(xtextDocument.get()) .setParseResult(parseResult) .setResource(parseResult.getRootElement().eResource()) .setContext(myEditor.getSite().getWorkbenchWindow()) .build();
3. 触发补全并获取结果
有了请求对象后,直接调用补全服务方法就能拿到CompletionProposal列表:
List<ICompletionProposal> proposals = completionProvider.computeCompletionProposals(request, null);
第二个参数是IProgressMonitor,不需要监控进度传null即可。
几个注意事项
- 线程安全:操作Xtext文档时,尽量用
xtextDocument.readOnly或xtextDocument.modify包裹,避免并发问题 - 依赖配置:确保你的View插件已依赖Xtext核心和UI bundle(比如
org.eclipse.xtext、org.eclipse.xtext.ui),否则可能无法获取注入器或服务 - 解析状态:如果文档未完成解析,
parseResult会为null,记得先触发解析再继续操作
内容的提问来源于stack exchange,提问作者Alirno
相关产品推荐
相关产品推荐

