By Qinqi
Most frontend developers have used VsCode. It is a handy tool, and its powerful plug-in capability undoubtedly makes us fall deeply in love with it. According to incomplete statistics, the number of VsCode plug-ins in the plug-in market has exceeded 30,000, which shows how enthusiastic everyone is about VsCode plug-ins. Plug-ins involve various features, such as thematic songs and code development, including code snippets, Git plug-ins, tslint, etc. As a developer, you must have used various plug-ins for code hinting represented by TabNine, Copilot, etc. Today, let's develop a dedicated code hinting plug-in by ourselves.
There are many tutorials on the development environment setup of VsCode plug-ins online, which will not be repeated in this article. Please refer to this link for more details.
The code hinting here means that in the process of writing code, based on the current input, VsCode will pop up with a panel showing some of the possible input. If there is the input you expect, you can directly press the Enter
or Tab
key (which can be modified in the setting) to enter the recommended code into the editor. This can improve the efficiency of development. After all, writing a line of code by directly pressing a key is far more efficient than typing characters one by one.
So far, you may have been curious about a few things. Where does the code come from among so many recommended options? Why are some options recommended that you do not expect at all? According to my research (I have not seen the source code), the sources of those options are listed below:
1. The specific implementation of Language Service Protocol (LSP) is the language supported by VsCode. For example, if you select TypeScript
, when you write code, there will be hints related to ts syntax. For example, if con
is entered, the const
, console
, and continue
are keywords in ts syntax.
2. Various Built-In Code Snippets: VsCode has many built-in code snippets, which can also help us input quickly. General code snippets have more than one line of code, which can help us omit a lot of input. In addition to the built-in code snippets, we can configure our code snippets, which are also part of our dedicated plug-ins.
3. Object Path and Exported Object Hints: For example, I set an APP
constant and a Test
method in another file. Then, if I enter the AP
in the current file, I can see that the first item is the constant defined previously. After pressing the Tab
key at this time, the variable name will be completed, and the import
sentence will be added at the top.
4. The last part is options provided by various plug-ins. This part is also the main content of our development of the dedicated plug-ins today. The numerous plug-ins have brought a lot of hints, but they have also increased the burden on us to identify and think. We are required to find the code we want among pages of hints, but we would have already typed out the whole code during that time. Therefore, a plug-in is not a panacea, and more plug-ins do not lead to better effects. It is enough to install some commonly used and easy-to-use plug-ins.
There are two ways to configure code snippets:
1. The code snippets are directly configured in VsCode:
typescriptrect
here, which is the commonly used .tsx
file. (This is the key
of the tsx
file in VsCode
.)Python
. All we have to do is add our code snippets in this json file.2. Plug-ins for developing code snippets:
At the same time, you can develop a plug-in related to a code snippet, so no matter where you are, the corresponding plug-in directly downloaded can be common to multiple editors, which is much better than saving locally. The development of plug-ins of code snippets is relatively simple and only requires two steps:
package.json
: The effect is to declare the information related to the code snippets, including the corresponding language, which is, the file type and paths corresponding to the code snippets. The following shows the same configuration file applied to ts
, tsx
, js
, and jsx
files at the same time."contributes": {
"snippets": [
{
"language": "typescriptreact",
"path": "./snippets.json"
},
{
"language": "typescript",
"path": "./snippets.json"
},
{
"language": "javascript",
"path": "./snippets.json"
},
{
"language": "javascriptreact",
"path": "./snippets.json"
}
]
},
The code snippets are relatively simple, which configure some fixed modes and enter them directly through shortcut keys. Here are several ideas:
"component": {
"prefix": [
"component"
],
"body": [
"import * as React from 'react';",
"",
"export interface IProps {",
"\t${1}",
"}",
"",
"const ${2}: React.FC<IProps> = (props) => {",
"\tconst { } = props;",
"",
"\treturn (",
"\t\t<div className=\"component-$3\">",
"\t\t\t$4",
"\t\t</div>",
"\t);",
"};",
"",
"export default ${2};",
"",
],
"description": "Generate component templates"
},
"import": {
"prefix": "import",
"body": [
"import ${1} from '${2}';"
],
"description": "import"
}
region
and write the operation down as a code snippet. "region": {
"prefix": "region",
"body": [
"// #region ${1}\n ${2}\n// #endregion"
],
"description": "customized code blocks"
},
Tips: There are many variables above, such as ${1}. Please see the official documents for more information. It is convenient to record some commonly used and fixed templates.
Let's customize our dedicated plug-ins.
First of all, after the scaffold is initialized, let's look at the code directory. The extension.ts
in src directory is the code of plug-ins we want to write, and we can see that the initialized file looks like this:
It contains two methods, activate
and deactivate
, and a large number of comments. Generally, each plug-in has its own lifecycle, and these two lifecycle methods correspond to the lifecycles of activation and deregistration of a plug-in. Our main recommendation logic is also written in the activate
method.
The most basic API we use is the registerCompletionItemProvider
, which is located under the vscode.languages
namespace. As the name implies, this method registers a provider for code completion. Please see the official documents for more information on API.
import * as vscode from 'vscode';
/** Supported language type */
const LANGUAGES = ['typescriptreact', 'typescript', 'javascript', 'javascriptreact'];
export function activate(context: vscode.ExtensionContext) {
/** Trigger a list of recommended characters */
const triggers = [' '];
const completionProvider = vscode.languages.registerCompletionItemProvider(LANGUAGES, {
async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
const completionItem: vscode.CompletionItem = {
label: 'Hello VsCode',
};
return [completionItem];
}
}, ...triggers);
context.subscriptions.push(completionProvider);
}
The section above is the most basic code for code completion. Register a completionProvider
and return the vscode.CompletionItem
array. You can see the result of the code above by pressing F5.
The effect of the demo above is not what we expected. Since our goal is to develop dedicated plug-ins, it must be something different.
If you are weak in English, you have to look up a slightly longer word in a dictionary. Why not use a plug-in to help us achieve this operation? The idea is simple. It is only requires a well-compiled English dictionary, download it to the local drive, and then look up the current input in the dictionary every time to return the best matching word. Here is the simplest implementation logic:
import * as vscode from 'vscode';
/** Supported language type */
const LANGUAGES = ['typescriptreact', 'typescript', 'javascript', 'javascriptreact'];
const dictionary = ['hello', 'nihao', 'dajiahao', 'leihaoa'];
export function activate(context: vscode.ExtensionContext) {
/** Trigger a list of recommended characters */
const triggers = [' '];
const completionProvider = vscode.languages.registerCompletionItemProvider(LANGUAGES, {
async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
const range = new vscode.Range(new vscode.Position(position.line, 0), position);
const text = document.getText(range);
const completionItemList: vscode.CompletionItem[] = dictionary.filter(item => item.startsWith(text)).map((item, idx) => ({
label: item,
preselect: idx === 0,
documentation: 'My dedicated VsCode plug-ins provider',
sortText: `my_completion_${idx}`,
}));
return completionItemList;
}
}, ...triggers);
context.subscriptions.push(completionProvider);
}
Here is the effect:
The code snippet above still needs a lot to improve, such as:
lh
, leihaoa
is recommended. Another way is to add no matching logic. No matter what input is, it will be thrown to VsCode, and VsCode matches itself. This is also possible. However, when your dictionary is large, it is not good enough. It is better to do a simple screening by yourself first.There is nothing suiting you better than personalized code completion. After all, no one knows you better than you. Our general idea is simple and does not involve deep learning or the like. It requires you to record your input in the process of writing code and then process this data and form a document similar to a dictionary. The method is similar to the word completion mentioned above: looking up the input in the dictionary to obtain the best matching recommendation. At the same time, this dictionary must be updated automatically to meet our personalized requirements. Here are a few things to do:
Simple ideas:
1. Take the code of your code library directly for extraction and processing to form an initial dictionary. Theoretically, the richer the code library, the more accurate the dictionary. However, it causes another problem:
2. You can record the current document contents and update the dictionary every time you accept recommendations.
The process of transforming code into a dictionary and the code for automatically updating the dictionary are not displayed in this article. The preceding code is modified, and the general code is listed below:
import * as vscode from 'vscode';
/** The command triggered when the recommended item is registered */
function registerCommand(command: string) {
vscode.commands.registerTextEditorCommand(
command,
(editor, edit, ...args) => {
const [text] = args;
// TODO records the current content in the dictionary and automatically updates the dictionary.
}
);
}
/** Supported language type */
const LANGUAGES = ['typescriptreact', 'typescript', 'javascript', 'javascriptreact'];
const dictionary = ['hello', 'nihao', 'dajiahao', 'leihaoa'];
/** Commands that are triggered after the user chooses items */
const COMMAND_NAME = 'my_code_completion_choose_item';
export function activate(context: vscode.ExtensionContext) {
/** Trigger a list of recommended characters */
const triggers = [' '];
registerCommand(COMMAND_NAME);
const completionProvider = vscode.languages.registerCompletionItemProvider(LANGUAGES, {
async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext) {
const range = new vscode.Range(new vscode.Position(position.line, 0), position);
const text = document.getText(range);
const completionItemList: vscode.CompletionItem[] = dictionary.filter(item => item.startsWith(text)).map((item, idx) => ({
label: item,
preselect: idx === 0,
documentation: 'My dedicated VsCode plug-ins provider',
sortText: `my_completion_${idx}`,
command: {
arguments: [text],
command: COMMAND_NAME,
title: 'choose item'
},
}));
return completionItemList;
}
}, ...triggers);
context.subscriptions.push(completionProvider);
}
There is an additional registerCommand
method, compared with word completion, and a command
parameter is added to each recommended item. The logic is to trigger this command every time a recommended item is chosen and then update the dictionary. The implementation is for reference only. If you want to do it better, you can try it:
The simple examples of code completion mentioned above show the ability of the VsCode plug-ins to assist development. It is not difficult to write a plug-in. I hope you can write personalized plug-ins. At the same time, I expect to provide you with an idea. In the development, you can try some ideas by writing plug-ins that may be amazing tools for improving efficiency.
Understand the Difference between Computer Vision (CV) and Computer Graphics (CG)
66 posts | 3 followers
FollowLouis Liu - August 27, 2019
Alibaba Cloud Community - June 27, 2023
Louis Liu - August 26, 2019
Alibaba Cloud Native - July 20, 2023
Alibaba Cloud Serverless - March 2, 2020
淘系技术 - November 4, 2020
66 posts | 3 followers
FollowExplore Web Hosting solutions that can power your personal website or empower your online business.
Learn MoreA low-code development platform to make work easier
Learn MoreExplore how our Web Hosting solutions help small and medium sized companies power their websites and online businesses.
Learn MoreHelp enterprises build high-quality, stable mobile apps
Learn MoreMore Posts by Alibaba F(x) Team