最近学习了一下如何写vscode插件,不得不感叹大神写的vscode框架就是厉害,简单通过配置文件加上事件处理代码就可以扩展编辑器前端的能力。膜拜之余,造了一个轮子,交互过程如下,右键json文件选择json生成go结构体(JsonToGo)就可以生成json文件对应的选择生成golang代码或者结构体curl生成go代码(CurlToGo)就可以从curl命令(从浏览器的debugtool直接copy过来)生成对应的golang客户端代码,简单修改即可发起http请求。 代码放在https:github。comxiazemingolangCodeHelper,由于没有自己的独立域名,暂时没有发布到vscode应用市场,感兴趣的小伙伴可以到github 下载下来,然后通过导入vsix文件的方式来安装插件,编译好的插件位于:https:github。comxiazemingolangCodeHelperblobmaingolangCodeHelper0。0。1。vsix,通过这个插件我们可以在本地做常用的代码生成,提升我们的开发效率。比如: json文件:{name:golangCodeHelper,version:0。0。1,lockfileVersion:2,requires:true,packages:{:{name:golangCodeHelper,version:0。0。1,devDependencies:{typesglob:8。0。1,typesmocha:10。0。1, 可以生成typeAutoGeneratedstruct{Namestringjson:nameDisplayNamestringjson:displayNameDescriptionstringjson:descriptionVersionstringjson:versionEnginesstruct{Vscodestringjson:vscode}json:enginesCategories〔〕stringjson:categoriesActivationEvents〔〕stringjson:activationEventsMainstringjson:mainContributesstruct{Commands〔〕struct{Commandstringjson:commandTitlestringjson:titleCategorystringjson:category,omitempty}json:commands 在浏览器上复制下来的curlcurlhttps:ug。baidu。commcppcpcsearchHAccept:HAcceptLanguage:zhCN,q0。9HConnection:keepaliveHContentType:applicationjsonHCookie:BIDUPSID17AC3E8E8275F51ACFD6A4E37AC75966;PSTM1676794732;BAIDUID17AC3E8E8275F51AC7F6EA632EC051DD:FG1;HPSPSSID36555381123809238132381163815038175381733680237935380882635038119380973800837881;BDORZB490B5EBF6F3CD402E515D22BCDA1598;BAHECTOR0485ag8g0g2k8ha1250g0hjm1hv49q51k;delPer0;PSINO5;BAIDUIDBFESS17AC3E8E8275F51AC7F6EA632EC051DD:FG1;ZFYLzNgJDmgbcwFmDlSJY5RPCv4lgsx3Kzg2hlLesbqjdY:CHOrigin:https:www。baidu。comHReferer:https:www。baidu。coms?ieutf8f8rsvbp1rsvidx1tnbaiduwdcontenttype20application2Fjsonfenlei256oqcontenttype2520application252Fjsonrsvpqb58f78f900026b99rsvt1445vFHiJ7o4mPEOrw4MQTAUMrxUQJFcddCoRqhH8Q3CjHgKQK8m4sCm2NQrqlangcnrsventer0rsvdltbrsvbtypetinputT95112rsvsug3407rsvsug1450rsvsug7000rsvsug20rsvsug495250rsvsug1HSecFetchDest:emptyHSecFetchMode:corsHSecFetchSite:samesiteHUserAgent:Mozilla5。0(MIntelMacOSX10157)AppleWebKit537。36(KHTML,likeGecko)Chrome109。0。0。0Safari537。36Hsecchua:NotABv99,GoogleCv109,Cv109Hsecchuamobile:?0Hsecchuaplatform:macOSdataraw{invokeinfo:{pos1:〔{}〕,pos2:〔{}〕,pos3:〔{}〕}}compressed 可以生成typePayloadstruct{InvokeInfoInvokeInfojson:invokeinfo}typePos1struct{}typePos2struct{}typePos3struct{}typeInvokeInfostruct{Pos1〔〕Pos1json:pos1Pos2〔〕Pos2json:pos2Pos3〔〕Pos3json:pos3}data:Payload{fillstruct}payloadBytes,err:json。Marshal(data)iferr!nil{handleerr}body:bytes。NewReader(payloadBytes)req,err:http。NewRequest(POST,https:ug。baidu。commcppcpcsearch,body)iferr!nil{handleerr}req。Header。Set(Accept,)req。Header。Set(AcceptLanguage,zhCN,q0。9)req。Header。Set(Connection,keepalive)req。Header。Set(ContentType,applicationjson)req。Header。Set(Cookie,BIDUPSID17AC3E8E8275F51ACFD6A4E37AC75966;PSTM1676794732;BAIDUID17AC3E8E8275F51AC7F6EA632EC051DD:FG1;HPSPSSID36555381123809238132381163815038175381733680237935380882635038119380973800837881;BDORZB490B5EBF6F3CD402E515D22BCDA1598;BAHECTOR0485ag8g0g2k8ha1250g0hjm1hv49q51k;delPer0;PSINO5;BAIDUIDBFESS17AC3E8E8275F51AC7F6EA632EC051DD:FG1;ZFYLzNgJDmgbcwFmDlSJY5RPCv4lgsx3Kzg2hlLesbqjdY:C)req。Header。Set(Origin,https:www。baidu。com)req。Header。Set(Referer,https:www。baidu。coms?ieutf8f8rsvbp1rsvidx1tnbaiduwdcontenttype20application2Fjsonfenlei256oqcontenttype2520application252Fjsonrsvpqb58f78f900026b99rsvt1445vFHiJ7o4mPEOrw4MQTAUMrxUQJFcddCoRqhH8Q3CjHgKQK8m4sCm2NQrqlangcnrsventer0rsvdltbrsvbtypetinputT95112rsvsug3407rsvsug1450rsvsug7000rsvsug20rsvsug495250rsvsug1)req。Header。Set(SecFetchDest,empty)req。Header。Set(SecFetchMode,cors)req。Header。Set(SecFetchSite,samesite)req。Header。Set(UserAgent,Mozilla5。0(MIntelMacOSX10157)AppleWebKit537。36(KHTML,likeGecko)Chrome109。0。0。0Safari537。36)req。Header。Set(SecChUa,NotABv99,GoogleCv109,Cv109)req。Header。Set(SecChUaMobile,?0)req。Header。Set(SecChUaPlatform,macOS)resp,err:http。DefaultClient。Do(req)iferr!nil{handleerr}deferresp。Body。Close() 下面详细介绍下插件开发的详细流程。首先安装node环境nodevv18。0。0npmv8。6。0 然后安装脚手架和插件打包工具npminstallgyogeneratorcodenpminstallgvscodevsce 通过脚手架生成项目框架yocodeWelcometotheVisual(o)StudioCodeExtensiongenerator!(U)A。。Y?Whattypeofextensiondoyouwanttocreate?(Usearrowkeys)NewExtension(TypeScript)NewExtension(JavaScript)NewColorThemeNewLanguageSupportNewCodeSnippetsNewKeymapNewExtensionPackNewLanguagePack(Localization)NewWebExtension(TypeScript)NewNotebookRenderer(TypeScript)?Whattypeofextensiondoyouwanttocreate?NewExtension(TypeScript)?Whatsthenameofyourextension?hello?Whatstheidentifierofyourextension?hello?Whatsthedescriptionofyourextension?hello?Initializeagitrepository?No?Bundlethesourcecodewithwebpack?Yes?Whichpackagemanagertouse?npm 它生成的代码很简单,是一个最简单的模板,能够在vscode中输出vscode,它的核心代码是下面几行,首先看下package。jsonactivationEvents:〔onCommand:hello。helloWorld〕,main:。distextension。js,contributes:{commands:〔{command:hello。helloWorld,title:HelloWorld}〕}, 其中activationEvents,就是我们的插件和对应的命令,。distextension。js,是插件的入口文件,commands,后面就是对应的我们的命令。然后我们看下入口文件。distextension。jsThemodulevscodecontainstheVSCodeextensibilityAPIIThismethodiscalledwhenyourextensionisactivatedYourextensionisactivatedtheveryfirsttimethecommandisexecutedexportfunctionactivate(context:vscode。ExtensionContext){Usetheconsoletooutputdiagnosticinformation(console。log)anderrors(console。error)Thislineofcodewillonlybeexecutedoncewhenyourextensionisactivatedconsole。log(Congratulations,yourextensionhelloisnowactive!);Thecommandhasbeendefinedinthepackage。jsonfileNowprovidetheimplementationofthecommandwithregisterCommandThecommandIdparametermustmatchthecommandfieldinpackage。jsonletdisposablevscode。commands。registerCommand(hello。helloWorld,(){ThecodeyouplaceherewillbeexecutedeverytimeyourcommandisexecutedDisplayamessageboxtotheuservscode。window。showInformationMessage(HelloWorldfromhello1!);});context。subscriptions。push(disposable);}Thismethodiscalledwhenyourextensionisdeactivatedexportfunctiondeactivate(){} 它最核心的就是暴露了一个激活方法给vscode框架调用,在方法内部,通过vscode。commands。registerCommand,注册了需要执行的命令和对应的callback函数,并将命令发布到context,context。subscriptions。push(disposable);这样一个最简单的插件就制作完毕了。我们可以通过fnf5进行调试,没有问题后就可以通过vscepackage 进行打包生成对应的插件文件xxx。vsix,我们发布到应有市场然后搜索,或者直接导入插件文件,就可以使用我们的插件了。 熟悉完上述流程后,就可以开始制作自己的插件,首先在package。json里配置我们需要的命令和菜单。activationEvents:〔onCommand:golangCodeHelper。helloWorld,onCommand:golangCodeHelper。JsonToGo,onCommand:golangCodeHelper。CurlToGo,onCommand:golangCodeHelper。CurlToGoStructs〕,main:。distextension。js,contributes:{commands:〔{command:golangCodeHelper。helloWorld,title:golang编码辅助工具集},{command:golangCodeHelper。JsonToGo,title:json生成go结构体(JsonToGo),category:golangCodeHelper},{command:golangCodeHelper。CurlToGo,title:curl生成go代码(CurlToGo),category:生成golang代码或者结构体},{command:golangCodeHelper。CurlToGoStructs,title:curl生成go结构体(CurlToGoStructs),category:生成golang代码或者结构体}〕,menus:{explorercontext:〔{command:golangCodeHelper。JsonToGo,when:!explorerResourceIsFolder,group:2workspace1},{group:2workspace2,when:!explorerResourceIsFolder,submenu:golangCodeHelpersubmenugenerate}〕,golangCodeHelpersubmenugenerate:〔{command:golangCodeHelper。CurlToGo,group:1generate1},{command:golangCodeHelper。CurlToGoStructs,group:1generate2}〕},submenus:〔{id:golangCodeHelpersubmenugenerate,label:生成golang代码或者结构体}〕}, 然后注册我们的命令执行函数并且发布ThemodulevscodecontainstheVSCodeextensibilityAPIIconst{jsonToGo}require(。jsontogojsontogo。js);const{curlToGo}require(。curltogoresourcesjscurltogo。js);const{curlToGoStruct}require(。curltogostructcurltogostruct。js)parampath写入的文件路径paramcontent写入的文件内容paramfileName写入的文件名paramfileNameExtra当文件名存在于该文件夹下时的替代文件名constwriteFile(path:string,content:string,fileName?:stringundefined,fileNameExtra?:stringundefined){letnewfileNamefileNamejsontogo。constopt{flag:wx但是如果文件路径存在,则文件写入失败。覆盖写入:w};constexists:booleanfs。existsSync({path}{nodepath。sep}{newfileName});if(exists){newfileNamefileNameExtrafileNameExtra副本。}console。log(写入路径:{path}{nodepath。sep}{newfileName});fs。writeFile({path}{nodepath。sep}{newfileName},content,opt,(err){if(err){vscode。window。showErrorMessage(写入{newfileName}失败,可能原因是,改文件夹下已存在{newfileName});}vscode。window。showInformationMessage(已生成一个示例{newfileName});});};ThismethodiscalledwhenyourextensionisactivatedYourextensionisactivatedtheveryfirsttimethecommandisexecutedexportfunctionactivate(context:vscode。ExtensionContext){Usetheconsoletooutputdiagnosticinformation(console。log)anderrors(console。error)Thislineofcodewillonlybeexecutedoncewhenyourextensionisactivatedconsole。log(Congratulations,yourextensiongolangCodeHelperisnowactive!);Thecommandhasbeendefinedinthepackage。jsonfileNowprovidetheimplementationofthecommandwithregisterCommandThecommandIdparametermustmatchthecommandfieldinpackage。jsonletdisposablevscode。commands。registerCommand(golangCodeHelper。helloWorld,(){ThecodeyouplaceherewillbeexecutedeverytimeyourcommandisexecutedDisplayamessageboxtotheuservscode。window。showInformationMessage(HelloWorldfromgolangCodeHelper!);});letJsonToGovscode。commands。registerCommand(golangCodeHelper。JsonToGo,(e){vscode。window。showInformationMessage(JsonToGofromgolangCodeHelper!);constfilenamee?e?。fsPath?。split()。pop():vscode。window。activeTextEditor?。document。fileName。split()。pop();vscode。window。showInformationMessage(filenamee。fsPath);vardatafs。readFileSync(e。fsPath,utf8);vscode。window。showInformationMessage(data);console。log(data)console。log(jsonToGo)constgotjsonToGo(data,null,null,false);console。log(got)vscode。window。showInformationMessage(got);if(got。error){vscode。window。showInformationMessage(JsonToGofromgolangCodeHelperfailed!{got。error});}else{writeFile(nodepath。dirname(e。fsPath),got。go,jsontogo。go);}});letCurlToGovscode。commands。registerCommand(golangCodeHelper。CurlToGo,(e){vscode。window。showInformationMessage(curlToGofromgolangCodeHelper!);constfilenamee?e?。fsPath?。split()。pop():vscode。window。activeTextEditor?。document。fileName。split()。pop();vscode。window。showInformationMessage(filenamee。fsPath);vardatafs。readFileSync(e。fsPath,utf8);vscode。window。showInformationMessage(data);console。log(data)console。log(curlToGo)constgotcurlToGo(data,null,null,false);console。log(got)vscode。window。showInformationMessage(got);writeFile(nodepath。dirname(e。fsPath),got,curltogo。go);});letCurlToGoStructsvscode。commands。registerCommand(golangCodeHelper。CurlToGoStructs,(e){vscode。window。showInformationMessage(CurlToGoStructsfromgolangCodeHelper!);constfilenamee?e?。fsPath?。split()。pop():vscode。window。activeTextEditor?。document。fileName。split()。pop();vscode。window。showInformationMessage(filenamee。fsPath);vardatafs。readFileSync(e。fsPath,utf8);vscode。window。showInformationMessage(data);console。log(data)console。log(curlToGoStruct)constgotcurlToGoStruct(data,null,null,false);console。log(got)vscode。window。showInformationMessage(got);writeFile(nodepath。dirname(e。fsPath),got,curltogostruct。go);});context。subscriptions。push(disposable);context。subscriptions。push(JsonToGo);context。subscriptions。push(CurlToGo);context。subscriptions。push(CurlToGoStructs);}Thismethodiscalledwhenyourextensionisdeactivatedexportfunctiondeactivate(){} 至此,插件制作完毕,当然vscode还支持更为复杂的插件,可以参考其官方文档进行学习。