vscode 插件开发 常用接口API

代码开源地址    vscode 插件 蓝色空间: 仅供测试,勿用于生产环境

const vscode = require('vscode')                 // vscode  API 接口
const path = require('path')                     // 路径拼接
const fs = require('fs')                         // 文件操作
const os = require('os')                         // 可获得系统信息 

class 插件服务类 extends 通用nodejs类{ 
 
    constructor(context){        //构造  创建对象实例时会执行一次
        super()
        this.context= context
        this.插件路径 = this.context.extension.extensionPath    //这里包含插件基本信息
    }
   
    字符串_去开头结尾空白(字符串){  return 字符串.replace(/(^[\s]*)|([\s]*$)/g , '')  }
    打开vscode域名信任列表(){ this.执行vscode指令("workbench.action.manageTrustedDomain")  }
   
    //-------杂项
   
    插件重启(标识符id){ this.执行vscode指令("workbench.action.restartExtensionHost", 标识符id)  } //package.json里定义的名字
   
    通过shell查找软件版本号(指令 ,正则表达式){
        return new Promise((成功后回调,失败后回调)=>{
            this.终端_执行shell指令_then(指令)
                .then((返回值)=>{
                        let 版本号=this.查找版本号(正则表达式, 返回值.stdout)
                        成功后回调( 版本号 )//查找版本号
                    })
        })
    }
   
    查找版本号(正则表达式,字符串 ){
        let 数组 =正则表达式.exec(字符串)  //查找版本号
        if(数组===null)  数组=["未安装"]
        return 数组[0]
    }
    

    //-------vscode 指令和配置
    获取用户定义值(配置){  return vscode.workspace.getConfiguration().get(配置)   }
    生效配置(官方配置, 属性){   vscode.workspace.getConfiguration().update( 官方配置, 属性, true )  }
    注册vscode用户指令(指令, 处理函数){  vscode.commands.registerCommand(指令, 处理函数)  }
    注册vscode配置变化事件( 事件函数 ){ return  vscode.workspace.onDidChangeConfiguration( 事件函数  ) }
    
    打开vscode选择主题界面(){ this.执行vscode指令("workbench.action.selectTheme"); }
    async 执行vscode指令(指令,...参数){ return await vscode.commands.executeCommand(指令, ...参数)  }   //可变参数

 
    //-------UI界面 窗口相关
    选择后显示文件(绝对路径, 标题文本, 打开按钮文本){
        vscode.window.showOpenDialog( { defaultUri: vscode.Uri.file(绝对路径) ,
                                        canSelectFiles:true ,
                                        canSelectFolders:false,
                                        canSelectMany:false,
                                        title:标题文本, 
                                        openLabel:打开按钮文本 })     //返回一个数组
                .then( 路径数组 => {
                    if (路径数组 !== undefined)   this.用vscode编辑文件( 路径数组[0].path)   //选择多个文件只打开第一个 
                })                              //获得数据才处理            
    }
    打开窗口选择本地路径文件数组(绝对路径, 标题文本, 打开按钮文本){
        return new Promise(成功后回调 =>{
            vscode.window.showOpenDialog( { defaultUri: vscode.Uri.file(绝对路径) ,
                canSelectFiles:false ,
                canSelectFolders:true,
                canSelectMany:false,        //能否多选
                title:标题文本, 
                openLabel:打开按钮文本 })     //返回一个数组  
            .then(路径数组 => 成功后回调(路径数组))
        })   
    }

    用vscode打开文件2(绝对路径){   //这个只能打开文本
        vscode.workspace.openTextDocument( vscode.Uri.file( 绝对路径 ) )
                .then( 文件 => vscode.window.showTextDocument(文件) ) 
    }

    用系统默认应用打开(文件路径){ vscode.env.openExternal(vscode.Uri.parse(文件路径)) }    

    用vscode编辑文件(绝对路径){  this.执行vscode指令('vscode.open', vscode.Uri.file(绝对路径)) }  //这个比上面显示文件更加全面 
    用vscode预览md文件(文件路径){ this.执行vscode指令("markdown.showPreview" , vscode.Uri.file(文件路径))  }
    用vscode编辑项目(路径){this.执行vscode指令('vscode.openFolder', vscode.Uri.file(路径), true) } 

