如何写一个vscode插件

如何写一个vscode插件

先说说为什么会萌生了这个开发vscode插件的想法。我在写markdown的时候需要插入图片。本地写的话只能是本地的URI。如果放到别的平台上对于图片的处理是比较麻烦的。目前的解决方案是存到七牛云或者使用pic等等。但是比较不靠谱而且还要配置比较麻烦。所以我的这个插件就是把图片上传到码云的仓库,返回一个URL直接插入到markdown中。

首先要感谢大神的一系列博客https://www.cnblogs.com/liuxianan/p/vscode-plugin-overview.html。写一个简单的vscode插件看这系列文章就够了。我在这里只是简单记录一下我的开发过程。
vscode支持通过脚手架来初始化一个vscode插件目录。首先安装脚手架。

npm install -g yo generator-code

然后进入你的目运行 yo code
vscode插件初始化.jpg

编写

vscode支持TypeScript和JavaScript。我用的是JS。进入目录之后大部分的改动都在extension.js和package.json两个文件。
我下面直接把代码贴过来再加一些注释。

vscode的主要配置如下,main表明了入口文件。这里是extention.js。

package.json

contributes:这里定义了如何来触发自己的插件。我定义的是command。也就是通过Ctrl+shift+p然后输入命令。这些命令需要在activationEvents里面注册一下。
configuration:这里定义了一些配置,一些个性化的信息不适合写死在代码里。
输入命令对应的代码会写在extension.js里面。

// package.json
"activationEvents": [
    "onCommand:extention.upload",
    "onCommand:extention.upload_remote",
    "onCommand:extention.upload_local",
    "*"
	],
"main": "./extension.js",
"contributes": {
    "commands": [
        {
            "command": "extention.upload",
            "title": "upload"
        },
        {
            "command": "extention.upload_remote",
            "title": "uploadRemote"
        },
        {
            "command": "extention.upload_local",
            "title": "uploadLocal"
        }
    ],
    "configuration": {
        "type": "object",
        "title": "mdPic配置",
        "properties": {
            "pic.git": {
                "type": "string",
                "default": "null",
                "description": "git仓库"
            },
            "pic.access_token": {
                "type": "string",
                "default": "null",
                "description": "access_token"
            }
        }
    }
},

extenion.js

注册命令

首先vscode有一个声明周期函数。插件激活之后会自动进入activate函数。在这个函数里面我们需要把配置的commands注册一下。
sub.push(vscode.commands.registerCommand('extention.upload_remote', disposeRemotePic));这行代码标识如果输入upload_remote命令,它对应的回调函数是disposeRemotePic。vscode为我们提供了很多API,比如vscode.window.showInformationMessage("active!");就是弹出一个显示active的窗口。

// extension.js
/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {
	console.log('"md-pic" is now active!');
	const dispos = vscode.commands.registerCommand("extention.upload", function () {
		vscode.window.showInformationMessage("active!");
	});
	context.subscriptions.push(dispos);

	let sub = context.subscriptions;
	sub.push(vscode.commands.registerCommand('extention.upload_remote', disposeRemotePic));
	sub.push(vscode.commands.registerCommand('extention.upload_local', disposeLocalPic));
}

编写具体的功能实现。

这段代码实现了获取当前行的图片链接,并且下载该图片并转成base64格式编码。下载图片是用的axios。后面上传图片也是是用了这个模块。

function disposeRemotePic() {
	let editor = vscode.window.activeTextEditor;
	let document = editor.document;
	console.log(editor);
	console.log(document);
	const line = editor.selection.active.line;
	let url = document.lineAt(line);
	console.log(url.text);
	const text = '上传第' + line + '行链接图片:' + url.text + ' 至GitHub, 请输入图片名称';
	vscode.window.showInputBox(
		{
			password: false, // 输入内容是否是密码
			ignoreFocusOut: true, // 默认false,设置为true时鼠标点击别的地方输入框不会消失
			placeHolder: 'name', // 在输入框内的提示信息
			prompt: text, // 在输入框下方的提示信息
		}).then(res => {
			const pic_name = res + ".png";
			const pic_url = url.text;
			// upload(res + ".png", url.text);
			console.log('name: ' + pic_name + ', url: ' + pic_url);
			axios.get(encodeURI(pic_url),
				{
					responseType: 'arraybuffer'
				})
				.then(res => uploadGitee(pic_name, Buffer.from(res.data).toString('base64')))
				.catch(function (error) {
					console.log(error);
					vscode.window.showInformationMessage("download image failed, please try again!");
				});
		});
}

