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. 服务器端支持 首先,…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...