VSCode插件开发全攻略之跳转到定义、自动补全、悬停提示功能

跳转到定义

跳转到定义其实很简单,通过vscode.languages.registerDefinitionProvider注册一个provider,这个provider如果返回了new vscode.Location()就表示当前光标所在单词支持跳转,并且跳转到对应location。

为了示例更加有意义,我在这里写了一个支持package.jsondependenciesdevDependencies跳转到对应依赖包的例子jump-to-definition.js(当然我们这里只是很简单的实现,没有考虑特殊情况,直接从node_modules文件夹下面去找):

代码如下:

/**
 * 跳转到定义示例,本示例支持package.json中dependencies、devDependencies跳转到对应依赖包。
 */
const vscode = require('vscode');
const path = require('path');
const fs = require('fs');
const util = require('./util');

/**
 * 查找文件定义的provider,匹配到了就return一个location,否则不做处理
 * 最终效果是,当按住Ctrl键时,如果return了一个location,字符串就会变成一个可以点击的链接,否则无任何效果
 * @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('====== 进入 provideDefinition 方法 ======');
 console.log('fileName: ' + fileName); // 当前文件完整路径
 console.log('workDir: ' + workDir); // 当前文件所在目录
 console.log('word: ' + word); // 当前光标所在单词
 console.log('line: ' + line.text); // 当前光标所在行
 console.log('projectPath: ' + projectPath); // 当前工程目录
 // 只处理package.json文件
 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) 表示跳转到某个文件的第一行第一列
  return new vscode.Location(vscode.Uri.file(destPath), new vscode.Position(0, 0));
  }
 }
 }
}

module.exports = function(context) {
 // 注册如何实现跳转到定义,第一个参数表示仅对json文件生效
 context.subscriptions.push(vscode.languages.registerDefinitionProvider(['json'], {
 provideDefinition
 }));
};

注意不要忘了修改activationEvents

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

new vscode.Location接收2个参数,第一个是要跳转到文件的路径,第二个是跳转之后光标所在位置,接收Range或者Position对象,Position对象的初始化接收2个参数,行row和列col。

高亮显示范围

这里有一个问题我一直没找到解决方案,如下图所示:

当按住Ctrl跳转的时候,虽然可以控制跳转目标位置,但是却无法控制高亮显示的范围,下图我本应该让page/video/list.html全部变成蓝色的,但是默认却只能以单词为粒度变色,这个问题我找了很久官方文档就是没找到解决办法,如果大家有知道的欢迎评论指出。

自动补全

通过vscode.languages.registerCompletionItemProvider方法注册自动完成实现,接收3个参数:

  • 第一个是要关联的文件类型;
  • 第二个是一个对象,里面必须包含provideCompletionItems和resolveCompletionItem这2个方法;
  • 第三个是一个可选的触发提示的字符列表;

这里我们实现这样一个例子,当输入this.dependencies.xxx时自动把package.json中的依赖全部带出来,包括dependencies、devDependencies,就像这样:

实现代码如下:

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

/**
 * 自动提示实现,这里模拟一个很简单的操作
 * 当输入 this.dependencies.xxx时自动把package.json中的依赖带出来
 * 当然这个例子没啥实际意义,仅仅是为了演示如何实现功能
 * @param {*} document
 * @param {*} position
 * @param {*} token
 * @param {*} context
 */
function provideCompletionItems(document, position, token, context) {
 const line = document.lineAt(position);
 const projectPath = util.getProjectPath(document);

 // 只截取到光标位置为止,防止一些特殊情况
 const lineText = line.text.substring(0, position.character);
 // 简单匹配,只要当前光标前的字符串为`this.dependencies.`都自动带出所有的依赖
 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 表示提示的类型
  return new vscode.CompletionItem(dep, vscode.CompletionItemKind.Field);
 })
 }
}

/**
 * 光标选中当前自动补全item时触发动作,一般情况下无需处理
 * @param {*} item
 * @param {*} token
 */
function resolveCompletionItem(item, token) {
 return null;
}

module.exports = function(context) {
 // 注册代码建议提示,只有当按下“.”时才触发
 context.subscriptions.push(vscode.languages.registerCompletionItemProvider('javascript', {
 provideCompletionItems,
 resolveCompletionItem
 }, '.'));
};

