前言
本文将介绍如何利用VSCode插件开发环境结合大模型(LLM)来实现代码补全功能,并且介绍如何集成网络搜索功能以增强代码补全的能力.
一、代码补全
功能概述
本插件能够在用户编写代码时提供智能代码补全建议。插件会读取鼠标光标上下文信息,将提示词和上下文代码作为输入,通过调用大模型得到输出,并将输出内容插入到光标所在位置。
实现步骤
读取上下文信息:获取光标前后的代码。
调用大模型:构建提示词和指令模板,调用大模型生成补全代码。
代码补全显示:使用VSCode装饰器显示生成的代码。
快捷键插入代码:设置快捷键,如果代码补全正确,按下快捷键后自动插入代码;否则光标移动时代码自动消失。
代码实现
下面直接上代码。
extension.ts 文件:
import * as vscode from 'vscode';
import {
BaseUrlApiConfiguration,
openaicompatible,
streamText,
} from 'modelfusion';
import{
previewInsertion, getBeforeText, getAfterText }from '../src/main'
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "dytest" is now active!');
let globalText:string|undefined ;
let globalindex: vscode.Position | undefined;
// 如何删除字符
const editor = vscode.window.activeTextEditor;
// 代码补全命令
const disposable = vscode.commands.registerCommand('dytest.helloWorld', async () => {
if (!editor) {
return;
}
// 代码所在位置
const code =editor.document.getText();
//光标所在位置
const offset =editor.document.offsetAt(editor.selection.active);
const index = editor.document.positionAt(offset);
const position = editor.selection.active;
const document = editor.document;
const beforeText = getBeforeText(document, position);
const afterText = getAfterText(document, position);
// 调用大模型
const code_prompt='提示词';
const code_instruction='{
{
{prefix}}}[BLANK]{
{
{suffix}}}';
const code_instruction_2=code_instruction.replace("{
{
{prefix}}}", beforeText).replace("{
{
{suffix}}}",afterText)
console.log(code_instruction_2)
const text2 = await streamText({
model: openaicompatible
.ChatTextGenerator({
// 这里使用的是自己部署的大模型,url和openai的一样。但是模型不是用的openai系列的。如果要改,可以换成openai的。
api: new BaseUrlApiConfiguration({
baseUrl: "模型的url",
headers: {
Authorization: `模型的api`,
},
}),
provider: "openaicompatible-fireworksai", // optional, only needed for logging and custom configs
model: "自己的模型",
})
.withInstructionPrompt(),
prompt: {
system:
code_prompt,
instruction:
code_instruction_2
},
});
let responseUntilNow = "";
for await (const textPart of text2) {
// process.stdout.write(textPart);
responseUntilNow += textPart;
}
console.log(responseUntilNow)
// 进行代码补全的提示
const previewinsertion =previewInsertion(editor,index,responseUntilNow);
globalText=responseUntilNow;
globalindex=index
vscode.window.showInformationMessage('Hello World from dy_test!');
});
context.subscriptions.push(disposable);
const disposable2 = vscode.commands.registerCommand('extension.myCommand', async () => {
editor?.edit((editBuilder => {
if (!globalindex || !globalText){
return;
}
const lines = globalText.split(/\r\n|\n/); // 分割文本
editBuilder.insert(globalindex, lines[0])
globalindex=undefined;
globalText=undefined;
}));
vscode.window.