最近,我一直在用 Tabby[1] 搭配 VSCode 写代码,尤其是它的内联补全功能,真是越用越上瘾。今天,我想跟大家聊聊 Tabby 在 VSCode 中是如何实现内联代码补全的,这背后有一些挺有意思的技术细节。
内联补全的核心实现是在 InlineCompletionProvider[2] 这个类中。它实现了 VSCode 提供的 InlineCompletionItemProvider
接口,负责处理所有内联补全的逻辑。
简单来说,Tabby 的这个组件有几个关键任务:
它的核心代码逻辑长这样:
async provideInlineCompletionItems(
document: TextDocument,
position: Position,
context: InlineCompletionContext,
token: CancellationToken,
): Promise<InlineCompletionItem[] | null> {
try {
// 记录编辑器状态
this.client.fileTrack.addingChangeEditor(window.activeTextEditor);
// 发起请求
const request = this.client.languageClient.sendRequest(
InlineCompletionRequest.method,
params,
token
);
this.ongoing = request;
this.emit("didChangeLoading", true); // 开始加载状态
const result = awaitthis.ongoing;
this.ongoing = null;
this.emit("didChangeLoading", false); // 加载完成
if (!result || result.items.length === 0 || token.isCancellationRequested) {
returnnull;
}
// 转换补全项为 VSCode 支持的格式
return result.items.map((item, index) => {
returnnewInlineCompletionItem(
typeof item.insertText === "string"
? item.insertText
: newSnippetString(item.insertText.value),
item.range
? newRange(
item.range.start.line,
item.range.start.character,
item.range.end.line,
item.range.end.character,
)
: undefined,
{
title: "",
command: "tabby.applyCallback",
arguments: [
() => {
this.handleEvent("accept", result, index);
},
],
},
);
});
} catch (error) {
this.ongoing = null;
this.emit("didChangeLoading", false); // 出错后恢复状态
returnnull;
}
}
补全分两种触发方式:
Ctrl+Space
。触发的模式由 Tabby 的 triggerMode
配置项控制,你可以根据需要设置为 automatic
或 manual
。
Tabby 的 VSCode 扩展和 Tabby Agent 是通过 LSP(Language Server Protocol)通信的。Agent 在这里扮演了一个桥梁角色:
可以简单画个流程图说明整个过程:
从服务器返回的补全结果可能包含多个建议,Tabby 会把它们转换成 VSCode 支持的 InlineCompletionItem
格式。每个补全项包含以下内容:
代码是这样处理的:
return result.items.map((item, index) => {
returnnewInlineCompletionItem(
typeof item.insertText === "string" ? item.insertText : newSnippetString(item.insertText.value),
item.range
? newRange(
item.range.start.line,
item.range.start.character,
item.range.end.line,
item.range.end.character,
)
: undefined,
{
title: "",
command: "tabby.applyCallback",
arguments: [
() => {
this.handleEvent("accept", result, index);
},
],
},
);
});
Tabby 的补全系统还内置了一个事件追踪功能。通过这些事件,Tabby 可以知道你是如何与补全交互的:
最后我们简单看看 Tabby 和其他类似工具的区别:
工具 | 内联补全 | 自动触发 | 支持多语言 | 性能优化 | 事件追踪 |
---|---|---|---|---|---|
Tabby | ✅ | ✅ | ✅ | ✅ | ✅ |
Copilot | ✅ | ✅ | ✅ | ✅ | ❌ |
Codeium | ✅ | ✅ | ✅ | ✅ | ❌ |
Tabby 的内联补全功能,不仅提升了编程效率,还在用户体验上下了不少功夫。从核心架构到事件追踪,再到性能优化,每个环节都设计得相当用心。对开发者来说,它确实是一款值得尝试的工具。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。