这段代码是选择一个本地文件并把这个文件转成base64编码。

function disposeLocalPic() {
	vscode.window.showOpenDialog(
		{ // 可选对象
			canSelectFiles: true, // 是否可选文件
			canSelectFolders: false, // 是否可选文件夹
			canSelectMany: true, // 是否可以选择多个
			defaultUri: vscode.Uri.file("./"), // 默认打开本地路径
			openLabel: '上传'
		}).then(function (msg) {
			const path = msg[0].path;
			console.log(path);
			// var data = fs.readFileSync(path.substring(1));
			var data = fs.readFileSync(path);
			const base64Data = Buffer.from(data).toString('base64');
			const paths = path.split("/");
			const pic_name = paths[paths.length - 1];
			uploadGitee(pic_name, base64Data);
		});
}

这段代码是吧文件上传到gitee然后返回一个URL。并且调用API插入到文本编辑框里。

function uploadGitee(pic_name, base64_data) {
	const url = vscode.workspace.getConfiguration().get('pic.git');
	const auth = vscode.workspace.getConfiguration().get('pic.access_token');
	const headers = { 'Content-Type': 'application/json', 'charset': 'UTF-8' };
	const jdata = JSON.stringify({
		"access_token": auth,
		"message": pic_name,
		"content": base64_data
	});
	console.log(headers)
	console.log(jdata);

	axios.post(encodeURI(url + pic_name), jdata, {
		headers: headers
	}
	).then(res => {
		console.log(res);
		if (res.status = 200) {
			const git_url = res.data["content"]["download_url"]
			console.log(git_url);
			vscode.window.activeTextEditor.edit(editBuilder => {
				const md_img = "![" + pic_name + "](" + git_url + ")";
				const end = new vscode.Position(vscode.window.activeTextEditor.selection.active.line + 1, 0);
				editBuilder.replace(new vscode.Range(new vscode.Position(vscode.window.activeTextEditor.selection.active.line, 0), end), md_img);
			});
		} else {
			console.error("upload url failed!")
			vscode.window.showInformationMessage("upload url failed, please try again!");
		}
	}).catch(function (error) {
		console.log(error);
		vscode.window.showInformationMessage("upload url failed, please try again!");
	});

}

整体的功能比较简单。vscode提供的API相当丰富。这个只是一个比较简单的尝试。

上线

  • 方法一:直接把文件夹发给别人,让别人找到vscode的插件存放目录并放进去,然后重启vscode,一般不推荐;
  • 方法二:打包成vsix插件,然后发送给别人安装,如果你的插件涉及机密不方便发布到应用市场,可以尝试采用这种方式;
  • 方法三:注册开发者账号,发布到官网应用市场,这个发布和npm一样是不需要审核的。

本地打包

无论是本地打包还是发布到应用市场都需要借助vsce这个工具。

安装:npm i vsce -g
打包成vsix文件:vsce package

生成好的vsix文件不能直接拖入安装,只能从扩展的右上角选择Install from VSIX安装。

发布到应用市场

注册账号

访问 https://login.live.com/ 登录你的Microsoft账号,然后访问: https://aka.ms/SignupAzureDevOps, 进入组织的主页后,点击右上角的Security。点击创建新的个人访问令牌,这里特别要注意Organization要选择all accessible organizations,Scopes要选择Full access,否则后面发布会失败。

创建发布账号

获得个人访问令牌后,使用vsce以下命令创建新的发布者:vsce create-publisher your-publisher-name

发布

vsce publish // 发布
vsce publish patch // 增量发布
vsce unpublish (publisher name).(extension name) // 取消发布
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值