当前位置: 首页 > news >正文

vscode插件开发笔记——大模型应用之AI编程助手

系列文章目录

文章目录

  • 系列文章目录
  • 前言
  • 一、代码补全


前言

最近在开发vscode插件相关的项目,网上很少有关于大模型作为AI 编程助手这方面的教程。因此,借此机会把最近写的几个demo分享记录一下。

一、代码补全

思路:

  1. 读取vscode插件上鼠标光标的上下文信息。
  2. 将提示词和上下文代码作为输入,通过modelfusion调用大模型得到输出。
  3. 将输出内容插入到光标所在位置,通过Declaration在vscode页面进行显示。
  4. 设置快捷键,如果代码补全正确,按下快捷键后自动插入代码。反之光标移动,代码自动消失。

下面直接上代码。
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中&#xff0c;通过<a>标签让用户点击下载Excel文档&#xff0c;通常需要确保服务器支持直接下载该文件&#xff0c;并且你有一个可以直接访问该文件的URL。以下是一些步骤和示例&#xff0c;展示如何在Vue应用中实现这一功能。 1. 服务器端支持 首先&#xff0c;…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...