vscode Voice notes , Enrich information ( On )
I will make this series " Voice notes " The whole process of plug-ins is shared , Or that sentence ' The process ' Than ' result ' More interesting .
Usage display
download : voice-annotation
To configure + establish Voice file storage address
Right click to exhale ' Record audio notes '
After recording, click ' Save to project '
Hover to play voice
background
When you start reading a copy of engineering code , You may occasionally read code that you don't know what to expect , If it has notes but is still confused after reading, or it doesn't write notes at all , The most convenient way to solve this problem is to ask the original developer directly , Why do you write this here ?
Not only is js In language , Most languages already offer " Text notes " The grammar of , Why do we still encounter the above problems ? Suppose we write comments in every piece of code, but we still can't understand , To see what the problems are, we can use the voice plug-in " relieve " Of :
- It's very clear , It is indeed the reader's own problem to not understand (
Unable to resolve) - I wrote it but didn't understand it , Developer's own expression ability (
Unable to resolve, Be situated between " The Dake effect "&" The curse of knowledge " Not self aware ) - Maybe it has something to do with a few needs , It is very clear to describe in words ' complex ', I don't want to write any more (
Maybe it can alleviate) - The form of words is not clear , It is common in our daily communication , It's not clear online , Face to face solo (
Maybe it can alleviate) - A two page description , For example, a large paragraph of " Debugging method ", Which variable to hide , Forcibly assign a variable , Certain operations can achieve certain effects , Often used in the front end mock Some scenes (
Maybe it can alleviate)
I haven't vscode Plug in students are recommended to read the introductory tutorial I wrote first :
- Remember the front end once "vscode Plug in writing actual combat " Super detailed sharing ( Suggest collection )( Part 1 )
- Remember the front end once "vscode Plug in writing actual combat " Super detailed sharing ( Suggest collection )( The next part )
One 、 The function point ' Technical solution ' analysis
① Identify specific comments
We need to agree on a specific way of writing , The plug-in recognizes this as " Voice notes ", And when the mouse hovers over it, it can broadcast correctly , What I am currently using is // voice_annotation + _ Numbers This form .
② Play annotation audio
Since it is written in vscode Inside , In fact, the first choice is to use node To control the audio output device , If you open a web Play sounds in the way of new pages , It will increase the user's operating link , Investigated the existing audio plug-ins in the market , Mainly through the music playing plug-in or by opening web The way of the page , But we don't have any other operations for playback here , For example, fast forward loop playback and other slightly more complex requirements , So choose to use node Play .
③ Record notes
If you want to eat eggs, you must lay eggs , The recording function must be able to put the user's recording into the corresponding project , Return to the user ' Specific notes ' Writing , Suppose we return to voice_annotation_20220201, Users can paste it directly into the project and use it normally , There should not be many usage scenarios for this function , So consider performance related issues .
④ Store audio information
Most developers have more than one project on their computers , How to enable each project to accurately play the voice under the corresponding project , And the generated audio file can be put into the corresponding project after each recording , And it can support the team to use .
Two 、 Initial Engineering , This time we use ts
Global installation vscode development tool , And initialize the project :
npm install -g yo generator-code
yo code (ts It's really delicious ) Previous plug-ins were developed using native js Development , Because the plug-ins developed this time will use some ' Obscure " Of api, Frankly speaking vscode The documentation is not very friendly , So let's look directly at the code ts Type is the most convenient .
"activationEvents": [
"onStartupFinished"
], Came to package.json In the document , Modify the configuration of plug-in activation here :
onStartupFinished Specifies that the plug-in vscode Start after the initialization is completed , It does not take up user initialization vscode Time performance , And our voice annotation is not an emergency program .
Came to extension.ts In the document , Empty all useless code
Before emptying
After emptying
perform yarn watch Start compiling the code ,fn + F5 Debugging code will report an error :
I'm also confused to see the error report above , Before using native js It seems that I haven't encountered , I'll give it back vscode The editor still reports an error when it is upgraded , Then I checked the code :
This is very clear , Let's circle a compatibility range , Check the official website log , Finally, the lowest 2020 year 10 The version in about months .
"engines": {
"vscode": "^1.50.0"
}, Sure enough, the prompt box will appear after debugging again :
it is to be noted that :
At the bottom of the @types/vscode Also change to the same version number as above , Otherwise, no error will be reported at this stage , Errors will be reported when packaging and publishing .
"dependencies": {
"@types/vscode": "^1.50.0",
}3、 ... and 、 Identify special notes
This function is to identify the "voice-annotation" And highlight , The priority to develop this function is that it is relatively independent in its own functions , And you can see the effect intuitively , Browse vscode On the official website, I found two ways to implement specific statements ' The highlighted ' The effect of .
Here we can predefine several identifications " Voice notes " Regular , Suppose there is such a string of characters // voice_annotation_202202070612135678, First we have to identify // annotator , Get '//' hinder voice_annotation_202202070612135678 This string of characters can give it ' style ', And match the numbers in the content 202202070612135678, In this way, the voice can be played accurately .
stay src/util/index.ts
export const targetName = "voice_annotation"; // Take it out separately to facilitate subsequent changes
export const getAllTargetReg = new RegExp(`//\\s(${targetName}_\\d+)`, "g");
export const testTargetReg = new RegExp(`${targetName}_(\\d+)`);Four 、 Scheme 1 : Custom syntax highlighting
such as js In this way function (){}, Is the syntax of the function , in Is a keyword , These meaningful expressions are endowed with various ' The highlighted ', Then we can put // voice_annotation Set as keyword ,
First step : stay package.json File joining jojo Scope
It works on js、ts、tsx file .
"contributes": {
"grammars": [
{
"path": "./syntaxes/injection.json",
"scopeName": "jojo.injection",
"injectTo": [
"source.js",
"source.ts",
"source.tsx"
]
}
]
}, The second step : establish injection.json file
{
"scopeName": "jojo.injection",
"injectionSelector": "L:comment.line.double-slash",
"patterns": [
{
"include": "#jojo"
}
],
"repository": {
"jojo": {
"match": "jojo_ Gold experience ",
"name": "support.constant.color.0xFF00.css",
"settings": {
"foreground": "FFFFFF"
}
}
}
}
scopeNameThe scope name is defined as the name implies .injectionSelectorDefines the effective scope of the scope , This means yes//The following contents take effect .jojo.matchMatch keywords .jojo.nameThis is a little special , It defines the keyword style , But it is not ordinary css style , Instead, you need to define it in the file that defines the language style , Then it can only be used here .
There are many disadvantages in this scheme , Like bad ' Custom style ', It's not good to change settings dynamically, etc , Finally, I didn't choose this implementation .
5、 ... and 、 Option two : Document Retrieval
That is to get the current location ' file ' All text content of , Give it something like css The ability of style , This way is more flexible , And through Pseudo elements Achieve some interesting effects .
First, we need to abstract out a single initVoiceAnnotationStyle Method , This method is specifically used to set voice-annotation The style of , It is convenient to identify at any time " Voice notes ":
extension.ts Make changes in the document
import * as vscode from 'vscode';
import initVoiceAnnotationStyle from './initVoiceAnnotationStyle'; // newly added
export function activate(context: vscode.ExtensionContext) {
initVoiceAnnotationStyle() // newly added
context.subscriptions.push( // newly added
vscode.window.onDidChangeActiveTextEditor(() => {
initVoiceAnnotationStyle()
})
)
}
export function deactivate() { }
context.subscriptions.pushIs to register the command , Here is the registration of a lifecycle event .vscode.window.onDidChangeActiveTextEditorListened when we were vscode Event of switching development files in , That is, every time you open a file , The reason for using this , Because of our ' Voice notes ' Almost unchanged , There is no need to occupy vscode Performance of .
Definition of style
initVoiceAnnotationStyle file
import * as vscode from 'vscode';
import { getAllTargetReg } from './util/index'
export default function () {
vscode.window.visibleTextEditors.map((res) => {
const documentText = res.document.getText();
const decorator = vscode.window.createTextEditorDecorationType({
color: 'gray',
cursor: "pointer",
textDecoration: "underline",
before: {
contentText: "",
width: "10px",
height: '10px',
margin: "0 8px 0 0"
}
})
let n;
const ranges = [];
while (n = getAllTargetReg.exec(documentText)) {
const startPos = res.document.positionAt(n.index + 3);
const endPos = res.document.positionAt(n.index + 3 + n[1].length);
const range = new vscode.Range(startPos, endPos)
ranges.push(range);
}
res.setDecorations(decorator, ranges)
})}The knowledge here is very interesting , With the screenshot
vscode.window.visibleTextEditorsYou can understand it as getting to the present ' Activate ' Code edit page properties , It includes the lines you have read , Whether certain styles are activated .res.document.getText()Get the contents of the currently active page .vscode.window.createTextEditorDecorationTypeMake a pattern , Only a few fixed styles are defined here , But the great thing is that it can make ' Pseudo elements ' In this way, the playing methods will be diversified , We can print out the returned results .Back here
keyIs actually aclassName.rangesUsed to recordvoice-annotationStart position and end position .- The reason for choosing
whileLoop to handle , Because there may be multiplevoice-annotation. n.index + 3Because// voice-annotationAt the front is//I choose to keep this as it is .
We can adjust the style through vscode Developer tools
6、 ... and 、 hover // voice_annotation Playback style
First of all, we need to define a new hover modular , This module is responsible for hover After style + Play the audio .
extension.ts increase :
import * as vscode from 'vscode';
import hover from './hover'; // newly added
import initVoiceAnnotationStyle from './initVoiceAnnotationStyle';
export function activate(context: vscode.ExtensionContext) {
initVoiceAnnotationStyle()
context.subscriptions.push(hover); // newly added
context.subscriptions.push(
vscode.window.onDidChangeActiveTextEditor(() => {
initVoiceAnnotationStyle()
})
)
}
export function deactivate() { }
Define the contents of the file
hover.ts
import * as vscode from 'vscode';
import { getVoiceAnnotationDirPath, targetName, testTargetReg } from './util'
let stopFn: () => void;
function playVoice(id: string) {
// Here is the logic of playing audio ...
}
export default vscode.languages.registerHoverProvider("*", {
provideHover(documennt: vscode.TextDocument, position: vscode.Position) {
stopFn?.()
const word = documennt.getText(documennt.getWordRangeAtPosition(position));
const testTargetRes = testTargetReg.exec(word);
if (testTargetRes) {
playVoice(testTargetRes[1])
return new vscode.Hover(' Playing ...')
}
}
})
documennt.getText(documennt.getWordRangeAtPosition(position))You can get the currenthoverText content of .testTargetReg.exec(word)Verify the current hover Whether the text of is the target text .return new vscode.Hover(' Playing ...')The text returned here can only bemarkdownThe format of .stopFnIt is the logic to stop playing in the later stage , Because some audio may be very long , We don't want to hear it half way through , Or while listening to one audio, I hover over anotherVoice notesOn , Then we should stop the previous audio and play the current audio .
end
The next article should cover vscode How to play sound , How to transfer and store audio files , Wait for me to jump That's what happened this time , Hope to progress with you .







