1. 程式人生 > >VsCode插件開發之插件初步通信

VsCode插件開發之插件初步通信

shee gin register end bootstrap 下載源碼 link spa 默認

參考了Egret Wing,想像Egret Wing那樣在上方titlebar最右邊上面增加一個menu(這個menu相對於一個按鈕,當點擊這個按鈕時會出現一個window彈框,這個window彈框裏就包含相關的表單信息以供登錄或者註冊使用。我是以這個作為參考模板的。但是目前進展並不是很順。於是我通過插件的方式暫時性解決了這個問題。但是覺得還不是想要的那樣。

Egret Wing是這樣的,如圖所示:

技術分享圖片

不得不承認一點Egret Wing改造的挺不錯的,不愧是對VsCode進行魔改。

今天先說一下通過插件通信。

我主要參考的是一個叫小茗同學的插件開發,並改造其插件來達到我的目的。

這個小茗同學我覺得他寫的插件開發,我覺得不是特別詳細全面,當然,參考意義還是有的。

他的插件開發目錄如下:

技術分享圖片

他的插件github地址為:https://github.com/sxei/vscode-plugin-demo.git

他的插件可以在VsCode插件擴展中搜到(搜到後安裝,然後直接在下載成功的插件的基礎上改造),例如:

技術分享圖片

那麽說說我是如何改造它的呢?

我主要改造它這麽幾個地方?

一個是圖標,另外一個修改它的html界面(主要是修改custom-welcome.html),同時我要和還改了package.json文件。

插件開發可以用TypeScript,也可以用JavaScript。

如果是用TypeScript的話,通常擴展腳本文件是extension.ts形式存在,如果是JavaScript,則是以extension.js的形式存在。

在此我想強調的是改他人插件或者自己編寫插件,以ts為例,主要把握也就兩個文件,一個是extension.ts,另一個就是package.json。

如何從0開發以插件的相關視頻,感興趣的可以看看,感覺還是有一定的啟發的:https://v.qq.com/x/page/k08220bdz3s.htmlb

我改造後的插件代碼,放在我的個人github上,大家可以將其下載下來放入,如下兩個文件中(任意一個都行):

技術分享圖片

註意:

.vscode文件夾:官方插件下載好默認放入的目錄。

.vscode-oss-dev:下載源碼,自己編譯,下載插件放置的目錄。

自己編譯的不知道由於什麽原因不能直接聯網通信搜索一些應用市場下載的插件。

通常情況下(以.vscode-oss-dev為例),git clone下來我的插件地址,然後將其移植到這個目錄就能看到對應的效果,效果圖如下:

技術分享圖片

我的VsCode插件地址為:https://github.com/youcong1996/study_simple_demo/tree/vscode-plugin-communication

將其克隆下來放入.vscode或者.vscode-oss-dev中的extensions目錄下即可起作用。

另外有一點要強調的是,如果是vscode非自己編譯的,需要重啟一下vscode,如果是自己編譯的話,監聽需要暫時中斷重新輸入(yarn watch)。

接下來說說我修改的三個地方。

1.修改package.json(包含圖標一起說了及其點擊登錄的同時展示對應的左側欄sidebar)

{
    "name": "vscode-plugin-demo",
    "displayName": "vscode-plugin-demo",
    "description": "VSCode插件demo",
    "keywords": [
        "vscode",
        "plugin",
        "demo"
    ],
    "version": "1.0.3",
    "publisher": "sxei",
    "engines": {
        "vscode": "^1.27.0"
    },
    "categories": [
        "Other"
    ],
    "icon": "images/icon.png",
    "activationEvents": [
        "*"
    ],
    "main": "./src/extension",
    "contributes": {
        "configuration": {
            "type": "object",
            "title": "Code插件demo",
            "properties": {
                "vscodePluginDemo.yourName": {
                    "type": "string",
                    "default": "guest",
                    "description": "你的名字"
                },
                "vscodePluginDemo.showTip": {
                    "type": "boolean",
                    "default": true,
                    "description": "啟動時顯示自定義歡迎頁"
                }
            }
        },
        "commands": [
            {
                "command": "extension.sayHello",
                "title": "Hello,小茗同學"
            },
            {
                "command": "extension.demo.getCurrentFilePath",
                "title": "獲取當前文件(夾)路徑"
            },
            {
                "command": "extension.demo.testMenuShow",
                "title": "這個菜單僅在JS文件中出現",
                "icon": {
                    "light": "./images/tool-light.svg",
                    "dark": "./images/tool-light.svg"
                }
            },
            {
                "command": "extension.demo.openWebview",
                "title": "打開WebView"
            },
            {
                "command": "extension.demo.showWelcome",
                "title": "顯示自定義歡迎頁"
            }
        ],
        "keybindings": [
            {
                "command": "extension.sayHello",
                "key": "ctrl+f10",
                "mac": "cmd+f10",
                "when": "editorTextFocus"
            },
            {
                "command": "extension.demo.openWebview",
                "key": "ctrl+f9",
                "mac": "cmd+f9",
                "when": "editorTextFocus"
            }
        ],
        "menus": {
            "editor/context": [
                {
                    "when": "editorFocus",
                    "command": "extension.sayHello",
                    "group": "navigation@6"
                },
                {
                    "when": "editorFocus",
                    "command": "extension.demo.getCurrentFilePath",
                    "group": "navigation@5"
                },
                {
                    "when": "editorFocus && resourceLangId == javascript",
                    "command": "extension.demo.testMenuShow",
                    "group": "z_commands"
                },
                {
                    "command": "extension.demo.openWebview",
                    "group": "navigation"
                }
            ],
            "editor/title": [
                {
                    "when": "editorFocus && resourceLangId == javascript",
                    "command": "extension.demo.testMenuShow",
                    "group": "navigation"
                }
            ],
            "editor/title/context": [
                {
                    "when": "resourceLangId == javascript",
                    "command": "extension.demo.testMenuShow",
                    "group": "navigation"
                }
            ],
            "explorer/context": [
                {
                    "command": "extension.demo.getCurrentFilePath",
                    "group": "navigation"
                },
                {
                    "command": "extension.demo.openWebview",
                    "group": "navigation"
                }
            ]
        },
        "snippets": [
            {
                "language": "javascript",
                "path": "./snippets/javascript.json"
            },
            {
                "language": "html",
                "path": "./snippets/html.json"
            }
        ],
        "viewsContainers": {
            "activitybar": [
                {
                    "id": "beautifulGirl",
                    "title": "測試",
                    "icon": "images/beautifulGirl.svg"
                }
            ]
        },
        "views": {
            "beautifulGirl": [
                {
                    "id": "測試001",
                    "name": "test"
                },
                {
                    "id": "測試002",
                    "name": "test"
                },
                {
                    "id": "測試003",
                    "name": "test"
                }
            ]
        },
        "iconThemes": [
            {
                "id": "testIconTheme",
                "label": "測試圖標主題",
                "path": "./theme/icon-theme.json"
            }
        ]
    },
    "scripts": {
        "postinstall": "node ./node_modules/vscode/bin/install",
        "test": "node ./node_modules/vscode/bin/test"
    },
    "devDependencies": {
        "typescript": "^2.6.1",
        "vscode": "^1.1.6",
        "eslint": "^4.11.0",
        "@types/node": "^7.0.43",
        "@types/mocha": "^2.2.42"
    },
    "license": "SEE LICENSE IN LICENSE.txt",
    "bugs": {
        "url": "https://github.com/sxei/vscode-plugin-demo/issues"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/sxei/vscode-plugin-demo"
    },
    "homepage": "https://github.com/sxei/vscode-plugin-demo/blob/master/README.md",
    "__metadata": {
        "id": "ac2b7b16-d87f-4e51-87a8-37011e8aa713",
        "publisherId": "cdd0fc1d-3acf-4250-a09b-95545e29bdbc",
        "publisherDisplayName": "小茗同學"
    }
}

在package.json我也就修改了這麽幾個地方,一個是views(這個view通常主要用於展示左側的sidebar視圖),一個是viewsContainers(我主要修改beautifulGirl.svg)。

修改後的效果分別如下所示:

技術分享圖片

技術分享圖片

2.通信(修改custom-welcome.html)

通信我目前采用最原始的javascript的ajax請求,其實jQuery及其vue.js的異步通信也是可以的。

這個custom-welcome.html你可以理解成它就是一個webview。

custom-welcome.html文件內容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定義歡迎頁</title>
    <link rel="stylesheet" href="../../lib/bootstrap-3.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="../../lib/layui/css/layui.css">
    <style>
        html, body, #app {
            height: 100%;
        }
        ::-webkit-scrollbar {
            width: 10px;
            height: 10px
        }

        ::-webkit-scrollbar-track {
            border-radius: 10px;
            background-color: #d8dce5
        }

        ::-webkit-scrollbar-thumb {
            border-radius: 5px;
            background-color: #adadad
        }

        ::-webkit-scrollbar-thumb:hover {
            background-color: #929292
        }

        ::-webkit-scrollbar-thumb:active {
            background-color: #666363
        }

        ::-webkit-scrollbar-corner {
            background-color: #535353
        }

        ::-webkit-scrollbar-resizer {
            background-color: #ff6e00
        }
        .page-title {
            margin-bottom: 20px;
        }

        .control-label {
            font-weight: normal;
        }

        .btn-primary {
            background-color: #1890ff;
            border-color: #1890ff;
            outline: none;
        }

        .btn-primary:focus,
        .btn-primary:hover {
            background-color: #40a9ff;
            border-color: #40a9ff;
            outline: none;
        }

        .btn-primary.active,
        .btn-primary:active {
            background-color: #096dd9;
            border-color: #096dd9;
            color: #fff;
            outline: none;
        }
    </style>
