From 35c78acab6be9a59719ae51bb7050b44f5535902 Mon Sep 17 00:00:00 2001 From: fromwheretowhere Date: Sat, 8 Aug 2020 01:23:21 -0700 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E7=AC=A6=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/StringEx.js | 2 +- ...45\345\205\250\345\256\236\347\216\260.js" | 105 +++++++++--------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/lib/StringEx.js b/lib/StringEx.js index 7a7539d..22962d8 100644 --- a/lib/StringEx.js +++ b/lib/StringEx.js @@ -5,7 +5,7 @@ exports.包含中文 = function 包含中文(str) { exports.是纯字母 = function 是纯字母(str) { return /[A-Za-z]/.test(str) } -exports.查找词组 = function 查找词组(s) { +exports.查找字段 = function 查找字段(s) { var wordPattern = /(-?\d*\.\d\w*)|([^\`\~\!\@\^\&\*\(\)\-\#\?\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s?。,、;:?…—·ˉˇ¨“”~〃|《》〔〕(),]+)/g; return Array.from(new Set(s.match(wordPattern))) } diff --git "a/\350\241\245\345\205\250\345\256\236\347\216\260.js" "b/\350\241\245\345\205\250\345\256\236\347\216\260.js" index 9794be9..b9e832d 100755 --- "a/\350\241\245\345\205\250\345\256\236\347\216\260.js" +++ "b/\350\241\245\345\205\250\345\256\236\347\216\260.js" @@ -1,45 +1,44 @@ var vscode = require('vscode') var R = require('ramda') var { log } = require('./lib/LogEx') -var { 包含中文, 查找词组, 是纯字母 } = require('./lib/StringEx') +var { 包含中文, 查找字段, 是纯字母 } = require('./lib/StringEx') var { 数组去重 } = require('./lib/ArrayEx') var 获得中文字符表示 = require('./lib/GetChineseExpression') var 谷歌输入法API = require('./lib/IM_google') var 百度搜索联想 = require('./lib/IM_baidu') -function 获得当前输入词() { - // 我们需要的是文本被编辑后的情况 而不是编辑前的情况 - // 在某些地方调用 会意外的 获得文本被编辑前的情况 - // 所以加个定时器 确保函数在文本修改后执行 - // 这样函数就变成了异步的 于是加了Promise +function 获得当前输入字段() { + // 我们需要的是文本被编辑后而非编辑前的情况。 + // 为避免意外获得文本被编辑前的情况,加个定时器,确保函数在文本修改后执行。 + // 这样函数就变成了异步的,于是加了Promise。 return new Promise((res, rej) => { setTimeout(() => { - var editor = vscode.window.activeTextEditor - if (!editor) return res(null) + var 编辑器 = vscode.window.activeTextEditor + if (!编辑器) return res(null) - var position = editor.selections[0].anchor; - var document = editor.document - var range = document.getWordRangeAtPosition(position) + var 光标位置 = 编辑器.selections[0].anchor; + var 文件 = 编辑器.document + var 范围 = 文件.getWordRangeAtPosition(光标位置) - if (range == null) return res(null) + if (范围 == null) return res(null) - var 当前输入词 = document.getText(range) - return res(当前输入词) + var 当前输入字段 = 文件.getText(范围) + return res(当前输入字段) }, 0) }) } // vscode.executeCompletionItemProvider 会调用 provideCompletionItems 导致无限递归 -// 因为 js 是单线程模型 所以做了一个简单的锁 应该不会有问题 +// 因为 js 是单线程模型,所以做了一个简单的锁,应该不会有问题 var 防递归锁 = false async function provideCompletionItems(document, position, token, context) { - var 输入词 = await 获得当前输入词() || '' + var 输入字段 = await 获得当前输入字段() || '' if (防递归锁) return [] 防递归锁 = true log('================') - log('输入词', 输入词) + log('输入字段', 输入字段) // var 文件后缀名 = R.last(document.fileName.split('.')) // log('当前文件后缀名', 文件后缀名) @@ -50,65 +49,65 @@ async function provideCompletionItems(document, position, token, context) { 用户配置.提示方式 = vscode.workspace.getConfiguration('中文代码快速补全').get("提示方式") // log('用户配置', 用户配置) - var 返回对象 = [] + var 补全项 = [] - var 完成项提供程序 = await vscode.commands.executeCommand('vscode.executeCompletionItemProvider', document.uri, position) - 完成项提供程序 = 完成项提供程序.items - 返回对象 = 返回对象.concat(完成项提供程序) - // log('完成项提供程序', 完成项提供程序.map(a => a.label)) + var 补全项提供器 = await vscode.commands.executeCommand('vscode.executeCompletionItemProvider', document.uri, position) + 补全项提供器 = 补全项提供器.items + 补全项 = 补全项.concat(补全项提供器) + // log('补全项提供器', 补全项提供器.map(a => a.label)) 防递归锁 = false // 这个好像很卡 - // var 文档符号提供程序 = await vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider', document.uri) - // 文档符号提供程序 = 文档符号提供程序.map(a => new vscode.CompletionItem(a.name, a.kind)) - // 返回对象 = 返回对象.concat(文档符号提供程序) - // log('文档符号提供程序', 文档符号提供程序.map(a => a.label)) + // var 文档字段提供程序 = await vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider', document.uri) + // 文档字段提供程序 = 文档字段提供程序.map(a => new vscode.CompletionItem(a.name, a.kind)) + // 补全项 = 补全项.concat(文档字段提供程序) + // log('文档字段提供程序', 文档字段提供程序.map(a => a.label)) - var 文档符号 = R.compose(R.filter(包含中文), 查找词组)(document.getText()) - 文档符号 = 文档符号.map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text)) - 返回对象 = 返回对象.concat(文档符号) - // log('文档符号', 文档符号.map(a => a.label)) + var 文档字段 = R.compose(R.filter(包含中文), 查找字段)(document.getText()) + 文档字段 = 文档字段.map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text)) + 补全项 = 补全项.concat(文档字段) + // log('文档字段', 文档字段.map(a => a.label)) if (用户配置.使用输入法 != 'no') { - // 如果我想分别输入一个词组 例如 "多重笛卡尔积" - // 我的输入顺序是 先输入 "多重" 再输入 "笛卡尔积" 这是一个组词 而不是一次性打出来 - // 当我输入到 "多重d"的时候 `输入词`这个变量是"多重d" 如果直接拿这个词去调用输入法 很难得到正确的结果 - // 我们期待的应该是 此时 使用"d"去调用输入法 - // 但这样也是不可行的 如果我拿"d"去调用输入法 确实可以得到正确的结果 但此时 得到的结果 并不是以"多重"开头的 便不会弹出提示框 - // 因此 这里的方案是 同时获得前缀(不带字母的)的和纯字母输入词 用纯字母输入词调用输入法 再在结果前面补上前缀 - // 注意 这个策略在一些情况下会失效 例如 在汉字中间输入时 - var 前缀 = 输入词.split('').filter(a => !是纯字母(a)).join('') - var 纯字母输入词 = 输入词.split('').filter(a => 是纯字母(a)).join('') + // 如果分段输入一个词组,例如“多重笛卡尔积”,输入顺序是:先输入“多重”,再输入“笛卡尔积”。 + // 当输入到“多重d”的时候,变量`输入字段`值为“多重d”。如果直接拿这个词去调用输入法,很难得到正确的结果。 + // 但如果使用"d"去调用输入法,得到的结果并不以"多重"开头,导致不会弹出提示框。 + // 因此,这里的方案是,拆分中文部分和英文部分,用英文部分调用输入法,再在结果前面补上中文部分。 + // 注意:这个策略在一些情况下会失效,例如在中文当中输入时。 + var 中文部分 = 输入字段.split('').filter(a => !是纯字母(a)).join('') + var 英文部分 = 输入字段.split('').filter(a => 是纯字母(a)).join('') var 输入法提供的词 = [] var 输入法 = null - if (用户配置.使用输入法 == 'Google Pinyin' && 纯字母输入词 != '' && 纯字母输入词 != null) { - 输入法 = 谷歌输入法API - } else if (用户配置.使用输入法 == 'Baidu Sugrec' && 纯字母输入词 != '' && 纯字母输入词 != null) { - 输入法 = 百度搜索联想 + if (英文部分 != '' && 英文部分 != null) { + if (用户配置.使用输入法 == 'Google Pinyin') { + 输入法 = 谷歌输入法API + } else if (用户配置.使用输入法 == 'Baidu Sugrec') { + 输入法 = 百度搜索联想 + } } if (输入法 != null) { - 输入法提供的词 = await 输入法(纯字母输入词).catch(e => { + 输入法提供的词 = await 输入法(英文部分).catch(e => { console.error(e) - vscode.window.showInformationMessage(`调用输入法接口出错:` + e) + vscode.window.showInformationMessage(`调用输入法接口出错:` + e) }) - 输入法提供的词 = 输入法提供的词.map(a => 前缀 + a).map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text)) - 返回对象 = 返回对象.concat(输入法提供的词) + 输入法提供的词 = 输入法提供的词.map(a => 中文部分 + a).map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text)) + 补全项 = 补全项.concat(输入法提供的词) } } - 返回对象 = 数组去重((a, b) => a.label == b.label, 返回对象) - 返回对象 = 返回对象.filter(a => 包含中文(a.label)).filter(a => a.label != 输入词) - 返回对象 = 返回对象.map(a => R.set(R.lensProp('insertText'), a.label, a)) + 补全项 = 数组去重((a, b) => a.label == b.label, 补全项) + 补全项 = 补全项.filter(a => 包含中文(a.label)).filter(a => a.label != 输入字段) + 补全项 = 补全项.map(a => R.set(R.lensProp('insertText'), a.label, a)) - 返回对象 = 返回对象.map(a => R.set(R.lensProp('label'), `${a.label}\t${获得中文字符表示({ + 补全项 = 补全项.map(a => R.set(R.lensProp('label'), `${a.label}\t${获得中文字符表示({ 表示方法: 用户配置.提示方式, 文本: a.label, 选项: { 使用多音字: 用户配置.使用多音字 } })}`, a)) - log('返回对象', 返回对象.map(a => a.label)) - return new vscode.CompletionList(返回对象, true) + log('补全项', 补全项.map(a => a.label)) + return new vscode.CompletionList(补全项, true) } function resolveCompletionItem(item, token) { -- Gitee From 9ec3dcfbf0b8bdad2692b456bbf2c2ff43088b96 Mon Sep 17 00:00:00 2001 From: fromwheretowhere Date: Sat, 8 Aug 2020 01:51:51 -0700 Subject: [PATCH 2/2] =?UTF-8?q?=E6=A0=87=E8=AF=86=E7=AC=A6=E8=BF=98?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E5=8C=85=E5=90=AB=C2=AD=C2=89=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\350\241\245\345\205\250\345\256\236\347\216\260.js" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/\350\241\245\345\205\250\345\256\236\347\216\260.js" "b/\350\241\245\345\205\250\345\256\236\347\216\260.js" index b9e832d..cab405b 100755 --- "a/\350\241\245\345\205\250\345\256\236\347\216\260.js" +++ "b/\350\241\245\345\205\250\345\256\236\347\216\260.js" @@ -73,9 +73,9 @@ async function provideCompletionItems(document, position, token, context) { // 如果分段输入一个词组,例如“多重笛卡尔积”,输入顺序是:先输入“多重”,再输入“笛卡尔积”。 // 当输入到“多重d”的时候,变量`输入字段`值为“多重d”。如果直接拿这个词去调用输入法,很难得到正确的结果。 // 但如果使用"d"去调用输入法,得到的结果并不以"多重"开头,导致不会弹出提示框。 - // 因此,这里的方案是,拆分中文部分和英文部分,用英文部分调用输入法,再在结果前面补上中文部分。 + // 因此,这里的方案是,拆分非英文部分和英文部分,用英文部分调用输入法,再在结果前面补上非英文部分。 // 注意:这个策略在一些情况下会失效,例如在中文当中输入时。 - var 中文部分 = 输入字段.split('').filter(a => !是纯字母(a)).join('') + var 非英文部分 = 输入字段.split('').filter(a => !是纯字母(a)).join('') var 英文部分 = 输入字段.split('').filter(a => 是纯字母(a)).join('') var 输入法提供的词 = [] var 输入法 = null @@ -91,7 +91,7 @@ async function provideCompletionItems(document, position, token, context) { console.error(e) vscode.window.showInformationMessage(`调用输入法接口出错:` + e) }) - 输入法提供的词 = 输入法提供的词.map(a => 中文部分 + a).map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text)) + 输入法提供的词 = 输入法提供的词.map(a => 非英文部分 + a).map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text)) 补全项 = 补全项.concat(输入法提供的词) } } -- Gitee