31

Write a vscode plugin to help read the code of the i18n project

image.png

introduce

The author’s current project is for global users. The project inevitably needs to be internationalized. Even if it is just a simple ok button, the ok copy should be translated into languages of different countries for display, so we often can’t directly display the code in the code. The name is ok , but it may be named user_base_plan_edit_ok_button , and in order to distinguish i18n from other names, our team will use all capitals to be similar to USER_BASE_PLAN_EDIT_OK_BUTTON , and if there are more such codes, reading it will make eyes dry, similar The pseudo code in the figure below:

image.png

In order to solve the problem that not easy to read, my expected effect is that when the mouse is hovering over the target text, a pop-up box will appear, and this pop-up box must at least tell me the Chinese or English meaning of the word. The effect is as follows:

image.png

It can be seen that if this plug-in is done, it may not only be used for i18n but it can be used in many ways. For example, a certain code 103993283 specifically represents what the code means can be displayed as a plug-in.

One: Initialize the vscode project

Students who have never done the vscode plugin recommend to read the introductory tutorial I wrote first:

The plug-in I made this time is for my current project. I didn't have extensive application capabilities so I didn't publish it to the vscode official. After the development, it was packaged and sent to the company's intranet and group.

Create a project: The project name here is tentatively called i18n2c

   yo code

image.png

Two: Initialize the architecture

We clean up the extension.js

const vscode = require("vscode");

function activate(context) {
  vscode.window.showInformationMessage("i18n翻译插件加载完成");
}

module.exports = {
  activate,
};

Modify the package.json file: set to start loading our plug-in when the resource is loaded

{
// ...

  "activationEvents": [
    "onStartupFinished"
  ],

// ...
}

Click f5 turn on the debugging mode, and the following picture appears to prove that the plug-in can start normally:
image.png

Three: Initialize the hover file

We put the logic after hover

image.png

Simply modify extension.js and add the hover method:

const vscode = require("vscode");
const hover = require("./src/hover");

function activate(context) {
  vscode.window.showInformationMessage("i18n翻译插件加载完成");

  context.subscriptions.push(hover);
}

module.exports = {
  activate,
};

hover.js Export the processing method when hovering

const vscode = require("vscode");

module.exports = vscode.languages.registerHoverProvider("*", {
  provideHover(document, position) {
    return new vscode.Hover(`i18n插件前来助你渡劫`);
  },
});

When you hover in any position, the effect is as follows:

image.png

4: Identification of i18n target copy

The technical solutions of each team are different. Here I only design the solutions of our team, hoping to serve the purpose of attracting ideas:

Our team’s i18n copywriting is all uppercase, and underscores are used to link each other, but I found that there are no more than three underlines in the i18n copywriting, and underscores, and 1615d3b6de2ae0, I at least four i18ae0 underscores. It is to determine whether there are more than three '_' .

const vscode = require("vscode");

module.exports = vscode.languages.registerHoverProvider("*", {
  provideHover(document, position) {
    const word = document.getText(document.getWordRangeAtPosition(position));

    if (word.split("_").length > 3) {
      return new vscode.Hover(`i18n插件前来助你渡劫`);
    }

  },
});

The word above is the hovered text we

Five: How to translate into Chinese

Above we found the to be translated, here we are going to study how to translate this copy, generally there will be a dictionary package for i18n, our team is a json file, the difference is that each key is lowercase , The approximate look is as follows:

image.png

What I have to do is to read this file, and then convert the copy to be translated into lowercase, and then match it again and it will be ok.

const vscode = require("vscode");
const fs = require("fs");

module.exports = vscode.languages.registerHoverProvider("*", {
  provideHover(document, position) {
    const word = document.getText(document.getWordRangeAtPosition(position));

    let jsonCN = JSON.parse(
      fs.readFileSync("/xxxx/xxxxx/langs/zh-CN.json")
    );

    if (word.split("_").length > 3) {
      return new vscode.Hover(`i18n插件前来助你渡劫:
- 中文: ${jsonCN[word.toLocaleLowerCase()]}
      `);
    }

  },
});

image.png

Our i18n dictionaries are all placed in the same folder, so I only need to know this folder. By default, take out the Chinese and English copywriting in it, and modify it.

const vscode = require("vscode");
const fs = require("fs");

module.exports = vscode.languages.registerHoverProvider("*", {
  provideHover(document, position) {
    const word = document.getText(document.getWordRangeAtPosition(position));

    if (word.split("_").length > 3) {
      const i18nPath = "/xxxx/xxxxx/langs";
      const jsonUrlCN = i18nPath + "/zh-CN.json";
      const jsonUrlEN = i18nPath + "/en.json";
      let jsonCN = JSON.parse(fs.readFileSync(jsonUrlCN));
      let jsonEN = JSON.parse(fs.readFileSync(jsonUrlEN));
      return new vscode.Hover(`i18n插件前来助你渡劫:
- 中文: ${jsonCN[word.toLocaleLowerCase()]}
- 英文: ${jsonEN[word.toLocaleLowerCase()]}
      `);
    }
  },
});

image.png

The i18nPath here can of course be configured by the user, and then we will study it.