    生成输出界面(界面名称){ return vscode.window.createOutputChannel(界面名称 )}
    生成按钮(左右, 优先级){        //优先级越高越靠边
        if (左右 === "左边")  return vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 优先级)
        else  return vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 优先级)
    }
    vscode窗口激活事件(){
        vscode.window.onDidChangeWindowState((窗口)=>{ //参数是vscode软件聚焦激活 还是非激活
           
        })
    }
 
    打开插件设置页面(){ this.执行vscode指令( "workbench.action.openSettings","@ext:" + this.context.extension.id ) }  //打开指定的 设置UI
    打开插件某项设置页面(某项设置id){this.执行vscode指令( "workbench.action.openSettings", 某项设置id ) }
    
    打开侧边栏view视图(id){  this.执行vscode指令(`workbench.view.extension.${id}`) }  // package.json 里定义的 view id 



    //-------终端相关
    用vscode终端执行(指令文本,工作路径, 传入终端名){
        let 终端名 = 传入终端名 || path.basename(工作路径)
        let 终端 = this.生成vscode终端界面(终端名, 工作路径)  
        终端.sendText( `${指令文本}\n` )     
    }
    用vscode终端执行后销毁( 指令文本, 工作路径){
        this.用vscode终端执行(`${指令文本}\n; sleep 2; exit` ,工作路径 , "临时终端" )
    }
    生成vscode终端界面(界面名称, 工作路径 , 欢迎信息){                                   //isTransient true  vs重启后不再打开旧终端窗口
        let 终端数组 = vscode.window.terminals
        let 查找终端数组 = 终端数组.filter(终端 => 终端.name === 界面名称)
        let 终端 = 查找终端数组?.length !==0 ? 查找终端数组[0] : vscode.window.createTerminal({ name:界面名称, cwd: 工作路径,  message:欢迎信息  ,isTransient:true}) 
        终端.show()
        this.执行vscode指令("workbench.action.terminal.focus", 终端)
        return 终端
    }
    vscode终端激活事件(){
        vscode.window.onDidChangeActiveTerminal((终端)=>{ //参数是当前激活的终端
             
        })
    }
    获取vscode终端数组(){  return vscode.window.terminals }


    //-------文件操作相关
    保存配置JSON到电脑(配置对象){ this.文件写JSON文件( 配置对象.配置文件路径, 配置对象)}

    //-------常用网页接口
    读网页html_转换路径(网页面板, html绝对路径){   
        const 目录路径 = path.dirname(html绝对路径);
        let 页面 = fs.readFileSync(html绝对路径, 'utf-8');  //读取文件  ---- vscode不支持直接加载本地资源
        //会自动将HTML文件中link、href、script、img的资源相对路径全部替换成正确的vscode-resource:绝对路径
        let html文本 = 页面.replace(/( {
                let Uri路径 = vscode.Uri.file(path.join(目录路径, 第二个正则括号里匹配的内容))
                return  第一个正则括号里匹配的内容 + 网页面板.webview.asWebviewUri(Uri路径) + '"'
            });
        return html文本
    }
    创建网页面板(标题){                       //每个网页需要一个面板
        let 网页面板 = vscode.window.createWebviewPanel(
            'test',                     // viewType
            标题,                               // 视图标题
            vscode.ViewColumn.One,             // 显示在编辑器的哪个部位
            {
                enableScripts: true,           // 启用JS,默认禁用
                retainContextWhenHidden: true, // webview被隐藏时保持状态,避免被重置   影响性能
            },
            {   // 限制只能访问这个目录 [] 空表示限制访问
                localResourceRoots: [ vscode.Uri.file(this.插件路径) ]
            })
        return 网页面板
    }
    用vscode显示网页(相对路径, 标题){
        let 网页面板 = this.创建网页面板(标题)
        网页面板.webview.html = this.读网页html_转换路径(网页面板,相对路径)   // 显示网页
        return 网页面板
    }
    async 用vscode侧边栏显示网页(预设id, html绝对路径  ,消息处理函数 ){   
        return new Promise((成功后回调,失败后回调)=>{
            vscode.window.registerWebviewViewProvider( 预设id, 
                {                                                   
                    resolveWebviewView: (网页面板)=>{                                       
                             网页面板.webview.options={ 
                                 enableScripts: true,
                                 enableForms: true,
                                 localResourceRoots: [ vscode.Uri.file(this.插件路径 )]
                             };
                             网页面板.webview.html = this.读网页html_转换路径(网页面板, html绝对路径)    // fs.readFileSync(网页路径, 'utf-8')                 // vue 单文件网页     
                             网页面板.webview.onDidReceiveMessage( 消息处理函数 )                       //注册网页面板消息事件
                             成功后回调(网页面板)
                         }
                },
                {  webviewOptions:{ retainContextWhenHidden:true }  }                                 //保持内容,切换后不重启
            )
        })
    }

    处理收到的网页信令(网页面板, 处理函数){ // 网页面板接收消息    
        网页面板.webview.onDidReceiveMessage( 消息=>{ 处理函数(消息) }, undefined, this.context.subscriptions);
    }

  
    //-------下面备用
    // vscode.DocumentSemanticTokensProvider 实现可编程的语义分析   「Sematic Tokens Provider」 是 vscode 内置的一种对象协议,它需要自行扫描代码文件内容,然后以整数数组形式返回语义 token 序列,告诉 vscode 在文件的哪一行、那一列、多长的区间内是一个什么类型的 token。
    // 告诉 vscode 在文件的哪一行、那一列、多长的区间内是一个什么类型的 token(比如变量)。 
    注册编辑器_选择文本事件(){  //选中 移动关闭都会触发
        vscode.window.onDidChangeTextEditorSelection()
    }
    注册编辑器_切换编辑器事件(){
        vscode.window.onDidChangeActiveTextEditor()
    }
    注册编辑器_列变化事件(){
        vscode.window.onDidChangeTextEditorViewColumn()
    }
    注册编辑器_打开文档事件(){
        vscode.window.onDidOpenTextDocument()
    }
    注册编辑器_关闭文档事件(){
        vscode.window.onDidCloseTextDocument()
    }
    注册编辑器_文档可视变化事件(){
        vscode.window.onDidChangeTextEditorVisibleRanges()
    }
    
    注册编辑器_文本变化事件(){  //每次输入都会触发
        vscode.workspace.onDidChangeTextDocument( (变化事件)=>{
            
        })
    }

    数组里是否有子集(数组, 子集元素){  
        if(数组.includes(子集元素)) return true
        else return false
    }
    字符串是否有子集(字符串, 子集字符串){ // 有问题 ---> 字符里有正则符号会出错
        //  includes  是测试数组
        if( 字符串.search(子集字符串) === 0) return true
        else  return false
    }
    创建文件监视器(){
        vscode.workspace.createFileSystemWatcher()
    }
    获取vscode所有内部指令(){                
        vscode.commands.getCommands().then(allCommands => { // 获取所有命令
          
        });
    }
    重启所有的webview页面(){ this.执行vscode指令("workbench.action.webview.reloadWebviewAction") }
    
    创建问题诊断集合( 名称 ){ return vscode.languages.createDiagnosticCollection(名称);  } //创建问题诊断集合
    添加问题诊断( 问题诊断集合 , 编辑器, 起始位置, 结束位置 ){
        问题诊断集合.set(编辑器.document.uri, [{     //vscode内部代码诊断
            message: '异常中文标点',
            range: new vscode.Range(起始位置, 结束位置),
            severity: vscode.DiagnosticSeverity.Warning    
       } ])  
    }
    获取当前编辑器(){  return vscode.window.activeTextEditor }
    内容坐标( 编辑器, 位置 ){  return 编辑器.document.positionAt(位置)}
    对内容装饰(编辑器, CSS样式 , 起始位置, 结束位置){   //对页面代码进行外观上的装饰
        编辑器.setDecorations( vscode.window.createTextEditorDecorationType({   CSS样式 })   //某段范围添加一些 CSS
        ,[{
            range: new vscode.Range(起始位置, 结束位置)
        }])
    }
    注册代码自动补全(补全条目, 悬浮菜单 ){
        this.context.subscriptions.push(
            vscode.languages.registerCompletionItemProvider()
        )
    }
}

 

你可能感兴趣的:(vscode,ide,编辑器)