我写了一个可以保存代码片段的vscode插件,再也不用到处找代码复制了。
背景
前两天准备创建一个midway项目做一个demo,项目创建完成后,需要开启vscode调试功能,这一步官网文档中有写怎么使用vscode调试,并且把到官网,我们只要从官网复制到本地就行了。
我想了一下,这一步操作我已经重复了很多遍,每次都要去官网复制代码,浪费了很多时间。为什么不能把这个做成vscode代码片段,需要的时候直接在vscode中插入需要的代码片段就行了。上面例子只是其中一个,实际上要保存的代码片段还有很多。
vscode是支持定义代码片段的,但是只能在当前项目中定义,需要在新建的项目里,把代码片段复制过去,这样也比较麻烦。
有没有全局定义代码片段的方案呢,有的,可以直接写一个代码片段插件,但是这个不支持动态插入代码片段,不可能每加一个代码片段还要改一下代码片段插件代码,重新发布插件。
网上也有一些代码片段管理工具,但是都是和vscode隔离开的,如果想使用,还得从vscode切出去,我的想法是所有操作都在vscode中进行。
所以我打算自己写一个vscode插件,在用户选中代码的时候,调用我的插件,把选中的代码动态保存到代码片段文件中,当前用户想插入代码片段时,选择前面保存的代码片段插入当前位置。
插件功能演示
导入导出功能,是为了解决不同电脑同步问题,可以把当前的代码片段导出出去,然后在另外一台电脑上导入进来。
实现
创建插件项目
安装脚手架
npm install -g yo generator-code
在合适的目录下执行
yo code
修改package.json文件,配置命令和右键菜单
配置代码片段存放位置
完整配置
{
"contributes": {
"submenus": [
{
"id": "code-snippet",
"label": "代码片段"
}
],
"commands": [
{
"command": "code-snippet.save",
"title": "保存代码片段"
},
{
"command": "code-snippet.insert",
"title": "插入代码片段"
},
{
"command": "code-snippet.import",
"title": "导入配置"
},
{
"command": "code-snippet.export",
"title": "导出配置"
}
],
"menus": {
"editor/context": [
{
"submenu": "code-snippet",
"group": "code-snippet@001",
"when": "editorTextFocus"
}
],
"code-snippet": [
{
"when": "editorHasSelection",
"command": "code-snippet.save",
"group": "code-snippet@001"
},
{
"when": "editorFocus",
"command": "code-snippet.insert",
"group": "code-snippet@002"
},
{
"when": "editorFocus",
"command": "code-snippet.import",
"group": "code-snippet@003"
},
{
"when": "editorFocus",
"command": "code-snippet.export",
"group": "code-snippet@004"
}
]
},
"snippets": [
{
"path": "./snippets/snippets.code-snippets"
}
],
}
}
"when": "editorHasSelection"
表示只有选中代码,才会显示保存代码片段,其他都是编辑器获取焦点时显示。
在插件项目根目录下创建/snippets/snippets.code-snippets
文件,内容为{}
,存放后面用户保存的代码片段。
实现保存代码片段
实现思路
我的实现思路是先获取当前选中的代码,然后打开一个webview预览当前选中的代码,在webview里添加一个保存代码片段按钮,当用户点击保存代码片段按钮,让用户输入当前要保存的代码片段名称和代码片段类型,然后把数据存入到用户本地文件中。
实现代码
在extension.js文件activate事件中,注册code-snippet.save命令
获取当前选中的代码
创建webview预览代码
预览代码使用的是highlight.js库,可以在原生html中使用。
文件 html/preview.html 里的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/atom-one-dark.min.css"
integrity="sha512-Jk4AqjWsdSzSWCSuQTfYRIF84Rq/eV0G2+tu07byYwHcbTGfdmLrHjUSwvzp5HvbiqK4ibmNwdcG49Y5RGYPTg=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/javascript.min.js"
integrity="sha512-XrpvbK+zc0wErJG1VptH0H4w4zyiniHOBR35DJ1VISA+cqYxhksvqFwZk0M8lX9ylaIjTXoMYolOPb93zdrGpg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
code {
background-color: transparent !important;
line-height: 1.5;
font-size: 16px;
}
.button-box {
position: fixed;
right: 10px;
top: 16px;
}
.btn {
outline: none;
position: relative;
display: inline-block;
font-weight: 400;
white-space: nowrap;
text-align: center;
background-image: none;
background-color: transparent;
border: 1px solid transparent;
cursor: pointer;
transition: all .2s cubic-bezier(.645, .045, .355, 1);
user-select: none;
touch-action: manipulation;
line-height: 1.5714285714285714;
color: rgba(0, 0, 0, .88);
font-size: 14px;
height: 32px;
padding: 4px 15px;
border-radius: 6px;
color: #fff;
background-color: #1677ff;
box-shadow: 0 2px 0 rgba(5, 145, 255, .1);
}
.btn:hover {
background-color: #1677ffee;
}
</style>
</head>
<body>
<pre><code id="code"></code></pre>
<div class="button-box">
<button class="btn">保存当前代码片段</button>
</div>
<script>
const vscode = acquireVsCodeApi();
let language;
let code;
// 监听vscode发送过来的消息
window.addEventListener('message', e => {
// 高亮代码
const result = hljs.highlightAuto(e.data);
language = result.language;
code = e.data;
// 渲染高亮代码
document.querySelector('#code').innerHTML = result.value;
})
// 监听保存按钮点击事件
document.querySelector('.btn').addEventListener('click', () => {
// 发送保存消息
vscode.postMessage({ type: 'save', code, language });
})
</script>
</body>
</html>
在vscode中把选中的代码发给webview,并且监听当前选中内容变化,如果变化把最新的发送给webview预览
监听webview里发送的保存代码片段事件,调用save方法保存代码
save方法实现
插入代码片段
实现思路
先从本地获取以保存的代码片段,然后创建webview展示这些代码片段,用户可以选择其中一个代码代码插入到当前光标位置,可以复制选择的代码片段到剪切板,也可以删除代码片段。
实现代码
在extension.js文件activate事件中,注册code-snippet.insert命令
获取当前编辑器和当前编辑器的标识
获取本地已保存的所有代码片段
创建webview展示所有代码片段
在html/list.html
文件里使用监听vscode传过来的代码片段
动态创建html元素,渲染代码片段列表
监听代码片段点击事件,预览当前代码片段代码
监听复制按钮点击事件,将代码片段复制到剪贴板
监听插入按钮点击事件,将代码片段插入到当前编辑器中
监听删除按钮点击事件,将代码片段从列表中移除
在vscode中监听webview发送过来的数据
删除代码片段方法实现
导出配置
在extension.js文件activate事件中,注册code-snippet.export命令,并实现导出方法
导入配置
在extension.js文件activate事件中,注册code-snippet.import命令,并实现导出方法
后续计划
- 现在保存代码片段只能是写死的代码,其实vscode自带的代码片段是支持变量的,后续打算在预览代码的时候,可以编辑代码,允许把一些关键字设置为变量。
- 把配置存放到远程,做一个代码片段市场,这样大家可以共享代码片段。
最后
可以在vscode插件市场里搜索代码片段助手
关键字,安装此插件。
插件源码地址:github.com/dbfu/code-s…
转载自:https://juejin.cn/post/7397024981571780647