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

「入选文章」腾讯云AI代码助手 | AI助力,从零基础开发一个vscode插件

前言

在日常的代码开发中,总会遇到很多很小的知识点,想用却无从记起。尤其是在日常的前端开发,想要添加一个自己想要的css样式,却又想不起属性名,然后再css网站和笔记中搜索。当时想,如果能在IDE中内嵌一个AI编程助手就好了。

后来GitHub推出了Copilot,再后来腾讯云基于混元大模型,推出了腾讯云AI代码助手。在惊喜之余,更多的是想要体验一下腾讯云AI代码助手的功能。

开发需求

以前都是用IDEA做代码开发,但是IDEA太占内存,所以最近在朋友的推荐下,开始尝试使用vscode做前端开发。但是在开发中发现一个问题:vscode不和IDEA一样的是,在一个字符或者变量后面紧跟.log,无法自动补全为console.log。

我在IDEA可以自动补全console.log:

而在vscode中,却无法使用.log生成console.log,只能输入console.log,然后通过腾讯云AI编程助手的自动补全功能,补全括号和其中的变量部分:

vscode有着丰富的插件,同时也给开发者提供了独立开发插件的功能。虽然我对vscode插件开发没有涉猎过,但是这次想借着腾讯云AI代码助手的“东风”,看我是否可以从零基础,独自开发一个vscode的插件,实现IDEA中console.log的功能。

腾讯云AI代码助手

首先我们先在vscode中安装腾讯云AI助手的插件。在vscode插件市场中搜索腾讯云AI代码助手下载安装。

安装之后在下方就能看到AI助手的图标,点击即可使用。

腾讯云AI代码助手除了提供完善的自动补全代码、根据注释生成代码、代码解释、生成测试代码、转换代码语言、技术对话等能力,还内置了很多对话快捷指令,在对话输入框中输入 / 或 @ 就可调用快捷指令:

  1. /clear:清空当前会话。
  2. /comments:为所选的代码添加文档注释。
  3. /newNotebook:创建一个新的 Jupyter 笔记本。
  4. /explain:解释所选代码的工作原理。
  5. /fix:针对所选代码中的问题提出修复方案。
  6. /tests:为所选代码生成单元测试。
  7. /nameVariable:变量命名。
  8. @vscode:询问 VS Code。
  9. @terminal:询问如何在终端中执行某些操作。
  10. @workspace:询问您的工作空间,将自动引用当前代码。

插件开发环境准备

询问腾讯云AI代码助手创建vscode插件的流程:

根据给出的代码安装vocode插件的开发依赖和环境。在腾讯云AI代码助手给出的操作代码中,我们无需再通过选中,然后CTRL + C复制,在代码助手中提供了辩解的一键复制功能。

然后在terminal中执行代码,创建过程中根据提示操作,最后打包方式选择unbundled

这样,vscode创建项目就创建完成。在src中只生成了一个extension.ts文件,猜测这就是vscode插件的代码文件。

选中代码,使用腾讯云AI代码助手的代码解释(Explain code),来解释一下代码。

从下图中可以看出,上面操作与在对话框中直接输入 @workpace /explain 的快捷指令效果相同。

通过腾讯云AI代码助手的代码解释,明白了extension.ts是如何定义插件的。对于开发者要做的就是在vscode.commands.registerCommand接口中,定义插件的逻辑代码即可。

代码语言:typescript

复制

