This commit is contained in:
pqcqaq 2024-11-01 13:41:19 +08:00
commit 6c2b304501
2 changed files with 120 additions and 41 deletions

View File

@ -1,4 +1,8 @@
import { getAvailableKeys } from './../utils/locales';
import {
addKeyToLocale,
addLocaleToData,
getAvailableKeys,
} from './../utils/locales';
import { join } from 'path';
import {
getCachedLocaleItemByKey,
@ -41,9 +45,9 @@ class LocaleDocumentLinkProvider implements vscode.DocumentLinkProvider {
if (isKeyExist(key)) {
const localePath = getCachedLocaleItemByKey(key);
if (localePath && localePath.path) {
const startPos = document.positionAt(match.index);
const startPos = document.positionAt(match.index + 2);
const endPos = document.positionAt(
match.index + match[0].length
match.index + match[0].length - 1
);
const range = new vscode.Range(startPos, endPos);
@ -56,7 +60,9 @@ class LocaleDocumentLinkProvider implements vscode.DocumentLinkProvider {
range,
vscode.Uri.file(filePath)
);
documentLink.tooltip = '点击跳转到定义';
documentLink.tooltip = localePath.desc
? `CN: ${localePath.desc}`
: `[未找到中文] 跳转到定义`;
documentLinks.push(documentLink);
}
}
@ -175,8 +181,11 @@ async function validateDocument(document: vscode.TextDocument) {
}
if (!isKeyExist(key)) {
const startPos = document.positionAt(match.index);
const endPos = document.positionAt(match.index + match[0].length);
// range需要排除掉t(的部分和最后的 ) 部分
const startPos = document.positionAt(match.index + 2);
const endPos = document.positionAt(
match.index + match[0].length - 1
);
const range = new vscode.Range(startPos, endPos);
const diagnostic = new vscode.Diagnostic(
range,
@ -227,6 +236,17 @@ const addLocaleActionProvider = vscode.languages.registerCodeActionsProvider(
const addLocaleCommand = vscode.commands.registerCommand(
'oak-i18n.addLocaleDefinition',
(document: vscode.TextDocument, range: vscode.Range, key: string) => {
// 先判断key是不是命名空间的形式或者entity的形式
if (key.includes(':')) {
console.log('命名空间形式的key需要找到对应的文件');
const { path, error } = addKeyToLocale(key, '');
if (error) {
vscode.window.showErrorMessage(error);
return;
}
vscode.window.showTextDocument(vscode.Uri.file(path!));
return;
}
// 得到文档的位置
const filePath = document.uri.fsPath;
// 得到 locale 文件的路径
@ -264,37 +284,6 @@ const addLocaleCommand = vscode.commands.registerCommand(
}
);
const addLocaleToData = (
localeData: any,
key: string,
value: string = ''
): void => {
const keys = key.split('.');
let current = localeData;
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
if (i === keys.length - 1) {
// 最后一个键,直接赋值
current[k] = value;
} else {
// 不是最后一个键,检查下一级
if (!(k in current)) {
// 如果键不存在,创建一个新的对象
current[k] = {};
} else if (typeof current[k] !== 'object') {
// 如果存在但不是对象,抛出错误
throw new Error(
`Cannot add key "${key}". "${k}" is not an object.`
);
}
// 移动到下一级
current = current[k];
}
}
};
export function activateOakLocale(context: vscode.ExtensionContext) {
const enabledI18n = vscode.workspace
.getConfiguration('oak-assistant')

View File

@ -139,7 +139,7 @@ export const findValueByKey = (
* @param key key
* @returns string
*/
export const getLocaleItem = (key: string): LocaleItem | undefined => {
const getLocaleItem = (key: string): LocaleItem | undefined => {
// 如果是namespace则为xxxx::开头
if (key.includes('::')) {
// 从cachedLocaleItems中找到对应的值
@ -186,8 +186,10 @@ const getNamespacedLocaleItems = (
label: key,
value: key,
desc:
findValueByKey(locales.namespaced[namespaceName], key) ||
'',
findValueByKey(
locales.namespaced[namespaceName],
key.split('::')[1]
) || '',
path: join(pathConfig.localesHome, namespaceName),
};
}),
@ -211,7 +213,11 @@ const getEntityLocaleItems = (
return {
label: key,
value: key,
desc: findValueByKey(locales.entities[name], key) || '',
desc:
findValueByKey(
locales.entities[name],
key.split(':')[1]
) || '',
path: getEntityLocalePath(key.split(':')[0]),
};
}
@ -352,6 +358,90 @@ export const getCachedLocaleItemByKey = (
return getLocaleItem(key);
};
export const addLocaleToData = (
localeData: any,
key: string,
value: string = ''
): void => {
const keys = key.split('.');
let current = localeData;
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
if (i === keys.length - 1) {
// 最后一个键,直接赋值
current[k] = value;
} else {
// 不是最后一个键,检查下一级
if (!(k in current)) {
// 如果键不存在,创建一个新的对象
current[k] = {};
} else if (typeof current[k] !== 'object') {
// 如果存在但不是对象,抛出错误
throw new Error(
`Cannot add key "${key}". "${k}" is not an object.`
);
}
// 移动到下一级
current = current[k];
}
}
};
export const addKeyToLocale = (
keyPath: string,
value: string
): {
path?: string;
error?: string;
} => {
// 如果是namespace则为xxxx::开头
if (keyPath.includes('::')) {
const [namespace, key] = keyPath.split('::');
const path = join(pathConfig.localesHome, namespace);
// 如果文件不存在则创建
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
// 判断是否存在 zh_CN.json 文件,如果不存在则使用 zh-CN.json
let localeFilePath = join(path, 'zh-CN.json');
if (!fs.existsSync(localeFilePath)) {
localeFilePath = join(path, 'zh_CN.json');
if (!fs.existsSync(localeFilePath)) {
// 如果两个都不存在,创建一个新的 zh_CN.json 文件
fs.writeFileSync(localeFilePath, '{}');
}
}
// 尝试读取文件
let localeData = {};
try {
localeData = JSON.parse(fs.readFileSync(localeFilePath, 'utf-8'));
} catch (error) {
// 如果读取文件失败,直接返回
return {
error: '读取文件失败',
};
}
// 添加新的键值对
addLocaleToData(localeData, key, value);
// 写入文件
fs.writeFileSync(localeFilePath, JSON.stringify(localeData, null, 2));
// 更新缓存
locales.namespaced[namespace] = localeData;
return {
path: localeFilePath,
};
} else if (keyPath.includes(':')) {
return {
error: '暂不支持entity的locales编辑',
};
}
return {
error: '这个函数只用于处理namespace的locales',
};
};
subscribeEntity('#all', (name) => {
setEntityLocales(name);
});