From bbe5ae5d5a97059a448f1a36cde37dfee9767f03 Mon Sep 17 00:00:00 2001 From: ijklam Date: Fri, 28 Oct 2022 20:57:19 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=85=81=E8=AE=B8=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=AD=97=E5=85=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 7 ++- src/extension.ts | 23 +++++----- "src/lib/\344\272\224\347\254\224.ts" | 12 ++--- ...46\344\270\262\346\211\251\345\261\225.ts" | 10 +++++ .../\350\207\252\345\256\232\344\271\211.ts" | 44 +++++++++++++++++++ ...55\346\226\207\350\241\250\347\244\272.ts" | 6 ++- ...67\345\276\227\351\205\215\347\275\256.ts" | 9 +++- 7 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 "src/lib/\350\207\252\345\256\232\344\271\211.ts" diff --git a/package.json b/package.json index 17f0f0f..bb51708 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 ce7eeed..6ebe730 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,6 +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,6 +20,12 @@ async function 完成项提供者(document: TextDocument, position: Position) { var 补全项: CompletionItem[] = [] var 输入字段 = await 获得当前输入字段() + if (用户配置.提示方式 === '自定义') { + await 读取字典(用户配置.自定义的字典路径); + } else { + 删除字典(); + } + // 如果输入的是中文, 那么不需要构造翻译. if (包含中文(输入字段)) { return [] @@ -56,17 +63,13 @@ 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 = spell; + }) 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 e818e08..969ec42 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 9a37397..abdace5 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 0000000..2ecf510 --- /dev/null +++ "b/src/lib/\350\207\252\345\256\232\344\271\211.ts" @@ -0,0 +1,44 @@ +import * as fs from 'fs/promises'; +import { 首字母大写 } from './字符串扩展'; +import { 多重笛卡尔积 } from './数组扩展'; + +var 当前字典路径: string | undefined = undefined; +let 字典: Map = new Map(); + +/** + * 字典格式:汉字\t拼写,允许同一个汉字有多种拼写方式 + * @param 字典路径 + * @returns + */ +export async function 读取字典(字典路径: string): Promise { + if (当前字典路径 === 字典路径) return; + 当前字典路径 = 字典路径; + 字典.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): string[] { + let 拼写: string[][] = []; + for (let i = 0; i < 文本.length; i++) { + const element = 文本[i]; + 拼写.push(字典.get(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 68142f3..82cb27f 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,9 +3,11 @@ import 五笔 from './五笔' import { 多重笛卡尔积 } from './数组扩展' import { 转换为大写 } from './字符串扩展' import 拼音A from './拼音' +import { 自定义 } from './自定义' -export function 获得中文字符表示(表示方法: string, 文本: string) { - if (表示方法.indexOf('五笔') != -1) { +export function 获得中文字符表示(表示方法: string, 文本: string): string[] { + if (表示方法 === '自定义') { return 自定义(文本); } + else if (表示方法.indexOf('五笔') != -1) { return [五笔(文本, 表示方法)] } else { var 结果 = 拼音(文本, { heteronym: true, style: 拼音.STYLE_NORMAL }) 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 cf53ab5..86775fb 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 获得配置() { -- Gitee From 3885b914591fc26441f1fcc6f31f9066962ad37b Mon Sep 17 00:00:00 2001 From: ijklam Date: Fri, 28 Oct 2022 21:13:55 +0800 Subject: [PATCH 2/4] add test --- "src/lib/\350\207\252\345\256\232\344\271\211.ts" | 2 +- src/test/index.test.ts | 9 +++++++++ src/test/testDict.tsv | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/test/testDict.tsv 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" index 2ecf510..ce10ae0 100644 --- "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" @@ -6,7 +6,7 @@ var 当前字典路径: string | undefined = undefined; let 字典: Map = new Map(); /** - * 字典格式:汉字\t拼写,允许同一个汉字有多种拼写方式 + * 字典格式:汉字\t拼写\n,允许同一个汉字有多种拼写方式 * @param 字典路径 * @returns */ diff --git a/src/test/index.test.ts b/src/test/index.test.ts index 595fe6f..82ec3e6 100644 --- a/src/test/index.test.ts +++ b/src/test/index.test.ts @@ -1,5 +1,6 @@ import 'mocha' import { 包含中文, 标识符模式 } from '../lib/字符串扩展' +import { 读取字典 } from '../lib/自定义' import { 获得中文字符表示 } from '../lib/获得中文表示' function 断言相等(a: any, b: any) { @@ -10,6 +11,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 0000000..b8aa93e --- /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 -- Gitee From 2dff45a102efa66323e8c5597a2cb37876d6fc8d Mon Sep 17 00:00:00 2001 From: ijklam Date: Fri, 28 Oct 2022 21:59:15 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E7=BC=93=E5=AD=98=20?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E5=9C=A8=E6=B1=89=E5=AD=97=E5=90=8E=E9=9D=A2?= =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E5=86=99=E5=AD=97=E6=AF=8D=E6=9D=A5=E8=8E=B7?= =?UTF-8?q?=E5=BE=97=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/extension.ts | 15 +++-- .../\350\207\252\345\256\232\344\271\211.ts" | 37 +----------- ...55\346\226\207\350\241\250\347\244\272.ts" | 56 ++++++++++++++++++- src/test/index.test.ts | 5 +- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 6ebe730..2df402a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,8 +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/获得配置' import { 获得输入法补全项 } from './lib/输入法' @@ -21,15 +20,15 @@ async function 完成项提供者(document: TextDocument, position: Position) { var 输入字段 = await 获得当前输入字段() if (用户配置.提示方式 === '自定义') { - await 读取字典(用户配置.自定义的字典路径); + await 载入字典(用户配置.自定义的字典路径); } else { - 删除字典(); + 清空字典(); } // 如果输入的是中文, 那么不需要构造翻译. - if (包含中文(输入字段)) { - return [] - } + // if (包含中文(输入字段)) { + // return [] + // } // 获得系统补全项 if (用户配置.分析vsc提供的补全项 == 'yes') { @@ -68,7 +67,7 @@ async function 完成项提供者(document: TextDocument, position: Position) { // 设置补全项的 filterText 补全项.forEach((a) => { let spell = 获得中文字符表示(用户配置.提示方式, a.label.toString()).toString(); - a.filterText = spell; + a.filterText = a.label + spell; }) return new vscode.CompletionList(补全项, true) 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" index ce10ae0..9b43bd5 100644 --- "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" @@ -1,44 +1,11 @@ -import * as fs from 'fs/promises'; -import { 首字母大写 } from './字符串扩展'; import { 多重笛卡尔积 } from './数组扩展'; - -var 当前字典路径: string | undefined = undefined; -let 字典: Map = new Map(); - -/** - * 字典格式:汉字\t拼写\n,允许同一个汉字有多种拼写方式 - * @param 字典路径 - * @returns - */ -export async function 读取字典(字典路径: string): Promise { - if (当前字典路径 === 字典路径) return; - 当前字典路径 = 字典路径; - 字典.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(); -} +import { 读取字典 } from './获得中文表示'; export function 自定义(文本: string): string[] { let 拼写: string[][] = []; for (let i = 0; i < 文本.length; i++) { const element = 文本[i]; - 拼写.push(字典.get(element) ?? [element]); + 拼写.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 82cb27f..1fb7f92 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" @@ -4,16 +4,66 @@ import { 多重笛卡尔积 } from './数组扩展' import { 转换为大写 } from './字符串扩展' import 拼音A from './拼音' import { 自定义 } from './自定义' +import * as fs from 'fs/promises'; +import { 首字母大写 } from './字符串扩展'; + +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 (表示方法 === '自定义') { return 自定义(文本); } + if (上次使用的表示方式 !== 表示方法) { + 缓存.clear(); + 上次使用的表示方式 = 表示方法; + } + if (缓存.has(文本)) return 缓存.get(文本)!; + + let 拼写: string[]; + if (表示方法 === '自定义') { 拼写 = 自定义(文本); } else if (表示方法.indexOf('五笔') != -1) { - return [五笔(文本, 表示方法)] + 拼写 = [五笔(文本, 表示方法)] } 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/test/index.test.ts b/src/test/index.test.ts index 82ec3e6..a46feb7 100644 --- a/src/test/index.test.ts +++ b/src/test/index.test.ts @@ -1,7 +1,6 @@ import 'mocha' import { 包含中文, 标识符模式 } from '../lib/字符串扩展' -import { 读取字典 } from '../lib/自定义' -import { 获得中文字符表示 } from '../lib/获得中文表示' +import { 获得中文字符表示, 载入字典 } from '../lib/获得中文表示' function 断言相等(a: any, b: any) { if (JSON.stringify(a) == JSON.stringify(b)) return @@ -14,7 +13,7 @@ it('获得中文字符表示', async function () { it('自定义字典', async function () { - await 读取字典('./src/test/testDict.tsv'); + await 载入字典('./src/test/testDict.tsv'); 断言相等(获得中文字符表示('自定义', '啊'), ['A']) 断言相等(获得中文字符表示('自定义', '啊陂'), ['APo', 'APi', 'ABei']) }) -- Gitee From 05d0be582c40210425a8645b7a0998523956a099 Mon Sep 17 00:00:00 2001 From: ijklam Date: Fri, 28 Oct 2022 22:05:08 +0800 Subject: [PATCH 4/4] bugfix --- src/extension.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/extension.ts b/src/extension.ts index 2df402a..381f0cb 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -68,6 +68,7 @@ async function 完成项提供者(document: TextDocument, position: Position) { 补全项.forEach((a) => { let spell = 获得中文字符表示(用户配置.提示方式, a.label.toString()).toString(); a.filterText = a.label + spell; + a.insertText ??= a.label.toString() }) return new vscode.CompletionList(补全项, true) -- Gitee