const disposable = vscode.commands.registerCommand('test.helloWorld', () => {// 在这里编写插件的功能代码vscode.window.showInformationMessage('Hello World from aqi!');});context.subscriptions.push(disposable);
}

在给出的模板代码中,插件功能主题是vscode.window.showInformationMessage,在vscode中展示提示信息,提示信息我改成了“Hello World from aqi!”。

test.helloWorld就是插件注册的命令,调用这个命令就可以执行插件的功能。同时,也需要在package.json声明这个命令。

其中title意味着在命令界面输入Hello World,就可以调用这个插件命令。

运行插件

第一次使用vscode,第一次开发vscode插件,还是要求助腾讯云AI代码助手:如何在vscode中运行自己开发的插件。

F5启动vscode的debug,进入Extension Development Host页面。

然后使用快捷键Ctrl + Shift + P调出命令面板,输入Hello World就可以执行插件命令。

执行Hello World之后,可以从上图右下角看到执行结果,弹出了"aqi"的消息提示框。至此,在腾讯云AI编程助手的助力下,关于vscode插件的开发环境搭建、开发框架以及运行流程都已经完成,接下来就是继续实现我们的console.log的需求。

插件功能实现接口

我在github搜索vscode插件项目的时候,搜到了一个名叫quickly-log的插件,看介绍是将光标放在变量后面,通过快捷键实现log补全的功能。我感觉这个项目和我的需求十分吻合,然后我就把代码pull下来,学习一下人家是如何实现功能的。

运行插件

pull代码之后,运行插件体验quickly-log的功能。根据项目的README所写,此插件一共提供了三个功能,目前我只触发了前两个功能。

1. 生成console.log

quickly-log插件中,将光标放在变量后面,然后使用CTRL + SHIFT + L快捷键,就自动将生成console.log(),并在括号中的输入内容中回填变量。

2. 清除console.log

使用Ctrl + Shift + K快捷键,就可以删除编辑器中所有console.log的语句。

阅读代码

从quickly-log生成console.log的功能来看,虽然和我想要的最终结果不一样,但是对同样都是对vscode编辑器的文本输入进行了监听,以及代码的插入。所以我打算阅读这部分代码,来了解插件中对于vscode编辑器的接口是如何实现的。

1. 获取编辑器对象

通过对quickly-log项目结构的分析,生成console.log的核心代码如下。

我大概看了一下代码,猜测window.activeTextEditor就是我想要获取的vscode的编辑器对象,后面的document、selection都是编辑器对象的一些属性。为了验证自己的猜想,我使用腾讯云AI代码助手求证。

2. 获取插入行号

然后就是获取在编辑器中,要插入console.log的行号,getInsertLine就实现了这个功能。

先调用getLineText,根据行号调用document的lineAt,就可以获取到当前行的代码。

那么形参中行号line是怎么来的?

其实在上面quickly-log生成console.log的演示中,是将光标放在了变量的后面,所以通过编辑器的selection.active属性,获取当前光标所在的行号就可以了。

同样,对于selection.active想希的解释,可以求助腾讯云AI代码助手。

最后在getInsertLine中,将line + 1,表示将console.log插入到光标所在行的下一行。

同时,我在阅读获取代码缩进位置的实现方法getStartSpace时,编辑器波浪线标识出代码不规范,这里我使用腾讯云AI代码助手的快速修复(Quick Fix)功能,直接生成规范符合要求的代码。

同时,AI代码助手还“兼职”接口文档的功能,遇到不懂的方法,选中会弹出详细的方法描述。

在腾讯云AI代码助手的帮助下,我迅速阅读完了quickly-log的逻辑功能代码。

基本功能开发

接下来就是我在extension.ts中,实现自己预期生成console.log的代码逻辑。

1.获取当前行代码

同样,在registerCommand中注册一个logCompletion命令,然后获取vscode的编辑器对象。在获取了编辑器对象之后,通过document和selection分别获取编辑器的文档对象和当前行。

然后使用腾讯云AI代码助手的注释生成代码功能,直接生成获取光标所在行文本的代码。如图所示,变量lineText代表的就是当前行我输入的代码。

2. 替换.log

例如我输入的是"aqi".log,所以我要进行判断,如果代码以.log结尾,那么就将前面的变量填充到console.log中,即让其变成console.log("aqi");

代码语言:typescript

复制

if (lineText.endsWith('.log')) {const logText = lineText.substring(0, lineText.length - 4); const logStatement = `console.log(${logText});`;editor.edit(editBuilder => {const range = new vscode.Range(line.range.start, line.range.end);editBuilder.replace(range, logStatement); });
}

通过对当前行的代码lineText进行substring,去掉最后的四个字符,即.log。然后将结果字符串(即.log前面的字符)拼接到logStatement对象中。

最后使用vscode.Range的对象,选定当前行的所有内容,然后将当前行的所有代码替换成console.log。

3. 定义快捷键

最后就是在package.json中声明logCompletion命令,并在keybindings中将其快捷键定义为CTRL + SHIFT + H

4. 运行结果

输入"aqi".log,然后按下CTRL + SHIFT + H快捷键,如图所示实现了console.log的功能。

但是这里出现了两个问题:

  1. 括号内“aqi”前面有空格(缩进)
  2. 代码没有缩进

所以下一步就是对这两个问题进行优化。

5. 优化缩进问题

个人猜测问题1出现的原因是,在获取获当前代码logText时,调用substring的起始下标是从0开始的,所以将前面的缩进(空格)也带进去了,所以我们调用trim()或者trimStart()去掉前面的空格就行了。

去掉代码缩进

我将问题抛给了AI代码助手,果然和我猜测的原因一致。在AI代码助手给出的代码块右上方,除了一键复制功能的功能,还能将代码一键插入到编辑器中。

这样就成功解决了问题1。

获取代码缩进index

至于问题2,生成的console.log直接定格没有缩进,原因是在创建用于表明替换范围的vscode.Range时,使用line.range.start作为起始坐标,line表示一行代码,在编辑器中一行代码的起始坐标肯定是0。所以,要想办法获取到缩进结尾的index,以此作为Range的起始范围。

这时候再次使用腾讯云AI代码助手的注释声成代码功能。

最终,通过firstNonWhitespaceCharacterIndex获取到缩进结尾的index。然后使用腾讯云AI代码助手生成修改偏移量的代码。

优化后代码

对上面的代码进行合并之后,最终的优化代码如下:

代码语言:typescript

复制

if (lineText.endsWith('.log')) {const logText = lineText.substring(0, lineText.length - 4).trimStart(); const logStatement = `console.log(${logText});`;// 获取前面的缩进最后的indexconst indent = line.firstNonWhitespaceCharacterIndex;editor.edit(editBuilder => {const newStartCharacter = line.range.start.character + indent;const newStart = new vscode.Position(line.range.start.line, newStartCharacter);const range = new vscode.Range(newStart, line.range.end);editBuilder.replace(range, logStatement); });
}
  1. 使用trimStart去掉了前面的空格
  2. indent表示缩进结尾的index,然后以indent为起始创建一个Position对象,在创建Range时作为参数,用于标明起始位置。
6. 优化后的运行结果

运行插件,在输入.log和按下快捷键一波操作之后,效果如预期的一样,两个缩进问题都完美解决。

至此,console.log插件的基本功能已完成。但是我想要进一步的简化操作,不想每次都使用CTRL + SHIFT + H快捷键生成,能不能在输入.log之后,再输入回车就能自动生成呢。

回车生成console.log

我第一时间把需求交给了腾讯云AI代码助手。

1. 开发思路

我尝试用JavaScript的开发思维,看vscode是否能监听文本输入或者输入回车的事件。

腾讯云AI代码助手根据我的描述,并结合我已经实现的插件代码,给出了插件的详细功能设计方案和代码实现。

2. 监听回车

主要使用onDidChangeTextDocument监听vscode编辑器的文本变化,只要输入或者删除代码造成文本变化,都会触发这个监听。如果想要实现监听回车,那么文本进行判断,看是否最后的一个字符输入的是否是回车。

代码语言:typescript

复制

context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {const editor = vscode.window.activeTextEditor;if (!editor) {return;}const document = event.document;const changes = event.contentChanges;// 只处理用户输入的最后一个字符if (changes.length === 1) {const change = changes[0];const text = change.text;// 检查用户是否输入了回车键,并且之前的文本是 .logif (text === '\n' || text === '\r\n') {const line = document.lineAt(change.range.start.line);const lineText = line.text.trim();if (lineText.endsWith('.log')) {vscode.window.showInformationMessage(`Generated console.log by 回车`);vscode.commands.executeCommand('extension.logCompletion');}}}
}));

