diff --git a/package.json b/package.json index 17f0f0f614a68dfb5b7c6c9ef7638ab611a549df..bb517084977e996c69436692defdc3fc39c77026 100755 --- a/package.json +++ b/package.json @@ -33,10 +33,15 @@ "微软双拼", "自然码双拼", "紫光双拼", - "拼音加加双拼" + "拼音加加双拼", + "自定义" ], "enumDescriptions": [] }, + "ChineseInputAssistant.CustomDictionaryPath": { + "type": "string", + "description": "自定义的字典路径" + }, "ChineseInputAssistant.InputMethod": { "type": "string", "description": "输入法设置", diff --git a/src/extension.ts b/src/extension.ts index ce7eeeda2dac236287f578a95eeaa71b105a9cb3..381f0cbc541fba62010a8f4f55c49fafaff78807 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,7 +4,7 @@ import { CompletionItem, Position, TextDocument } from 'vscode' import { 常用汉字 } from './data/常用汉字' import { 获得当前输入字段, 获得文档补全项, 获得系统补全项 } from './lib/VSC扩展' import { 包含中文 } from './lib/字符串扩展' -import { 获得中文字符表示 } from './lib/获得中文表示' +import { 清空字典, 获得中文字符表示, 载入字典 } from './lib/获得中文表示' import { 获得配置 } from './lib/获得配置' import { 获得输入法补全项 } from './lib/输入法' @@ -19,11 +19,17 @@ async function 完成项提供者(document: TextDocument, position: Position) { var 补全项: CompletionItem[] = [] var 输入字段 = await 获得当前输入字段() - // 如果输入的是中文, 那么不需要构造翻译. - if (包含中文(输入字段)) { - return [] + if (用户配置.提示方式 === '自定义') { + await 载入字典(用户配置.自定义的字典路径); + } else { + 清空字典(); } + // 如果输入的是中文, 那么不需要构造翻译. + // if (包含中文(输入字段)) { + // return [] + // } + // 获得系统补全项 if (用户配置.分析vsc提供的补全项 == 'yes') { var 补全项提供器 = await 获得系统补全项(document.uri, position) @@ -56,17 +62,14 @@ async function 完成项提供者(document: TextDocument, position: Position) { // - 现在正在输入的字段不需要加入补全项. // - 无论这个函数是否返回结果,vsc总会检测和自动补全定义的片段(Snippet),所以这里把片段过滤掉. 补全项 = R.uniqWith((a, b) => a.label == b.label, 补全项) - .filter((a) => 包含中文(a.label.toString())) - .filter((a) => a.label != 输入字段) - .filter((a) => a.kind != vscode.CompletionItemKind.Snippet) - - // 设置补全项的实际补全内容 - 补全项 = 补全项.map((a) => R.set(R.lensProp('insertText'), a.label.toString(), a)) + .filter((a) => 包含中文(a.label.toString()) && a.label != 输入字段 && a.kind != vscode.CompletionItemKind.Snippet) // 设置补全项的 filterText - 补全项 = 补全项.map((a) => - R.set(R.lensProp('filterText'), `${获得中文字符表示(用户配置.提示方式, a.label.toString())}`, a), - ) + 补全项.forEach((a) => { + let spell = 获得中文字符表示(用户配置.提示方式, a.label.toString()).toString(); + a.filterText = a.label + spell; + a.insertText ??= a.label.toString() + }) return new vscode.CompletionList(补全项, true) } @@ -82,4 +85,4 @@ export function activate(context: vscode.ExtensionContext) { ) } -export function deactivate() {} +export function deactivate() { } diff --git "a/src/lib/\344\272\224\347\254\224.ts" "b/src/lib/\344\272\224\347\254\224.ts" index e818e08b0247f8b4619e6c6e593529e5f5d4a109..969ec42ba06d517e419861a0b57f07e94520be0a 100644 --- "a/src/lib/\344\272\224\347\254\224.ts" +++ "b/src/lib/\344\272\224\347\254\224.ts" @@ -1,3 +1,5 @@ +import { 首字母大写 } from "./字符串扩展" + const 码表 = require('wubi-code-data') function 五笔(文字: string, 提示方式: string) { @@ -31,13 +33,5 @@ function 五笔(文字: string, 提示方式: string) { } return 键码 } -function 首字母大写(拼音: string) { - if (拼音.length > 0) { - var first = 拼音.substr(0, 1).toUpperCase() - var spare = 拼音.substr(1, 拼音.length) - return first + spare - } else { - return 拼音 - } -} + export default 五笔 diff --git "a/src/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.ts" "b/src/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.ts" index 9a373978f160a69885b9da5fb59dccff7f81fe79..abdace5336999279700cfa543a691f3b452fec68 100644 --- "a/src/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.ts" +++ "b/src/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.ts" @@ -22,3 +22,13 @@ export function 拆分中英文部分(输入字段: string) { .join('') return { 非英文部分, 英文部分 } } + +export function 首字母大写(拼音: string): string { + if (拼音.length > 0) { + var first = 拼音[0].toUpperCase() + var spare = 拼音.substring(1, 拼音.length + 1) + return first + spare + } else { + return 拼音 + } +} diff --git "a/src/lib/\350\207\252\345\256\232\344\271\211.ts" "b/src/lib/\350\207\252\345\256\232\344\271\211.ts" new file mode 100644 index 0000000000000000000000000000000000000000..9b43bd592b39778c7bf6fe6385e968415b4f311f --- /dev/null +++ "b/src/lib/\350\207\252\345\256\232\344\271\211.ts" @@ -0,0 +1,11 @@ +import { 多重笛卡尔积 } from './数组扩展'; +import { 读取字典 } from './获得中文表示'; + +export function 自定义(文本: string): string[] { + let 拼写: string[][] = []; + for (let i = 0; i < 文本.length; i++) { + const element = 文本[i]; + 拼写.push(读取字典(element) ?? [element]); + } + return 多重笛卡尔积(拼写).map((a) => a.join('')); +} \ No newline at end of file diff --git "a/src/lib/\350\216\267\345\276\227\344\270\255\346\226\207\350\241\250\347\244\272.ts" "b/src/lib/\350\216\267\345\276\227\344\270\255\346\226\207\350\241\250\347\244\272.ts" index 68142f306eb5e720815ecff28e24ce38a27e09c8..1fb7f9246db3a81e927a5443fd06d7d3a8220821 100644 --- "a/src/lib/\350\216\267\345\276\227\344\270\255\346\226\207\350\241\250\347\244\272.ts" +++ "b/src/lib/\350\216\267\345\276\227\344\270\255\346\226\207\350\241\250\347\244\272.ts" @@ -3,15 +3,67 @@ import 五笔 from './五笔' import { 多重笛卡尔积 } from './数组扩展' import { 转换为大写 } from './字符串扩展' import 拼音A from './拼音' +import { 自定义 } from './自定义' +import * as fs from 'fs/promises'; +import { 首字母大写 } from './字符串扩展'; -export function 获得中文字符表示(表示方法: string, 文本: string) { - if (表示方法.indexOf('五笔') != -1) { - return [五笔(文本, 表示方法)] +let 缓存 = new Map(); +let 上次使用的表示方式 = '全拼'; +var 当前字典路径: string | undefined = undefined; +let 字典: Map = new Map(); + +/** + * 字典格式:汉字\t拼写\n,允许同一个汉字有多种拼写方式 + * @param 字典路径 + * @returns + */ +export async function 载入字典(字典路径: string): Promise { + if (当前字典路径 === 字典路径) return; + 当前字典路径 = 字典路径; + 字典.clear(); + 缓存.clear(); + + let tsv = await fs.readFile(当前字典路径, 'utf-8'); + tsv.split('\n').forEach((v, _, __) => { + if (v.length < 3 || !v.includes('\t')) return; + let [i, k, ...___] = v.split('\t'); + let j = 首字母大写(k); + if (字典.has(i)) { + 字典.get(i)!.push(j); + } else { + 字典.set(i, [j]); + } + }); +} + +export function 清空字典() { + if (当前字典路径 === undefined) return; + 当前字典路径 = undefined; + 字典.clear(); +} + +export function 读取字典(字: string) { + return 字典.get(字); +} + +export function 获得中文字符表示(表示方法: string, 文本: string): string[] { + if (上次使用的表示方式 !== 表示方法) { + 缓存.clear(); + 上次使用的表示方式 = 表示方法; + } + if (缓存.has(文本)) return 缓存.get(文本)!; + + let 拼写: string[]; + if (表示方法 === '自定义') { 拼写 = 自定义(文本); } + else if (表示方法.indexOf('五笔') != -1) { + 拼写 = [五笔(文本, 表示方法)] } else { var 结果 = 拼音(文本, { heteronym: true, style: 拼音.STYLE_NORMAL }) 结果 = 结果.map((a) => a.map((a) => 转换为大写(a[0]) + a.substring(1))) var 转换后结果 = 多重笛卡尔积(结果).map((a) => a.join('')) if (表示方法 != '全拼') 转换后结果 = 转换后结果.map((a) => 拼音A.双拼转换(a, 表示方法)) - return 转换后结果 + 拼写 = 转换后结果 } + 缓存.set(文本, 拼写); + return 拼写; } diff --git "a/src/lib/\350\216\267\345\276\227\351\205\215\347\275\256.ts" "b/src/lib/\350\216\267\345\276\227\351\205\215\347\275\256.ts" index cf53ab5436f42c2d838fa5a1df507568ecad553c..86775fbc00f06a5c393e388be176e02be090dc03 100644 --- "a/src/lib/\350\216\267\345\276\227\351\205\215\347\275\256.ts" +++ "b/src/lib/\350\216\267\345\276\227\351\205\215\347\275\256.ts" @@ -20,7 +20,8 @@ class 配置 { | '微软双拼' | '自然码双拼' | '紫光双拼' - | '拼音加加双拼' { + | '拼音加加双拼' + | '自定义' { return vscode.workspace.getConfiguration('中文代码快速补全').get('提示方式') as any } public get 分析vsc提供的补全项(): 'yes' | 'no' { @@ -32,6 +33,12 @@ class 配置 { public get 代理地址(): string { return vscode.workspace.getConfiguration('ChineseInputAssistant').get('proxy') as any } + + public get 自定义的字典路径(): string { + let v = vscode.workspace.getConfiguration('ChineseInputAssistant').get('CustomDictionaryPath') + if (v === undefined) return '' + else return v + } } export function 获得配置() { diff --git a/src/test/index.test.ts b/src/test/index.test.ts index 595fe6f3417dd4fbdd7ab5486b11ac2c9805b7bd..a46feb7c7d9c32927911241b75f948480b64e2bc 100644 --- a/src/test/index.test.ts +++ b/src/test/index.test.ts @@ -1,6 +1,6 @@ import 'mocha' import { 包含中文, 标识符模式 } from '../lib/字符串扩展' -import { 获得中文字符表示 } from '../lib/获得中文表示' +import { 获得中文字符表示, 载入字典 } from '../lib/获得中文表示' function 断言相等(a: any, b: any) { if (JSON.stringify(a) == JSON.stringify(b)) return @@ -10,6 +10,14 @@ function 断言相等(a: any, b: any) { it('获得中文字符表示', async function () { 断言相等(获得中文字符表示('全拼', '右折叠'), ['YouZheDie', 'YouSheDie']) }) + + +it('自定义字典', async function () { + await 载入字典('./src/test/testDict.tsv'); + 断言相等(获得中文字符表示('自定义', '啊'), ['A']) + 断言相等(获得中文字符表示('自定义', '啊陂'), ['APo', 'APi', 'ABei']) +}) + it('包含中文', async function () { 断言相等(包含中文('好'), true) 断言相等(包含中文('n好o'), true) diff --git a/src/test/testDict.tsv b/src/test/testDict.tsv new file mode 100644 index 0000000000000000000000000000000000000000..b8aa93e7dd432c19cbacdb5818e7285019078891 --- /dev/null +++ b/src/test/testDict.tsv @@ -0,0 +1,9 @@ +啊 a +陂 po +陂 pi +陂 bei +悖 bei +钡 bei +标 biao +表 biao +蛂 bie \ No newline at end of file