</head>

<body>
    <div id="app" class="container-fluid">
        <h3 class="page-title">自定義歡迎頁</h3>
        <p class="alert alert-success" style="width: 300px;">{{userName}},{{time}}好!
        <span id="info"></span>
        </p>
        <form class="form-horizontal">
            <div class="form-group">
                <div class="col-sm-6">
                    <div id="form">
                        <form>
                            <p>用戶名:<input type="text" id="userName" style="color:black;"/></p>
                            <p>密&nbsp;&nbsp;碼&nbsp;&nbsp;:<input type="password" id="password" style="color:black;"/></p>
                            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="button" style="color:black;" value="提交" onclick="test()"/>
                        <input type="button" value="打開" onclick="openLogin()"/>
                         </form>
                    </div>
                    <div class="checkbox">
                        <label>
                            <input type="checkbox" v-model="show"> 啟動時顯示自定義歡迎頁
                            &nbsp;&nbsp;
                            <input type="button" onclick="register()" value="退出"/>
                        </label>
                    </div>
                </div>
            </div>
        </form>



    </div>
    <script src="../../lib/jquery/jquery.min.js"></script>
    <script src="../../lib/bootstrap-3.3.1/js/bootstrap.min.js"></script>
    <script src="../../lib/vue-2.5.17/vue.js"></script>
    <script src="../../src/view/custom-welcome.js"></script>
    <script src="../../lib/layui/layui.js"></script>
    <script src="../../lib/layer/layer-v3.1.1/layer/mobile/layer.js"></script>
    <script>
    function openLogin(){
        layui.use(‘layer‘, function(){
          var layer = layui.layer;
    
          layer.open({
                type: 2,
                title: ‘Login‘,
                fix: false,
                maxmin: true,
                shadeClose: true,
                shade: 0.8,
                area: [‘500px‘, ‘500px‘],
                content: ‘login.html‘,
                end: function () {
                   location.reload();
                }
            });
        });
    }

    function test(){
           var userName = document.getElementById("userName").value;

           if(userName != null && userName != undefined){
            var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                $("#info").html("登錄成功");
                $("#form").hide();
                
                console.log(‘test:‘+xhr.status);
                console.log(xhr.responseText);
                } else {
                console.log("請求成功:" + xhr.status);
                }
                }
                };
                xhr.open("POST", "http://www.test.com/test-web/sysUser/getUserCodeByInfo?userCode=2", true);
                xhr.send(null);
                
            }else{
                layui.use(‘layer‘, function(){
                
                var layer = layui.layer;
                
                layer.msg(‘userName為必填項‘);
                }); 
            }

           }
    function register(){
        $("#info").html("");
        $("#form").show();
    }
                
    </script>
</body>

</html>

這個html在瀏覽器上看到的效果如下所示:

技術分享圖片

目前這僅僅是一個很初級的(蹩腳通信),後續我將會繼續補充對VsCode的源碼解析及其插件開發相關的詳細說明,由於目前掌握的比較分散不夠系統,暫時延後講解。

VsCode插件開發之插件初步通信