The function of jump to definition, automatic completion and hover prompt of vscode plug-in development strategy

Time:2020-11-29

Jump to definition

Jump to the definition is actually very simple, through thevscode.languages.registerDefinitionProviderSign up for oneproviderThis oneproviderIf you returnnew vscode.Location()It means that the current cursor word supports jump, and jump to the corresponding location.

To make the example more meaningful, I write a support herepackage.jsonindependenciesdevDependenciesExample of jumping to the corresponding dependent packagejump-to-definition.js(of course, we just implement it here simply, without considering special circumstances, we can directly use thenode_modulesFind it under the folder:

The code is as follows:

/**
 *Jump to the definition example, which supports package.json Dependencies and devdependencies jump to the corresponding dependency package.
 */
const vscode = require('vscode');
const path = require('path');
const fs = require('fs');
const util = require('./util');

/**
 *Find the provider defined in the file, and return a location if it matches it. Otherwise, it will not be processed
 *The final effect is that when you hold down the CTRL key, if you return a location, the string will become a link that you can click. Otherwise, there is no effect
 * @param {*} document 
 * @param {*} position 
 * @param {*} token 
 */
function provideDefinition(document, position, token) {
 const fileName = document.fileName;
 const workDir = path.dirname(fileName);
 const word = document.getText(document.getWordRangeAtPosition(position));
 const line = document.lineAt(position);
 const projectPath = util.getProjectPath(document);

 console.log ('= = = = = enter provideddefinition method = = = =');
 console.log ('filename: '+ filename); // full path of current file
 console.log ('workdir: '+ workdir); // directory of the current file
 console.log ('word: '+ word); // the word of the current cursor
 console.log ('line: ' +  line.text ); // current cursor line
 console.log ('projectpath: '+ projectpath); // current project directory
 //Processing only package.json file
 if (/\/package\.json$/.test(fileName)) {
 console.log(word, line.text);
 const json = document.getText();
 if (new RegExp(`"(dependencies|devDependencies)":\s*?\{[\s\S]*?${word.replace(/\//g, '\/')}[\s\S]*?\}`, 'gm').test(json)) {
  let destPath = `${workDir}/node_modules/${word.replace(/"/g, '')}/package.json`;
  if (fs.existsSync(destPath)) {
  // new  vscode.Position (0, 0) means to jump to the first line and first column of a file
  return new vscode.Location(vscode.Uri.file(destPath), new vscode.Position(0, 0));
  }
 }
 }
}

module.exports = function(context) {
 //Register how to implement jump to definition. The first parameter indicates that it is only valid for JSON files
 context.subscriptions.push(vscode.languages.registerDefinitionProvider(['json'], {
 provideDefinition
 }));
};

Be careful not to forget to reviseactivationEvents


"activationEvents": [
 "onLanguage:json"
],

new vscode.Location Two parameters are received. The first is the path to jump to the file. The second is the position of the cursor after the jump to receive the range or position object. The initialization of the position object receives two parameters, row row and col.

Highlight range

There is a problem I haven’t found a solution, as shown in the following figure:

When you press and hold Ctrl to jump, although you can control the jump target position, you can’t control the highlighted range. In the figure below, I should have let page / video/ list.html All of them turn blue, but by default, they can only change color according to the granularity of words. I have looked for the official documents for a long time, but I haven’t found a solution to this problem. If you have any information, please comment on it.

Automatic completion

adopt vscode.languages.registerCompletionItemProvider Method registration is completed automatically, and three parameters are received

  • The first is the file type to be associated with;
  • The second is an object, which must contain two methods: providecompletionitems and resolvecompletionitem;
  • The third is an optional character list to trigger the prompt;

Here we implement an example when the input this.dependencies.xxx Automatic control package.json All the dependencies in, including dependencies and devdependencies, are brought out, like this:

The implementation code is as follows:

const vscode = require('vscode');
const util = require('./util');

/**
 *Automatic prompt implementation, here simulates a very simple operation
 *When input this.dependencies.xxx Automatic control package.json Bring out the dependence in
 *Of course, this example has no practical significance, just to demonstrate how to implement the function
 * @param {*} document 
 * @param {*} position 
 * @param {*} token 
 * @param {*} context 
 */
function provideCompletionItems(document, position, token, context) {
 const line = document.lineAt(position);
 const projectPath = util.getProjectPath(document);

 //Only intercept to the cursor position to prevent some special cases
 const lineText = line.text.substring(0, position.character);
 //Simple match, as long as the string in front of the current cursor is` this.dependencies All dependencies are automatically brought out
 if(/(^|=| )\w+\.dependencies\.$/g.test(lineText)) {
 const json = require(`${projectPath}/package.json`);
 const dependencies = Object.keys(json.dependencies || {}).concat(Object.keys(json.devDependencies || {}));
 return dependencies.map(dep => {
  // vscode.CompletionItemKind  Indicates the type of prompt
  return new vscode.CompletionItem(dep, vscode.CompletionItemKind.Field);
 })
 }
}

/**
 *When the cursor selects the current auto complete item, the action will be triggered. In general, there is no need to deal with it
 * @param {*} item 
 * @param {*} token 
 */
function resolveCompletionItem(item, token) {
 return null;
}

module.exports = function(context) {
 //The registration code suggestion prompt is triggered only when "." is pressed
 context.subscriptions.push(vscode.languages.registerCompletionItemProvider('javascript', {
 provideCompletionItems,
 resolveCompletionItem
 }, '.'));
};

Hover prompt

From the above jump to definition, we can see that although we only define how to adjust, when we hold down the CTRL key but do not click, vscode will help us preview part of the content as a prompt by default. In addition, if we want to get more tips, we can also use the vscode.languages.registerHoverProvider Command.

Now we still pass the package.json To demonstrate how to implement a custom hover, we implement the following contents in red, when the mouse stops at package.json When dependencies or devdependencies of, the name, version number and license agreement of the corresponding package will be displayed automatically

How to achieve it? It’s also very simple. We go directly to the code:

const vscode = require('vscode');
const path = require('path');
const fs = require('fs');

/**
 *Mouse hover prompt, when the mouse stops at package.json When the dependencies or devdependencies of the,
 *Automatically display the name, version number and license agreement of the corresponding package
 * @param {*} document 
 * @param {*} position 
 * @param {*} token 
 */
function provideHover(document, position, token) {
 const fileName = document.fileName;
 const workDir = path.dirname(fileName);
 const word = document.getText(document.getWordRangeAtPosition(position));

 if (/\/package\.json$/.test(fileName)) {
 console.log ('enter providehover method ');
 const json = document.getText();
 if (new RegExp(`"(dependencies|devDependencies)":\s*?\{[\s\S]*?${word.replace(/\//g, '\/')}[\s\S]*?\}`, 'gm').test(json)) {
  let destPath = `${workDir}/node_modules/${word.replace(/"/g, '')}/package.json`;
  if (fs.existsSync(destPath)) {
  const content = require(destPath);
  console.log ('hover is in force ');
  //Hover content supports markdown syntax
  return new  vscode.Hover ('* * name * *:${ content.name }\N * * version * *:${ content.version }\N * * license agreement * *:${ content.license }`);
  }
 }
 }
}

module.exports = function(context) {
 //Sign up for hover tips
 context.subscriptions.push(vscode.languages.registerHoverProvider('json', {
 provideHover
 }));
};

Sometimes a field may already have prompt content. If we still register hover implementation for it, vscode will automatically merge and display multiple hover contents together.

summary

This article about vscode plug-in development strategy jump to definition, automatic completion, hover prompt function article introduced here, more related vscode plug-in development jump to definition, automatic completion, hover prompt content, please search the previous articles of developeppaer or continue to browse the related articles below. I hope you can support developeppaer more in the future!

Recommended Today

Can’t you tell a pile from a fool? This article tells you the best way to open heap in Java collection

In the “Java collection framework” in the last article, there is still one big problem that has not been mentioned, that is, priority queue, heap. What is heap? Heap is actually a special kind of queue priority queue. The ordinary queue game rule is very simple: first in first out; but this kind of priority […]