通过change.text变化文本,然后判断是否为回车(mac为\n,windowsw为\r\n),如果回车,且代码是以.log结尾的,就调用vscode.commands的executeCommand方法,执行我们上面定义的生成console.log的插件功能,即extension.logCompletion

3. 功能演示

为了区分回车与快捷键生成console.log,我在监听回车的逻辑中增加了一个消息弹出:Generated console.log by 回车

如图所示,我在.log后面输入回车,就自动生成了console.log,右下角也弹出了提示。

其他

DIY console.log

如果我们想要在console.log的文本中,加入一些有意思的文本元素,可以直接在logStatement变量中修改即可。

运行结果:

添加注释

在编写完所有的代码之后,为了提高自己代码的可读性,还是要对主要的功能代码加上注释。与以前需要手动输入或者依赖IDE添加注释不同的是,腾讯云AI代码助手的文档注释(Complete comments)功能会帮助我们生成注释。

在编辑器中代码上方,选择文档注释,在腾讯云AI代码助手对话框中就会生成注释。

除此之外,在输入框中选择快捷键 /comments,效果和上面等同。

最后将通过AI代码助手的一键复制或一键插入功能,完成代码注释。

结语

通过腾讯云AI代码助手的智能代码补全、自动代码生成、代码优化等功能的助力,让我从零基础开发了一个vscode插件。在整个开发过程中,腾讯云AI代码助仿佛是一个“知识宝库”,也像是一个全能的开发者,带给了我完全不一样的coding体验。

