欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > VScode 插件开发 国际化帮助工具

VScode 插件开发 国际化帮助工具

2025/6/15 12:24:45 来源:https://blog.csdn.net/qq_40881695/article/details/145336850  浏览:    关键词:VScode 插件开发 国际化帮助工具

一、功能实现

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');
const fs = require('fs');
const path = require('path')const axios = require('axios');
const crypto = require('crypto');
const YOUDAO_API_URL = 'https://openapi.youdao.com/api';
const targetLanguage = 'zh'; // 目标语言,例如中文// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed/*** @param {vscode.ExtensionContext} context*/
function activate(context) {// Use the console to output diagnostic information (console.log) and errors (console.error)// This line of code will only be executed once when your extension is activated// console.log('Congratulations, your extension "gn-i18n-helper" is now active!');// The command has been defined in the package.json file// Now provide the implementation of the command with  registerCommand// The commandId parameter must match the command field in package.jsonconst disposable = vscode.commands.registerCommand('extension.getSelectedText',  // 这个名称必须与package.json中的命令名称一致async () => {const editor = vscode.window.activeTextEditor;if (editor) {// 选中的文本const selection = editor.selection;const selectedText = editor.document.getText(selection);// 获取当前工作区的文件夹const workspaceFolders = vscode.workspace.workspaceFolders;// 获取文件内容const filePath1 = path.join(workspaceFolders[0].uri.fsPath, 'LANGUAGEI18n/LANGUAGEI18nCommon.md');const filePath2 = path.join(workspaceFolders[0].uri.fsPath, 'LANGUAGEI18n/LANGUAGEI18nFrontend.md');const filePath3 = path.join(workspaceFolders[0].uri.fsPath, 'LANGUAGEI18n/LANGUAGEI18nPage.md');const filePath4 = path.join(workspaceFolders[0].uri.fsPath, 'LANGUAGEI18n/LANGUAGEI18nGeneral.md');const fileContent1 = fs.readFileSync(filePath1, 'utf8');const fileContent2 = fs.readFileSync(filePath2, 'utf8');const fileContent3 = fs.readFileSync(filePath3, 'utf8');const fileContent4 = fs.readFileSync(filePath4, 'utf8');let fileContent = fileContent1 + fileContent2 + fileContent3 + fileContent4;if (editor.document.languageId === 'vue') {const document = editor.document;const position = editor.selection.active; // 获取光标位置const lineText = document.lineAt(position.line).text; // 获取当前行文本const currentFileContent = document.getText(); // 获取文件内容// 默认 template,防止出现多个 template 标签// 使用正则表达式匹配 <javaScript> 和 </javaScript> 之间的内容let section = 'template';const javaScriptRegex = /<script>([\s\S]*?)<\/script>/i;const javaScriptMatch = currentFileContent.match(javaScriptRegex);if (javaScriptMatch && javaScriptMatch[1]) {const matchContent = javaScriptMatch[1].trim(); // 提取内容并去除多余空格if(matchContent.includes(lineText)){section = 'javaScript';}}// 处理选中的内容,截取需要搜索的文字let searchText = '';if(selectedText.includes('=')){searchText = selectedText.split('=')[1].replace(/"/g, "").trim();}else{searchText = selectedText;}const searchResult = fileContent.search(new RegExp(searchText, 'g'));let isMatch = false;if (searchResult !== -1) {// 截取文件内容 - 提高搜索效率// let copyFileContent = fileContent.slice(searchResult - 1000, searchResult + 1000);const lines = fileContent.split('\n'); // 按行分割文本const regex = /(\w+)\("([^"]+)", "([^"]+)", "([^"]+)",/;for (const line of lines) {const match = line.match(regex);if (match) {const docKey = match[2];const docValue = match[3];const docText = match[4].replace(/"/g, "");let newText = '';if(section == 'template'){if(selectedText.includes('=')){// placeholder="验证码" -> :placeholder="$t('common.verifyCode')"const prop = selectedText.split('=')[0];newText = `:${prop}="$t('${docKey}.${docValue}')"`}else{// 验证码 -> {{$t('common.username')}}newText = `{{$t('${docKey}.${docValue}')}}`}}else if(section == 'javaScript'){// "验证码" -> this.$t('common.username')newText = `this.$t('${docKey}.${docValue}')`}if(docText == searchText){isMatch = true;if (docKey && docValue) {vscode.window.showInformationMessage(editor.selection, newText);if(section == 'template'){editor.edit(editBuilder => {editBuilder.replace(editor.selection, newText);});}else if(section == 'javaScript'){const start = selection.start;const end = selection.end;// 获取当前选中内容的前后字符位置const newStart = new vscode.Position(start.line, Math.max(start.character - 1, 0));const newEnd = new vscode.Position(end.line, Math.min(end.character + 1, document.lineAt(end.line).text.length));// 设置新的选择区域editor.selection = new vscode.Selection(newStart, newEnd);editor.edit(editBuilder => {editBuilder.replace(editor.selection, newText); // 替换选中的内容});}break; // 找到后退出循环}}}}// 如果没有找到精准匹配的内容if(!isMatch){addWordToFile(searchText, filePath4);// vscode.window.showInformationMessage(`未找到匹配内容:${searchText}`);}} else {addWordToFile(searchText, filePath4);}}} else {vscode.window.showInformationMessage('No active editor found.');}},);context.subscriptions.push(disposable);
}// 添加词条到文件
async function addWordToFile(searchText, filePath4) {const translatedText = await translateText(searchText, targetLanguage);const simplifyText = simplify(translatedText);const camelCaseText = toCamelCase(simplifyText);// 向文件中添加翻译后的文本const generationFilePath = filePath4;const generationFileContent = fs.readFileSync(generationFilePath, 'utf8');// GENERAL_UPDATELOG("general", "updateLog", "更新日志", "updateLog", "更新日志"),const insertText = `GENERAL_${camelCaseText.toUpperCase()}("general", "${camelCaseText}", "${searchText}", "${simplifyText}", "${searchText}"),`;const newGenerationFileContent = generationFileContent + '\n' + insertText;fs.writeFileSync(generationFilePath, newGenerationFileContent);
}async function translateText(text, targetLanguage) {const appKey = ''; // 替换为您的 App Keyconst appSecret = ''; // 替换为您的 App Secretconst salt = Date.now();const curtime = Math.floor(Date.now() / 1000);const sign = crypto.createHash('sha256').update(appKey + truncate(text) + salt + curtime + appSecret).digest('hex');const response = await axios.get(YOUDAO_API_URL, {params: {q: text,from: 'zh-CHS',to: targetLanguage,appKey: appKey,salt: salt,sign: sign,signType: "v3",curtime: curtime,},});return response.data.translation[0];
}function truncate(text) {return text.length > 200 ? text.slice(0, 200) : text;
}function toCamelCase(str) {// 将 - 替换为 " "str = str.replace(/-/g, " ");return str.split(/\s+/) // 按空格分割.map((word, index) => {if (index === 0) {return word.toLowerCase(); // 第一个单词小写}return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); // 其他单词首字母大写}).join('');
}function simplify(text) {// 示例: 删除多余空格和停用词const stopWords = ['the', 'is', 'in', 'at', 'and', 'of', 'to', 'a', 'that', 'it', 'on', 'for'];const words = text.split(' ').filter(word => !stopWords.includes(word.toLowerCase()));return words.join(' ').trim(); // 返回精简后的文本
}// This method is called when your extension is deactivated
function deactivate() {vscode.window.showInformationMessage(`Congratulations, your extension "gn-i18n-helper" is now active!`);
}module.exports = {activate,deactivate
}

二、快捷键定义

{"name": "gn-i18n-helper","displayName": "gn-i18n-helper","description": "A VS Code extension to help with i18n.","publisher": "guniao","version": "2.0.2","icon": "resources/i18n.png","engines": {"vscode": "^1.96.0"},"categories": ["Other"],"activationEvents": [],"main": "./extension.js","contributes": {"commands": [{"command": "extension.getSelectedText","title": "Get Selected Text"}],"keybindings": [{"command": "extension.getSelectedText","key": "alt+r","when": "editorTextFocus"}]},"scripts": {"lint": "eslint .","pretest": "npm run lint","test": "vscode-test"},"devDependencies": {"@types/mocha": "^10.0.10","@types/node": "20.x","@types/vscode": "^1.96.0","@vscode/test-cli": "^0.0.10","@vscode/test-electron": "^2.4.1","eslint": "^9.16.0"},"dependencies": {"axios": "^1.7.9"}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词