悬停提示

从上面的跳转到定义我们可以看到,虽然我们只是定义了如何调整,到按住Ctrl键但是不点击的时候,vscode默认就会帮我们预览一部分内容作为提示,除此之外,如果想获得更多的提示,我们还可以通过vscode.languages.registerHoverProvider命令来实现。

下面我们依然通过package.json中依赖跳转的例子来演示如何实现一个自定义hover,如下标红的内容是我们自己实现的,当鼠标停在package.json的dependencies或者devDependencies时,自动显示对应包的名称、版本号和许可协议:

如何实现的呢?也很简单,我们直接上代码:

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

/**
 * 鼠标悬停提示,当鼠标停在package.json的dependencies或者devDependencies时,
 * 自动显示对应包的名称、版本号和许可协议
 * @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('进入provideHover方法');
 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已生效');
  // hover内容支持markdown语法
  return new vscode.Hover(`* **名称**:${content.name}\n* **版本**:${content.version}\n* **许可协议**:${content.license}`);
  }
 }
 }
}

module.exports = function(context) {
 // 注册鼠标悬停提示
 context.subscriptions.push(vscode.languages.registerHoverProvider('json', {
 provideHover
 }));
};

有些时候某个字段可能本身已经有提示内容了,如果我们仍然给它注册了hover的实现的话,那么vscode会自动将多个hover内容合并一起显示。

总结

到此这篇关于VSCode插件开发全攻略之跳转到定义、自动补全、悬停提示功能的文章就介绍到这了,更多相关VSCode插件开发 跳转到定义、自动补全、悬停提示内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • VSCode插件开发全攻略之打包、发布、升级的详细教程

    一.发布方式 插件开发完了,如何发布出去分享给他人呢?主要有3种方法: 方法一:直接把文件夹发给别人,让别人找到vscode的插件存放目录并放进去,然后重启vscode,一般不推荐: 方法二:打包成vsix插件,然后发送给别人安装,如果你的插件涉及机密不方便发布到应用市场,可以尝试采用这种方式: 方法三:注册开发者账号,发布到官网应用市场,这个发布和npm一样是不需要审核的. 二.本地打包 无论是本地打包还是发布到应用市场都需要借助vsce这个工具. 安装: npm i vsce -g 打包成v

  • vscode extension插件开发详解

    最近公司要使用vscode作为开发工具,需要对vscode做一些定制功能,比如snippet提示,内容提示,以及其他插件集成等,为此做了一些调查,并做了一定的开发与支持. 官方文档 https://code.visualstudio.com/docs 上面是vscode官方提供的extension开发帮助,按照上面的步骤基本上可以做简单的demo事例 如下主要介绍下自己在开发中做的几个简单功能: 1. Snippet 感觉vscode的snippet功能真的很强大,只要编辑相应的json配置文件

  • VsCode插件开发之插件初步通信的方法步骤

    参考了Egret Wing,想像Egret Wing那样在上方titlebar最右边上面增加一个menu(这个menu相对于一个按钮,当点击这个按钮时会出现一个window弹框,这个window弹框里就包含相关的表单信息以供登录或者注册使用.我是以这个作为参考模板的.但是目前进展并不是很顺.于是我通过插件的方式暂时性解决了这个问题.但是觉得还不是想要的那样. Egret Wing是这样的,如图所示: 不得不承认一点Egret Wing改造的挺不错的,不愧是对VsCode进行魔改. 今天先说一下通

  • VSCode插件开发全攻略之命令、菜单、快捷键

    命令 我们在前面HelloWord章节中已经提到了命令写法,这里再重温一下. context.subscriptions.push(vscode.commands.registerCommand('extension.sayHello', () => { vscode.window.showInformationMessage('您执行了extension.sayHello命令!'); })); 然后在清单文件声明: "commands": [ { "command&q

  • VSCode插件开发全攻略之package.json详解

    package.json 在详细介绍vscode插件开发细节之前,这里我们先详细介绍一下vscode插件的package.json写法,但是建议先只需要随便看一下,了解个大概,等后面讲到具体细节的时候再回过头来看. 如下是package.json文件的常用配置,当然这里还不是全部: { // 插件的名字,应全部小写,不能有空格 "name": "vscode-plugin-demo", // 插件的友好显示名称,用于显示在应用市场,支持中文 "displa

  • VSCode插件开发全攻略之跳转到定义、自动补全、悬停提示功能

    跳转到定义 跳转到定义其实很简单,通过vscode.languages.registerDefinitionProvider注册一个provider,这个provider如果返回了new vscode.Location()就表示当前光标所在单词支持跳转,并且跳转到对应location. 为了示例更加有意义,我在这里写了一个支持package.json中dependencies.devDependencies跳转到对应依赖包的例子jump-to-definition.js(当然我们这里只是很简单的

  • vim自动补全插件YouCompleteMe(YCM)安装过程解析

    Vim是全平台上一个高度可拓展的编辑器.它本身只是一个简陋的编辑器,但是因为有各种插件而变得强大.使用Vim编写代码就不免遇到代码补全的问题.常用的代码补全插件有两个:日本人shougo写的neocomplete和前Google工程师Valloric写的YouCompleteMe.用的人比较多的还是YouCompleteMe.YouCompleteMe被称为Vim最难配置的插件,当初配置好YouCompleteMe也是费了九牛二虎之力,印象中是花了整整一个晚上.回报也是显然的,支持定义跳转,变量

  • ajax来自动补全表单字段示例

    源代码: 脚本一: <!DOCTYPE html> <html> <head> <title>Auto-fill Form Fields</title> <link rel="stylesheet"href="script06.css" rel="external nofollow" > <script src="script06.js">&l

  • QQ密码破解与对策全攻略

    QQ密码破解与对策全攻略 一.本地破解  方法:  这个办法的首要条件是你所在的机器开过你想要的QQ号,这又分两种情况,一是你所在的机器真的 曾经开过这个号码,二是通过共享入侵得到你想要的号码的整个目录,把它拷贝到你的OICQ的目录 下,启动OICQ你就能在号码选择下拉列表中看到这个号码了.共享入侵请参看本站黑客教程之 对 共享主机的简单入侵 ,网上硬盘共享最多的就是网吧和公司,而前者的硬盘里存有大量的QQ号码, 只要你能进去且它的OICQ目录或它所在的分区是共享的话,自己慢慢挑吧.但是网上的I

  • Chrome插件(扩展)开发全攻略(完整demo)

    写在前面 我花了将近一个多月的时间断断续续写下这篇博文,并精心写下完整demo,写博客的辛苦大家懂的,所以转载务必保留出处.本文所有涉及到的大部分代码均在这个demo里面:https://github.com/sxei/chrome-plugin-demo ,大家可以直接下载下来运行. 另外,本文图片较多,且图片服务器带宽有限,右下角的目录滚动监听必须等到图片全部加载完毕之后才会触发,所以请耐心等待加载完毕. 本文目录: demo部分截图: 前言 什么是Chrome插件 严格来讲,我们正在说的东

  • 生成PDF全攻略之在已有PDF上添加内容的实现方法

    项目在变,需求在变,不变的永远是敲击键盘的程序员..... PDF 生成后,有时候需要在PDF上面添加一些其他的内容,比如文字,图片.... 经历几次失败的尝试,终于获取到了正确的代码书写方式. 在此记录总结,方便下次以不变应万变,需要的 jar 请移步:生成PDF全攻略 PdfReader reader = new PdfReader("E:\\A.pdf"); PdfStamper stamper = new PdfStamper(reader, new FileOutputStr

  • 微信公众帐号开发教程之图文消息全攻略

    引言及内容概要 已经有几位读者抱怨"柳峰只用到文本消息作为示例,从来不提图文消息,都不知道图文消息该如何使用",好吧,我错了,原本以为把基础API封装完.框架搭建好,再给出一个文本消息的使用示例,大家就能够照猫画虎的,或许是因为我的绘画功底太差,画出的那只猫本来就不像猫吧-- 本篇主要介绍微信公众帐号开发中图文消息的使用,以及图文消息的几种表现形式.标题取名为"图文消息全攻略",这绝对不是标题党,是想借此机会把大家对图文消息相关的问题.疑虑.障碍全部清除掉. 图文消

随机推荐