期待腾讯云AI编程助手将会在未来带来更多的创新和惊喜,为全球开发者赋能,推动编程生产力的革命性提升。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • NGINX 之 location 匹配优先级
  • cdr工具介绍之刻刀工具
  • 重磅!RISC-V+OpenHarmony平板电脑发布
  • MySQL——高级查询(3)分组查询
  • 敲桌子游戏
  • Java OkHttp使用(二)
  • Java数组05:Arrays类
  • 多商户小程序审核存在商户入口无法通过
  • 消息中间件:Kafka消息丢失与堆积问题分析与解决方案
  • MySQL在Centos7环境安装
  • Oracle 同义词SYNONYM 的使用
  • 【GH】【EXCEL】P1: Write DATA SET from GH into EXCEL
  • 为什么要用云手机进行海外社交营销
  • 【Python异常处理简析】
  • 数据结构(邓俊辉)学习笔记】优先级队列 07——堆排序
  • 0x05 Python数据分析,Anaconda八斩刀
  • Angular 响应式表单 基础例子
  • angular组件开发
  • CSS3 变换
  • HomeBrew常规使用教程
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Java编程基础24——递归练习
  • Laravel 中的一个后期静态绑定
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • node和express搭建代理服务器(源码)
  • python学习笔记 - ThreadLocal
  • socket.io+express实现聊天室的思考(三)
  • Tornado学习笔记(1)
  • Twitter赢在开放,三年创造奇迹
  • Vue全家桶实现一个Web App
  • Yeoman_Bower_Grunt
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 码农张的Bug人生 - 初来乍到
  • 深度学习入门:10门免费线上课程推荐
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 网页视频流m3u8/ts视频下载
  • 详解移动APP与web APP的区别
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 通过调用文摘列表API获取文摘
  • 我们雇佣了一只大猴子...
  • ​补​充​经​纬​恒​润​一​面​
  • ###C语言程序设计-----C语言学习(3)#
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #07【面试问题整理】嵌入式软件工程师
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (33)STM32——485实验笔记
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (力扣题库)跳跃游戏II(c++)
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (十五)Flask覆写wsgi_app函数实现自定义中间件