Six: setting configuration

The location where our translation dictionary file is located must not be written in the plug-in. In many cases, users need to set it by themselves. At this time, we need the concept of vscode setting, as shown in the following figure:

image.png

Step 1: Initialize configuration items

We come to the package.json file to add the setting configuration item:

{
  "contributes": {
    "configuration": {
      "type": "object",
      "title": "i18n翻译配置",
      "properties": {
        "vscodePluginI18n.i18nPath": {
          "type": "string",
          "default": "",
          "description": "翻译文件的位置"
        },
        "vscodePluginI18n.open": {
          "type": "boolean",
          "default": true,
          "description": "开启18n翻译"
        }
      }
    }
  },
}

type set to Boolean will automatically generate CheckBox quite convenient.

Step 2: Initial plug-in read configuration

extension.js file:

const vscode = require("vscode");

function activate(context) {
  const i18nPath = vscode.workspace
    .getConfiguration()
    .get("vscodePluginI18n.i18nPath");
  const open = vscode.workspace.getConfiguration().get("vscodePluginI18n.open");

  if (open && i18nPath) {
    vscode.window.showInformationMessage("i18n翻译插件已就位");
    const hover = require("./src/hover");
    context.subscriptions.push(hover);
  }
}

module.exports = {
  activate,
};

It should be noted here that if const hover = require("./src/hover"); written at the top, it may cause the hover translation effect to be unable to be turned off. There are pitfalls in this, we will talk about it in detail later.

Step 3: Read the path when hovering

hover.js file:

const vscode = require("vscode");
const fs = require("fs");

module.exports = vscode.languages.registerHoverProvider("*", {
  provideHover(document, position) {
    const i18nPath = vscode.workspace
      .getConfiguration()
      .get("vscodePluginI18n.i18nPath");
    const open = vscode.workspace
      .getConfiguration()
      .get("vscodePluginI18n.open");

    if (i18nPath && open) {
      const word = document.getText(document.getWordRangeAtPosition(position));

      if (word.split("_").length > 3) {
        const i18nPath = "/xxxxx/xxxx/langs";
        const jsonUrlCN = i18nPath + "/zh-CN.json";
        const jsonUrlEN = i18nPath + "/en.json";
        let jsonCN = JSON.parse(fs.readFileSync(jsonUrlCN));
        let jsonEN = JSON.parse(fs.readFileSync(jsonUrlEN));
        return new vscode.Hover(`i18n插件前来助你渡劫:
- 中文: ${jsonCN[word.toLocaleLowerCase()]}
- 英文: ${jsonEN[word.toLocaleLowerCase()]}
      `);
      }
    }
  },
});

Seven: When to judge whether to open the plug-in

hover module is introduced in the extension.js file, even if we judge that the user has not opened the i18n translation process, we will also go to the hover module, but if we judge whether the user has opened the i18n translation, then we will introduce the hover module. When the user changes the configuration, the translation cannot respond in a timely manner, and the user needs to restart it, so the specific design here needs to be determined by everyone.

Eight: prompt popup

If the user opens the i18n translation but does not configure the path, then we can actually display a pop-up box prompting the user whether to fill in the path of the translation dictionary, similar to the effect of the following figure:

image.png

extension.js file uses the showInformationMessage method, but two parameters need to be added:

const vscode = require("vscode");

function activate(context) {
  const i18nPath = vscode.workspace
    .getConfiguration()
    .get("vscodePluginI18n.i18nPath");
  const open = vscode.workspace.getConfiguration().get("vscodePluginI18n.open");

  if (open && i18nPath) {
    vscode.window.showInformationMessage("i18n翻译插件已就位");
    const hover = require("./src/hover");
    context.subscriptions.push(hover);
  } else if (open && !i18nPath) {
    vscode.window
      .showInformationMessage("是否设置翻译文件路径", "是", "否")
      .then((result) => {
           if (result === "是") {

           }
      });
  }
}

module.exports = {
  activate,
};

Nine: Select file

When the user clicks'Yes', we need to use the API provided by vscode to select the file, and get the return value of the file for active setting operations:

vscode.window.showOpenDialog method, it has four main parameters:

  1. canSelectFiles optional file
  2. canSelectFolders is the optional folder
  3. canSelectMany can multiple choices
  4. openLabel prompt copy
  5. The return value is an array, the path attribute of the first element is the global path of the file

image.png

Finally, use the update method to actively update the global configuration.

vscode.window
      .showInformationMessage("是否设置翻译文件路径", "是", "否")
      .then((result) => {
        if (result === "是") {
          vscode.window
            .showOpenDialog({
              canSelectFiles: false, // 是否可选文件
              canSelectFolders: true, // 是否可选文件夹
              canSelectMany: false, // 是否可以选择多个
              openLabel: "请选择翻译文件夹",
            })
            .then(function (res) {
              vscode.workspace
                .getConfiguration()
                .update("vscodePluginI18n.i18nPath", res[0].path, true);
            });
        }
      });
  }

end

This is the case this time, I hope to make progress with you.


lulu_up
5.7k 声望6.9k 粉丝

自信自律, 终身学习, 创业者