vscode插件开发笔记——大模型应用之AI编程助手
系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、代码补全
前言
最近在开发vscode插件相关的项目,网上很少有关于大模型作为AI 编程助手这方面的教程。因此,借此机会把最近写的几个demo分享记录一下。
一、代码补全
思路:
- 读取vscode插件上鼠标光标的上下文信息。
- 将提示词和上下文代码作为输入,通过modelfusion调用大模型得到输出。
- 将输出内容插入到光标所在位置,通过Declaration在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 activatedconsole.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 configsmodel: "自己的模型",}).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=indexvscode.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.showInformationMessage('Hello World from myextension!');});let timeout: NodeJS.Timeout | undefined;context.subscriptions.push(disposable2);// 注册事件监听器以在特定条件下调用命令context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => {if (editor) {// 延迟调用命令if (timeout) {clearTimeout(timeout);}timeout = setTimeout(() => {vscode.commands.executeCommand('dytest.helloWorld');}, 200); // 延迟}}));context.subscriptions.push(vscode.window.onDidChangeTextEditorSelection(event => {if (timeout) {clearTimeout(timeout);}timeout = setTimeout(() => {vscode.commands.executeCommand('dytest.helloWorld');}, 200); // 延迟}));
}
export function deactivate() {}
main.ts文件:
import {parse}from '@babel/parser'
import traverse from '@babel/traverse'
import * as vscode from 'vscode';// 代码补全插入
export function previewInsertion(editor: vscode.TextEditor, position: vscode.Position, text: string, ) {const range = new vscode.Range(position, position.translate({characterDelta: text.length}));let currentDecoration: vscode.DecorationOptions[] | undefined = undefined;let decorationType: vscode.TextEditorDecorationType | undefined = undefined;const lines = text.split(/\r\n|\n/); // 分割文本
let lineCount = 0;
let totalCharacterCount = 0;// 计算总行数和总字符数
for (const line of lines) {lineCount++;totalCharacterCount += line.length;
}
totalCharacterCount--;
console.log(lineCount); // 输出非空行数if (!decorationType) {decorationType = vscode.window.createTextEditorDecorationType({light: { // Light theme settingsafter: {contentText: lines[0],fontStyle: 'italic',color: '#7f8c8d', // 灰色backgroundColor: 'transparent',// textDecoration: 'none',margin: '0 0 0 0',},},dark: { // Dark theme settingsafter: {contentText: lines[0],fontStyle: 'italic',color: '#95a5a6', // 灰色,适合深色主题backgroundColor: 'transparent',// textDecoration: 'none',margin: '0 0 0 0',}, }
});
}const endPosition=position.translate({lineDelta:lineCount-1,characterDelta:totalCharacterCount })
console.log("position:",position)
console.log("endPosition:",endPosition)// 创建装饰器选项currentDecoration = [{range: new vscode.Range(position, position),hoverMessage: new vscode.MarkdownString('按“tab”键确认'),
}];// 应用装饰器
editor.setDecorations(decorationType, currentDecoration);// 监听鼠标移动事件,移除装饰
const mouseMoveDisposable = vscode.window.onDidChangeTextEditorSelection((event) => {if (event.textEditor === editor) {editor.setDecorations(decorationType, []);currentDecoration = undefined;}},null,);}// 获取文本上下文信息
export function getBeforeText(document: vscode.TextDocument, position: vscode.Position): string {const range = new vscode.Range(new vscode.Position(0, 0), position);return document.getText(range);
}
export function getAfterText(document: vscode.TextDocument, position: vscode.Position): string {const lastLine = document.lineCount - 1;const lastLineLength = document.lineAt(lastLine).text.length;const range = new vscode.Range(position, new vscode.Position(lastLine, lastLineLength));return document.getText(range);
}
package.json
添加两个命令
"commands": [{"command": "dytest.helloWorld","title": "Hello World"},{ "command": "extension.myCommand","title": "My Command"}
]
快捷键
"keybindings": [{"command": "extension.myCommand","key": "ctrl+shift","when": "editorTextFocus"}]
实现效果:
代码补全(2)
目前遇到的问题:函数级代码生成后,通过Decoration装饰器无法显示全部的。希望有大佬指点一下。
相关文章:
vscode插件开发笔记——大模型应用之AI编程助手
系列文章目录 文章目录 系列文章目录前言一、代码补全 前言 最近在开发vscode插件相关的项目,网上很少有关于大模型作为AI 编程助手这方面的教程。因此,借此机会把最近写的几个demo分享记录一下。 一、代码补全 思路: 读取vscode插件上鼠…...
@JSONField(format = “yyyyMMddHH“)的作用和使用
JySellerItqrdDataDO对象中的字段为: private Date crdat; 2.数据库中的相应字段为: crdat datetime DEFAULT NULL COMMENT 创建时间,2. 打印出的结果为: “crdat”:“2024072718” 年月日时分秒 3. 可以调整format的格式 4. 这样就把Date类…...
计算机网络 6.1Internet概念
第六章 Internet基础 第一节 Internet概念 一、认识Internet 1.定义:集现代计算机技术、通信技术于一体的全球性计算机互联网。 2.地位:当今世界上规模最大的计算机互联网。 3.使用协议:TCP/IP。 4.基本结构: ①主干网…...
编写SpringBoot的自定义starter包
starter项目 先来看一下Starter的官方解释: Spring Boot Starter 是一种方便的依赖管理方式,它封装了特定功能或技术栈的所有必要依赖项和配置,使得开发者可以快速地将这些功能集成到Spring Boot项目中。Spring Boot官方提供了一系列的Star…...
【LeetCode:3106. 满足距离约束且字典序最小的字符串 + 贪心】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
25 Python常用函数——reduce()
在 Python 3.x 中,reduce() 不是内置函数,而是放到了标准库 functools 中,需要先导入再使用。 标准库 functools 中的函数 reduce() 可以将一个接受两个参数的函数以迭代累积的方式从左到右依次作用到一个序列或迭代器对象的所有元素上&#…...
oracle登录报“ORA-27101: shared memory realm does not exist”
oracle登录报“ORA-27101: shared memory realm does not exist” 问题: 1、使用ip:1521/服务名方式连库报错" ORA-27101: shared memory realm does not exist Linux-x86_64 Error: 2: No such file or directory" 2、sqlplus XX/密码 可以登录数据库 …...
界面控件Telerik UI for WPF 2024 Q2亮点 - 全新的AIPrompt组件
Telerik UI for WPF拥有超过100个控件来创建美观、高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序。UI for WPF支持MVVM、触摸等,创建的应用程序可靠且结构良好,非常容易维护,其直观的API将无缝地集成Visual Studio…...
IT服务运营过程中的资源要素管理(至简)
在IT服务运营管理过程中,所有资源要投入正式、连续、稳定运行,要保持规范化的管理和标准化的操作,具体包括工具管理、知识管理、服务台管理与评价、备件库管理等内容。 一、工具管理 1、工具的基本运营。见下表: 工具的基本运营…...
wodpress设置固定链接的方式和好处【SEO优化】
设置固定链接的好处 提高用户体验:固定链接使得网址更加直观和易于记忆,用户可以更容易地分享和访问文章。 优化SEO:搜索引擎更倾向于索引具有清晰结构的网址,固定链接有助于提高网站的SEO表现。 避免URL重复:固定链…...
【C#】 CancellationTokenSource 与Thread的启动、取消的区别?
1.Thread的使用 Thread的使用参考:【C#】Thread的使用 2.CancellationTokenSource 的使用 CancellationTokenSource在C#中用于取消长时间运行的操作,如异步或后台任务。它允许你从外部请求一个操作的取消,并且被取消的操作可以通过检查Ca…...
基于 HTML+ECharts 实现智慧运维数据可视化大屏(含源码)
智慧运维数据可视化大屏:基于 HTML 和 ECharts 的实现 在现代企业中,运维管理是确保系统稳定运行的关键环节。随着数据量的激增,如何高效地监控和分析运维数据成为了一个重要课题。本文将介绍如何利用 HTML 和 ECharts 实现一个智慧运维数据可…...
AIGC(Artificial Intelligence Generated Content)
随着人工智能技术的飞速发展,AIGC(Artificial Intelligence Generated Content)在各个领域的应用日益广泛,其中也包括前端开发的重要部分——CSS(层叠样式表)的优化。CSS作为网页设计中控制布局和样式的关键…...
02 MySQL数据库管理
目录 1.数据库的结构 sql语言主要由以下几部分组成 2. 数据库与表的创建和管理 1,创建数据库 2,创建表并添加数据 3,添加一条数据 4,查询数据 5,更新数据 6,删除数据 3.用户权限管理 1.创建用户 …...
C++编程: 使用 Nanomsg 进行 PUB-SUB 模式基准测试
文章目录 0. 引言1. Nanomsg简介1.1 可扩展性协议类型1.2 支持的传输机制1.3 NanoMsg 架构与实现 2. PUB-SUB 模式基准测试 0. 引言 Nanomsg 作为一款高性能的通信库,支持多种消息传递模式,其中包括 PUB-SUB(发布-订阅)。 本篇文…...
【Unity2D 2022:Data】读取csv格式文件的数据
一、创建csv文件 1. 打开Excel,创建xlsx格式文件 2. 编辑卡牌数据:这里共写了两类卡牌,第一类是灵物卡,具有编号、卡名、生命、攻击四个属性;第二类是法术卡,具有编号、卡名、效果三个属性。每类卡的第一…...
美团测开面经整理大汇总!!
大厂测开面经,加油加油,一周看一篇 美团测开面经美团测开暑期实习面经第二弹美团-地图服务部测开一面面经(70min)美团-优选事业部测开一面面经美团-优选事业部测开二面面经(82min)美团第一次测开笔试美团测…...
微信公众号获取用户openid(PHP版,snsapi_base模式)
微信公众号获取用户openid的接口有2个:snsapi_base、snsapi_userinfo 详情见微信公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html 本文介绍用PHP方式调用snsapi_base接口获取微信用户…...
DuckDB核心模块揭秘 | 第1期 | 向量化执行引擎之Pipeline
DuckDB核心模块揭秘 | 第1期 | 向量化执行引擎之Pipeline DuckDB是一款非常火的OLAP嵌入式数据库,性能超级棒。它分为多个组件:解析器、逻辑规划器、优化器、物理规划器、执行器以及事务和存储管理层。其中解析器原语PgSQL的解析器;逻辑规划器…...
Vue如何让用户通过a链接点击下载一个excel文档
在Vue中,通过<a>标签让用户点击下载Excel文档,通常需要确保服务器支持直接下载该文件,并且你有一个可以直接访问该文件的URL。以下是一些步骤和示例,展示如何在Vue应用中实现这一功能。 1. 服务器端支持 首先,…...
Generative-AI-Playground:模块化AI应用开发实践与本地部署指南
1. 项目概述:一个生成式AI的“游乐场”最近在GitHub上看到一个挺有意思的项目,叫“Generative-AI-Playground”,作者是drshahizan。光看这个名字,你可能会觉得这又是一个堆砌各种AI模型接口的“玩具”项目。但实际深入进去&#x…...
AirSim无人机仿真入门:从Unreal视角设置到Python API调用的保姆级避坑全流程
AirSim无人机仿真入门:从Unreal视角设置到Python API调用的保姆级避坑全流程 当你第一次打开AirSim的官方文档,可能会被那些专业术语和零散的配置步骤搞得晕头转向。作为微软开源的无人机与自动驾驶仿真平台,AirSim确实强大,但它的…...
保姆级教程:从显微镜下的芯片照片到完整版图,手把手教你图像拼接与对准
芯片显微图像处理实战:从碎片化照片到完整版图的逆向工程指南 当你面对数百张杂乱无章的芯片显微照片时,是否感到无从下手?这些看似孤立的图像碎片,实际上隐藏着芯片设计的完整密码。本文将带你走进电子显微镜下的微观世界&#x…...
Adafruit IO与WipperSnapper:无代码物联网开发实战指南
1. 项目概述与核心价值 如果你正在寻找一种能快速将硬件原型转化为可远程监控和控制的物联网设备的方法,那么Adafruit IO与WipperSnapper的组合绝对值得你花时间深入了解。这套方案的核心魅力在于,它几乎移除了传统物联网开发中最繁琐的环节——固件编程…...
物联网芯片设计挑战:EDA工具如何应对极致功耗与面积约束
1. 物联网浪潮下的EDA设计挑战:一次回归本质的审视十年前,当那篇关于物联网与EDA需求的文章发表时,很多人可能觉得“30亿联网设备”的预测有些遥远。今天回头看,这个数字早已被超越,物联网已经从概念变成了我们生活与产…...
【Oracle数据库指南】第37篇:Oracle角色与PROFILE管理详解
上一篇【第36篇】Oracle用户与权限管理详解(完整版) 下一篇【第38篇】Oracle数据库备份策略与实现详解 摘要 角色(Role)是权限的命名集合,通过角色可以将多个权限统一管理,简化复杂的权限授予操作…...
从ZZULIOJ这道题出发,聊聊面试常客:有序数组合并的三种写法与性能对比
从有序数组合并看算法优化:三种解法与百万级数据处理实战 在技术面试中,有序数组合并是一个经典且高频出现的问题。它不仅考察候选人对基础算法的掌握程度,更能检验其在实际问题中的优化思维。本文将以ZZULIOJ平台上的1124题为例,…...
抖音下载器终极指南:3分钟学会免费下载无水印视频和音乐
抖音下载器终极指南:3分钟学会免费下载无水印视频和音乐 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback sup…...
9.2%年复合增长!2032年全球电子束曝光系统市场冲刺36.13亿美元
电子束曝光系统(EBL)是一种依托电子束照射光敏材料实现微细图案加工的高精度设备,核心原理是在真空环境中将电子束精准聚焦于待加工表面,刻写纳米级精细图案,凭借极高的分辨率与操作灵活性,广泛应用于半导体…...
谷歌与新加坡国立大学联手打造“视频导演AI“
这项由谷歌云AI研究院与新加坡国立大学联合完成的研究,于2026年5月以预印本形式公开发布,论文编号为arXiv:2605.06924v1。有兴趣深入阅读原文的读者可通过该编号在arXiv平台检索到完整论文。**研究背景:AI拍视频为何总是"记性不好"…...
