diff --git a/.vscode/launch.json b/.vscode/launch.json
index 2bed8921e2803711f9c40a8be24fb242600ae42e..76cd0de96e1df539eb91c23192cab2abbf15194f 100755
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,9 +10,12 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
+ "env": {
+ "NODE_ENV": "dev"
+ },
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
- // "--disable-extensions"
+ "--disable-extensions"
]
},
{
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5c02960963d0d844310becadda23fa24e44abad2..37335f1524f3321bc56d225f23340f8e614c3712 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
## 各版本更新说明
+### 1.3.0
+
+- 修复:[JS 原补全项消失问题](https://gitee.com/Program-in-Chinese/vscode_Chinese_Input_Assistant/issues/I1Q34I)
+- 修复:[C++ 语言插件不兼容问题](https://gitee.com/Program-in-Chinese/vscode_Chinese_Input_Assistant/issues/I1PWE7)
+
### 1.2.1
修复问题: [补全项重复](https://gitee.com/Program-in-Chinese/vscode_Chinese_Input_Assistant/issues/I1PUZX)
diff --git a/README.md b/README.md
index 02267546074a7a19ae6b90171830bb5083b93a7c..06ea1d4a8c2e8d76f23bf687ef724d44dd4b30dc 100755
--- a/README.md
+++ b/README.md
@@ -44,28 +44,12 @@

-支持各种编程语言,全拼下已实测过的:
-
-- C#
-
-
-
-- Haskell
-
-
-
-- Java
-
-
+与各种编程语言的现有支持插件兼容,全拼下已实测过的:
- JavaScript

-- Kotlin
-
-
-
- PHP
对 $ 开头的变量名,直接输入拼音即有提示:
@@ -76,14 +60,14 @@

-- Swift
-
-
-
- TypeScript

+当无编程语言支持插件时,也支持当前文件中的中文字段补全:
+
+
+
同样支持中英混合命名:

@@ -96,6 +80,4 @@
## [版本更新说明](CHANGELOG.md)
-## 已知问题
-
-暂无
+## [已知问题](文档/已知问题.md)
diff --git a/lib/vscode.js b/lib/vscode.js
new file mode 100644
index 0000000000000000000000000000000000000000..d74a401ee78a1fa2bc6a8aa12a6e20c73113b350
--- /dev/null
+++ b/lib/vscode.js
@@ -0,0 +1,44 @@
+var vscode = require('vscode')
+var R = require('ramda')
+
+exports.获得当前输入词 = function 获得当前输入词() {
+ // 我们需要的是文本被编辑后的情况 而不是编辑前的情况
+ // 在某些地方调用 会意外的 获得文本被编辑前的情况
+ // 所以加个定时器 确保函数在文本修改后执行
+ // 这样函数就变成了异步的 于是加了Promise
+ return new Promise((res, rej) => {
+ setTimeout(() => {
+ var editor = vscode.window.activeTextEditor
+ if (!editor) return res(null)
+
+ var position = editor.selections[0].anchor;
+ var document = editor.document
+ var range = document.getWordRangeAtPosition(position)
+
+ if (range == null) return res(null)
+
+ var 当前输入词 = document.getText(range)
+ return res(当前输入词)
+ }, 0)
+ })
+}
+exports.获得当前文件后缀名 = function 获得当前文件后缀名({ document }) {
+ return R.last(document.fileName.split('.'))
+}
+exports.获得文档内容 = function 获得文档内容(document, position) {
+ var 总行数 = document.lineCount
+ var 当前行 = position.line
+ var 文档内容 = ""
+ for (var i = 0; i < 总行数; i++) {
+ if (i != 当前行)
+ 文档内容 += document.lineAt(i).text + "\n";
+ }
+ return 文档内容
+}
+exports.构造文本补全项 = function 构造文本补全项({ 标签, 内容 }) {
+ var r = new vscode.CompletionItem(标签)
+ r.label = 标签
+ r.kind = 'text'
+ r.insertText = 内容
+ return r
+}
diff --git "a/\344\272\224\347\254\224\350\276\223\345\205\245\346\263\225.js" "b/lib/\344\272\224\347\254\224.js"
similarity index 70%
rename from "\344\272\224\347\254\224\350\276\223\345\205\245\346\263\225.js"
rename to "lib/\344\272\224\347\254\224.js"
index c10470b67f3d519551019dcc0ef09dd0a12428c6..1c92b2fde16efaeb71f7c7718f6337791b614cd7 100644
--- "a/\344\272\224\347\254\224\350\276\223\345\205\245\346\263\225.js"
+++ "b/lib/\344\272\224\347\254\224.js"
@@ -4,7 +4,7 @@ function 五笔(文字, 提示方式) {
if (!文字) return "";
var 键码 = "";
var 非汉字字符计数 = 0
- var 版本=提示方式.substr(2,2);
+ var 版本 = 提示方式.substr(2, 2);
for (var i = 0, len = 文字.length; i < len; i++) {
var 字 = 文字.substr(i, 1);
var unicode = 字.charCodeAt(0);
@@ -12,23 +12,21 @@ function 五笔(文字, 提示方式) {
if (unicode > 40869 || unicode < 19968) {
键码 += 字
非汉字字符计数++
- } else if (提示方式.indexOf("全码")!=-1) {
- 键码 += 首字母大写(码表.取码(字,版本))
- } else if (提示方式.indexOf("四码")!=-1) {
+ } else if (提示方式.indexOf("全码") != -1) {
+ 键码 += 首字母大写(码表.取码(字, 版本))
+ } else if (提示方式.indexOf("四码") != -1) {
if (文字.length - 非汉字字符计数 == 1) {
- 键码 += 码表.取码(字,版本)
+ 键码 += 码表.取码(字, 版本)
} else if (文字.length - 非汉字字符计数 == 2) {
- 键码 += 码表.取码(字,版本).slice(0, 2)
+ 键码 += 码表.取码(字, 版本).slice(0, 2)
} else if (文字.length - 非汉字字符计数 == 3) {
- 键码 += 码表.取码(字,版本).slice(0, i - 非汉字字符计数 < 2 ? 1 : 2)
+ 键码 += 码表.取码(字, 版本).slice(0, i - 非汉字字符计数 < 2 ? 1 : 2)
} else if (文字.length - 非汉字字符计数 >= 4 && (i - 非汉字字符计数 < 3 || i + 1 - 非汉字字符计数 == 文字.length)) {
- 键码 += 码表.取码(字,版本).slice(0, 1)
+ 键码 += 码表.取码(字, 版本).slice(0, 1)
}
}
}
return 键码;
-
-
}
function 首字母大写(拼音) {
if (拼音.length > 0) {
diff --git "a/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.js" "b/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.js"
index dc598177758347cbd7644f579e7a2053836092e6..7a7539df19f08dc23b835f98011ba552950f8900 100644
--- "a/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.js"
+++ "b/lib/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225.js"
@@ -1 +1,11 @@
exports.转换为大写 = 字符串 => 字符串.toLocaleUpperCase()
+exports.包含中文 = function 包含中文(str) {
+ return /.*[\u4e00-\u9fa5]+.*$/.test(str)
+}
+exports.是纯字母 = function 是纯字母(str) {
+ return /[A-Za-z]/.test(str)
+}
+exports.查找词组 = function 查找词组(s) {
+ var wordPattern = /(-?\d*\.\d\w*)|([^\`\~\!\@\^\&\*\(\)\-\#\?\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s?。,、;:?…—·ˉˇ¨“”~〃|《》〔〕(),]+)/g;
+ return Array.from(new Set(s.match(wordPattern)))
+}
diff --git a/bopomofo.js "b/lib/\346\213\274\351\237\263.js"
similarity index 100%
rename from bopomofo.js
rename to "lib/\346\213\274\351\237\263.js"
diff --git "a/lib/\346\225\260\347\273\204\346\211\251\345\261\225.js" "b/lib/\346\225\260\347\273\204\346\211\251\345\261\225.js"
index 50f8042caa62ee07234ad5bd2de148770975a7a6..016627cf982a27b548da25a1cea889f9ec0edb99 100644
--- "a/lib/\346\225\260\347\273\204\346\211\251\345\261\225.js"
+++ "b/lib/\346\225\260\347\273\204\346\211\251\345\261\225.js"
@@ -1 +1,17 @@
exports.多重笛卡尔积 = arr => arr.reduce((as, bs) => as.map(a => bs.map(b => [...a, b])).flat(), [[]])
+exports.数组去重 = (判别式, 数组) => {
+ var 包含 = (判别式, 项, 数组) => {
+ for (var i = 0; i < 数组.length; i++) {
+ if (判别式(数组[i], 项))
+ return true
+ }
+ return false
+ }
+
+ var r = []
+ for (var i = 0; i < 数组.length; i++) {
+ if (!包含(判别式, 数组[i], r))
+ r.push(数组[i])
+ }
+ return r
+}
diff --git "a/lib/\346\227\245\345\277\227.js" "b/lib/\346\227\245\345\277\227.js"
new file mode 100644
index 0000000000000000000000000000000000000000..4f020f15766206c4525e9ea2dba9ff7d6bbdb124
--- /dev/null
+++ "b/lib/\346\227\245\345\277\227.js"
@@ -0,0 +1,6 @@
+exports.log = (...s) => {
+ if (process.env.NODE_ENV == 'dev') {
+ console.log(...s.map(a => JSON.stringify(a)))
+ }
+ return s[s.length - 1]
+}
diff --git "a/lib/\347\231\276\345\272\246\346\220\234\347\264\242\350\201\224\346\203\263.js" "b/lib/\347\231\276\345\272\246\346\220\234\347\264\242\350\201\224\346\203\263.js"
index f2e770b91fcefbcc776c02a7d4faa85821082594..b30f124549fc3f89ce5ff97aec83d8949f0a6da1 100644
--- "a/lib/\347\231\276\345\272\246\346\220\234\347\264\242\350\201\224\346\203\263.js"
+++ "b/lib/\347\231\276\345\272\246\346\220\234\347\264\242\350\201\224\346\203\263.js"
@@ -1,6 +1,6 @@
const http = require('./http')
-module.exports = 字符串 => async 数量 => {
+module.exports = async (字符串, 数量 = 5) => {
if (字符串.indexOf('\r') != -1 || 字符串.indexOf('\n') != -1) return []
// console.log(字符串)
var url = `https://www.baidu.com/sugrec?prod=pc&from=pc_web&wd=${字符串}`
diff --git "a/lib/\350\216\267\345\276\227\344\270\255\346\226\207\345\255\227\347\254\246\350\241\250\347\244\272.js" "b/lib/\350\216\267\345\276\227\344\270\255\346\226\207\345\255\227\347\254\246\350\241\250\347\244\272.js"
new file mode 100644
index 0000000000000000000000000000000000000000..6ce4aefe7d80654d2ec35f188717bfc395095321
--- /dev/null
+++ "b/lib/\350\216\267\345\276\227\344\270\255\346\226\207\345\255\227\347\254\246\350\241\250\347\244\272.js"
@@ -0,0 +1,20 @@
+var 五笔 = require('./五笔.js')
+var 拼音A = require('./拼音.js')
+var 拼音 = require('pinyin')
+var { 多重笛卡尔积 } = require('./数组扩展.js')
+var { 转换为大写 } = require('./字符串扩展')
+
+module.exports = function 获得中文字符表示({ 表示方法, 文本, 选项 }) {
+ if (表示方法.indexOf("五笔") != -1) {
+ return [五笔.五笔(文本, 表示方法)]
+ }
+ if (表示方法.indexOf('拼音')) {
+ var 结果 = null
+ 结果 = 拼音(文本, { heteronym: 选项.使用多音字 == 'yes', style: 拼音.STYLE_NORMAL })
+ 结果 = 结果.map(a => a.map(a => 转换为大写(a[0]) + a.substring(1)))
+ 结果 = 多重笛卡尔积(结果).map(a => a.join(''))
+ if (表示方法 != "全拼")
+ 结果 = 结果.map(a => 拼音A.双拼转换(a, 表示方法))
+ return 结果
+ }
+}
diff --git "a/lib/\350\260\267\346\255\214\350\276\223\345\205\245\346\263\225API.js" "b/lib/\350\260\267\346\255\214\350\276\223\345\205\245\346\263\225API.js"
index 220b0b15adc36ce756ff67d25917cae4522ce7fe..2f4fde96c045e7024381e04f197fe4564391ddab 100644
--- "a/lib/\350\260\267\346\255\214\350\276\223\345\205\245\346\263\225API.js"
+++ "b/lib/\350\260\267\346\255\214\350\276\223\345\205\245\346\263\225API.js"
@@ -1,7 +1,7 @@
const http = require('./http')
// api使用来自 https://github.com/zyctree/vscode-google-pinyin
-module.exports = 字符串 => async 数量 => {
+module.exports = async (字符串, 数量 = 5) => {
if (字符串.indexOf('\r') != -1 || 字符串.indexOf('\n') != -1) return []
// console.log(字符串)
var url = `http://inputtools.google.com/request?text=${字符串}&itc=zh-t-i0-pinyin&num=${数量}&cp=0&cs=1&ie=utf-8&oe=utf-8&app=demopage`
diff --git a/package-lock.json b/package-lock.json
index 110cb8fdd1907b9fadf2bf97af3931271bf92810..af6054e15d19a3ee3f6563cdc3f977c2d8dde7c5 100755
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "ChineseInputAssistant",
- "version": "1.2.1",
+ "version": "1.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index c72f35db4ee47a0830753cc7739e584f9e77a5a9..db15b3179e7f7c4878a002b346cb86a90ba43e5b 100755
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "ChineseInputAssistant",
"displayName": "中文代码快速补全",
"description": "中文标识符(变量、方法名等)无需切换中文输入法即有补全提示",
- "version": "1.2.1",
+ "version": "1.3.0",
"publisher": "CodeInChinese",
"engines": {
"vscode": "^1.38.0"
@@ -14,14 +14,8 @@
"*",
"onCommand:插件命令"
],
- "main": "./插件.js",
+ "main": "./入口.js",
"contributes": {
- "commands": [
- {
- "command": "插件命令",
- "title": "中文插件"
- }
- ],
"configuration": {
"title": "中文代码快速补全",
"properties": {
@@ -53,7 +47,7 @@
],
"enumDescriptions": [
"不使用输入法",
- "谷歌拼音输入法",
+ "谷歌拼音输入法(需能访问谷歌api)",
"百度搜索联想"
]
},
diff --git a/util.js b/util.js
deleted file mode 100755
index 6feb47b8713be06f6d0301655d945a772d822b28..0000000000000000000000000000000000000000
--- a/util.js
+++ /dev/null
@@ -1,259 +0,0 @@
-const fs = require('fs');
-const os = require('os');
-const path = require('path');
-const vscode = require('vscode');
-const exec = require('child_process').exec;
-
-const util = {
- /**
- * 获取当前所在工程根目录,有3种使用方法:
- * getProjectPath(uri) uri 表示工程内某个文件的路径
- * getProjectPath(document) document 表示当前被打开的文件document对象
- * getProjectPath() 会自动从 activeTextEditor 拿document对象,如果没有拿到则报错
- * @param {*} document
- */
- getProjectPath(document) {
- if (!document) {
- document = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document : null;
- }
- if (!document) {
- this.showError('当前激活的编辑器不是文件或者没有文件被打开!');
- return '';
- }
- const currentFile = (document.uri ? document.uri : document).fsPath;
- let projectPath = null;
-
- let workspaceFolders = vscode.workspace.workspaceFolders.map(item => item.uri.path);
- // 由于存在Multi-root工作区,暂时没有特别好的判断方法,先这样粗暴判断
- // 如果发现只有一个根文件夹,读取其子文件夹作为 workspaceFolders
- if (workspaceFolders.length == 1 && workspaceFolders[0] === vscode.workspace.rootPath) {
- const rootPath = workspaceFolders[0];
- var files = fs.readdirSync(rootPath);
- workspaceFolders = files.filter(name => !/^\./g.test(name)).map(name => path.resolve(rootPath, name));
- // vscode.workspace.rootPath会不准确,且已过时
- // return vscode.workspace.rootPath + '/' + this._getProjectName(vscode, document);
- }
- workspaceFolders.forEach(folder => {
- if (currentFile.indexOf(folder) === 0) {
- projectPath = folder;
- }
- })
- if (!projectPath) {
- this.showError('获取工程根路径异常!');
- return '';
- }
- return projectPath;
- },
- /**
- * 获取当前工程名
- */
- getProjectName: function (projectPath) {
- return path.basename(projectPath);
- },
- getPluginPath() {
-
- },
- /**
- * 将一个单词首字母大写并返回
- * @param {*} word 某个字符串
- */
- upperFirstLetter: function (word) {
- return (word || '').replace(/^\w/, m => m.toUpperCase());
- },
- /**
- * 将一个单词首字母转小写并返回
- * @param {*} word 某个字符串
- */
- lowerFirstLeter: function (word) {
- return (word || '').replace(/^\w/, m => m.toLowerCase());
- },
- /**
- * 全局日志开关,发布时可以注释掉日志输出
- */
- log: function (...args) {
- console.log(...args);
- },
- /**
- * 全局日志开关,发布时可以注释掉日志输出
- */
- error: function (...args) {
- console.error(...args);
- },
- /**
- * 弹出错误信息
- */
- showError: function (info) {
- vscode.window.showErrorMessage(info);
- },
- /**
- * 弹出提示信息
- */
- showInfo: function (info) {
- vscode.window.showInformationMessage(info);
- },
- findStrInFolder: function (folderPath, str) {
-
- },
- /**
- * 从某个文件里面查找某个字符串,返回第一个匹配处的行与列,未找到返回第一行第一列
- * @param filePath 要查找的文件
- * @param reg 正则对象,最好不要带g,也可以是字符串
- */
- findStrInFile: function (filePath, reg) {
- const content = fs.readFileSync(filePath, 'utf-8');
- reg = typeof reg === 'string' ? new RegExp(reg, 'm') : reg;
- // 没找到直接返回
- if (content.search(reg) < 0) return { row: 0, col: 0 };
- const rows = content.split(os.EOL);
- // 分行查找只为了拿到行
- for (let i = 0; i < rows.length; i++) {
- let col = rows[i].search(reg);
- if (col >= 0) {
- return { row: i, col };
- }
- }
- return { row: 0, col: 0 };
- },
- /**
- * 获取某个字符串在文件里第一次出现位置的范围,
- */
- getStrRangeInFile: function (filePath, str) {
- var pos = this.findStrInFile(filePath, str);
- return new vscode.Range(new vscode.Position(pos.row, pos.col), new vscode.Position(pos.row, pos.col + str.length));
- },
- /**
- * 简单的检测版本大小
- */
- checkVersion: function (version1, version2) {
- version1 = parseInt(version1.replace(/\./g, ''));
- version2 = parseInt(version2.replace(/\./g, ''));
- return version1 > version2;
- },
- /**
- * 获取某个扩展文件绝对路径
- * @param context 上下文
- * @param relativePath 扩展中某个文件相对于根目录的路径,如 images/test.jpg
- */
- getExtensionFileAbsolutePath: function (context, relativePath) {
- return path.join(context.extensionPath, relativePath);
- },
- /**
- * 获取某个扩展文件相对于webview需要的一种特殊路径格式
- * 形如:vscode-resource:/Users/toonces/projects/vscode-cat-coding/media/cat.gif
- * @param context 上下文
- * @param relativePath 扩展中某个文件相对于根目录的路径,如 images/test.jpg
- */
- getExtensionFileVscodeResource: function (context, relativePath) {
- const diskPath = vscode.Uri.file(path.join(context.extensionPath, relativePath));
- return diskPath.with({ scheme: 'vscode-resource' }).toString();
- },
- /**
- * 在Finder中打开某个文件或者路径
- */
- openFileInFinder: function (filePath) {
- if (!fs.existsSync(filePath)) {
- this.showError('文件不存在:' + filePath);
- }
- // 如果是目录,直接打开就好
- if (fs.statSync(filePath).isDirectory()) {
- exec(`open ${filePath}`);
- } else {
- // 如果是文件,要分开处理
- const fileName = path.basename(filePath);
- filePath = path.dirname(filePath);
- // 这里有待完善,还不知道如何finder中如何选中文件
- exec(`open ${filePath}`);
- }
- },
- /**
- * 在vscode中打开某个文件
- * @param {*} path 文件绝对路径
- * @param {*} text 可选,如果不为空,则选中第一处匹配的对应文字
- */
- openFileInVscode: function (path, text) {
- let options = undefined;
- if (text) {
- const selection = this.getStrRangeInFile(path, text);
- options = { selection };
- }
- vscode.window.showTextDocument(vscode.Uri.file(path), options);
- },
- /**
- * 用JD-GUI打开jar包
- */
- openJarByJdGui: function (jarPath) {
- // 如何选中文件有待完善
- const jdGuiPath = vscode.workspace.getConfiguration().get('eggHelper.jdGuiPath');
- if (!jdGuiPath) {
- this.showError('JD-GUI路径不能为空!');
- return;
- }
- if (!fs.existsSync(jdGuiPath)) {
- this.showError('您还没有安装JD-GUI,请安装完后到vscode设置里面找到HSF助手并进行路径配置。');
- return;
- }
- if (!fs.existsSync(jarPath)) {
- this.showError('jar包未找到:' + jarPath);
- return;
- }
- exec(`open ${jarPath} -a ${jdGuiPath}`);
- },
- /**
- * 使用默认浏览器中打开某个URL
- */
- openUrlInBrowser: function (url) {
- exec(`open '${url}'`);
- },
- /**
- * 递归遍历清空某个资源的require缓存
- * @param {*} absolutePath
- */
- clearRequireCache(absolutePath) {
- const root = require.cache[absolutePath];
- if (!root) return;
- if (root.children) {
- // 如果有子依赖项,先清空依赖项的缓存
- root.children.forEach(item => {
- this.clearRequireCache(item.id);
- });
- }
- delete require.cache[absolutePath];
- },
- /**
- * 动态require,和普通require不同的是,加载之前会先尝试删除缓存
- * @param {*} modulePath
- */
- dynamicRequire(modulePath) {
- this.clearRequireCache(modulePath);
- return require(modulePath);
- },
- /**
- * 读取properties文件
- * @param {*} filePath
- */
- readProperties(filePath) {
- const content = fs.readFileSync(filePath, 'utf-8');
- let rows = content.split(os.EOL);
- rows = rows.filter(row => row && row.trim() && !/^#/.test(row));
- const result = {};
- rows.forEach(row => {
- let temp = row.split('=');
- result[temp[0].trim()] = temp[1].trim();
- });
- return result;
- },
- /**
- * 比较2个对象转JSON字符串后是否完全一样
- * 特别注意,由于JS遍历对象的无序性(部分浏览器是按照添加顺序遍历的)导致同样的对象,
- * 转成JSON串之后反而不一样,所以这里采用其它方式实现。
- * @param {*} obj1
- * @param {*} obj2
- */
- jsonEquals(obj1, obj2) {
- let s1 = this.formatToSpecialJSON(obj1, '', true);
- let s2 = this.formatToSpecialJSON(obj2, '', true);
- return s1 === s2;
- }
-};
-
-module.exports = util;
diff --git a/vsc-extension-quickstart.md b/vsc-extension-quickstart.md
deleted file mode 100755
index e6da2a5c8e5a2590cb867d8a5fc207800b190639..0000000000000000000000000000000000000000
--- a/vsc-extension-quickstart.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Welcome to your VS Code Extension
-
-## What's in the folder
-
-* This folder contains all of the files necessary for your extension.
-* `package.json` - this is the manifest file in which you declare your extension and command.
- * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin.
-* `extension.js` - this is the main file where you will provide the implementation of your command.
- * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
- * We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
-
-## Get up and running straight away
-
-* Press `F5` to open a new window with your extension loaded.
-* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
-* Set breakpoints in your code inside `extension.js` to debug your extension.
-* Find output from your extension in the debug console.
-
-## Make changes
-
-* You can relaunch the extension from the debug toolbar after changing code in `extension.js`.
-* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
-
-## Explore the API
-
-* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`.
-
-## Run tests
-
-* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`.
-* Press `F5` to run the tests in a new window with your extension loaded.
-* See the output of the test result in the debug console.
-* Make changes to `src/test/suite/extension.test.js` or create new test files inside the `test/suite` folder.
- * The provided test runner will only consider files matching the name pattern `**.test.ts`.
- * You can create folders inside the `test` folder to structure your tests any way you want.
-## Go further
-
- * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace.
- * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).
diff --git "a/\344\276\233\346\265\213\350\257\225/cpp/hello.cpp" "b/\344\276\233\346\265\213\350\257\225/cpp/hello.cpp"
new file mode 100644
index 0000000000000000000000000000000000000000..fc088cced4efba3a7c1538cd95545410aeb3970f
--- /dev/null
+++ "b/\344\276\233\346\265\213\350\257\225/cpp/hello.cpp"
@@ -0,0 +1,19 @@
+#include
+#include
+#include
+
+/*
+源自: https://code.visualstudio.com/docs/cpp/config-clang-mac#_add-hello-world-source-code-file
+*/
+using namespace std;
+
+int main()
+{
+ vector msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};
+
+ for (const string& word : msg)
+ {
+ cout << word << " ";
+ }
+ cout << endl;
+}
\ No newline at end of file
diff --git "a/\344\276\233\346\265\213\350\257\225/cpp/main.cpp" "b/\344\276\233\346\265\213\350\257\225/cpp/main.cpp"
index 64d0c7ad764f78abe0133f0c4eddfd68157be78a..942343176de34a5826da1fa3298e92bb3389674c 100644
--- "a/\344\276\233\346\265\213\350\257\225/cpp/main.cpp"
+++ "b/\344\276\233\346\265\213\350\257\225/cpp/main.cpp"
@@ -5,6 +5,8 @@ using namespace std;
int main()
{
Circle 椭圆(3);
+ Circle oval(3);
+
// 输入 tuo 补全为 椭圆 再输入 点
return 1;
diff --git "a/\344\276\233\346\265\213\350\257\225/js/index.js" "b/\344\276\233\346\265\213\350\257\225/js/index.js"
index 585b5cff055bfacd24918d0cad64d59beda9a916..f4535ab04965c7a0b8a790e7e64429c3ab2edc70 100644
--- "a/\344\276\233\346\265\213\350\257\225/js/index.js"
+++ "b/\344\276\233\346\265\213\350\257\225/js/index.js"
@@ -3,6 +3,19 @@ import lib_esm from './lib_esm'
var lib_node = require('./lib_node')
var 中文变量 = 1
+function 加法() { }
+function add() { }
+
+零蛋 = 0
+zero = 0
+
+战国时代 = 1
+
+class 小类 { }
+class aClass { }
+
+多重笛卡尔积 = 0
+
// 输入 lib_esm.zw
// 输入 lib_node.zw
// 输入 zw
diff --git "a/\345\205\245\345\217\243.js" "b/\345\205\245\345\217\243.js"
new file mode 100644
index 0000000000000000000000000000000000000000..a7471db3d6005fd765157ff1ffeb3f0acd2aed98
--- /dev/null
+++ "b/\345\205\245\345\217\243.js"
@@ -0,0 +1,9 @@
+var vscode = require('vscode')
+var 补全实现 = require('./补全实现')
+
+function activate(context) {
+ console.log('恭喜,插件已激活')
+ 补全实现(context)
+}
+
+exports.activate = activate
diff --git "a/\346\210\252\345\233\276/\346\274\224\347\244\272_Haskell.png" "b/\346\210\252\345\233\276/\346\274\224\347\244\272_Haskell.png"
deleted file mode 100644
index a4a44d32a05d367c5af94d38d99a4403b2de35a7..0000000000000000000000000000000000000000
Binary files "a/\346\210\252\345\233\276/\346\274\224\347\244\272_Haskell.png" and /dev/null differ
diff --git "a/\346\210\252\345\233\276/\346\274\224\347\244\272_Java.png" "b/\346\210\252\345\233\276/\346\274\224\347\244\272_Java.png"
deleted file mode 100644
index 7858d3aed4b5c346f4255d12ea2d1e7b1e93b1fc..0000000000000000000000000000000000000000
Binary files "a/\346\210\252\345\233\276/\346\274\224\347\244\272_Java.png" and /dev/null differ
diff --git "a/\346\210\252\345\233\276/\346\274\224\347\244\272_Swift.png" "b/\346\210\252\345\233\276/\346\274\224\347\244\272_Swift.png"
deleted file mode 100644
index bb97d6a4c1657ebb9ac34a77e09fc6fe36c2fb69..0000000000000000000000000000000000000000
Binary files "a/\346\210\252\345\233\276/\346\274\224\347\244\272_Swift.png" and /dev/null differ
diff --git "a/\346\210\252\345\233\276/\346\274\224\347\244\272_c.png" "b/\346\210\252\345\233\276/\346\274\224\347\244\272_c.png"
deleted file mode 100644
index b7f0e0026a3eff0eefcffdb4f80edda76728e664..0000000000000000000000000000000000000000
Binary files "a/\346\210\252\345\233\276/\346\274\224\347\244\272_c.png" and /dev/null differ
diff --git "a/\346\217\222\344\273\266.js" "b/\346\217\222\344\273\266.js"
deleted file mode 100755
index 9b4db9585048de06fdce941c27887dc4d19db696..0000000000000000000000000000000000000000
--- "a/\346\217\222\344\273\266.js"
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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 util = require('./util');
-// 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('恭喜,插件已激活');
- require('./补全实现')(context);
- // 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.json
- let disposable = vscode.commands.registerCommand('插件命令', function () {
- // The code you place here will be executed every time your command is executed
-
- // Display a message box to the user
- vscode.window.showInformationMessage('喵');
- });
-
- context.subscriptions.push(disposable);
-}
-
-
-
-exports.activate = activate;
-
-// this method is called when your extension is deactivated
-function deactivate() { }
-
-module.exports = {
- activate,
- deactivate
-}
-
diff --git "a/\346\226\207\346\241\243/\345\212\237\350\203\275.md" "b/\346\226\207\346\241\243/\345\212\237\350\203\275.md"
new file mode 100644
index 0000000000000000000000000000000000000000..e738dba7d7936ceb59cc27499b019273ce957654
--- /dev/null
+++ "b/\346\226\207\346\241\243/\345\212\237\350\203\275.md"
@@ -0,0 +1,219 @@
+## 功能简述
+
+在不影响 VS Code 的现有代码补全功能的前提下,不用切换到第三方中文输入法,就可以通过拼音等方式获得对应的中文代码补全。
+
+## 术语表
+
+参考:[VSC IntelliSense 官方文档](https://code.visualstudio.com/docs/editor/intellisense)
+
+| 中文 | 英文 | 简述 |
+| ------------- | ------------- | ------------- |
+| 代码补全 | code completion | |
+| 触发字符 | trigger character | 比如 JavaScript 中的 . |
+| 建议弹窗 | suggestions widget | 光标下方的包含建议补全项的窗口 |
+| 关键词 | keyword | 编程语言语法中的保留关键词,如 [JS](https://www.w3schools.com/js/js_reserved.asp)中的 const,continue 等 |
+| 标识符 | identifier | 关键词之外的代码内容,包括变量、方法、类名等等 |
+| 字段 | | 包括标识符、注释中的中文字段
+
+关键词、标识符分类:
+| 图标 | 中文 | 英文 | 简述 |
+| ------------- | ------------- | ------------- | ------------- |
+|  | 方法 | method, function |
+|  | 变量 | variable |
+|  | 域 | field |
+|  | 类 | class |
+|  | 接口 | interface |
+|  | 模块 | module |
+|  | 属性 | Properties and Attributes |
+|  | 枚举 | Values and Enumerations |
+|  | 引用 | reference |
+|  | 关键词 | keyword |
+|  | 颜色 | color |
+|  | 单位 | unit |
+|  | 代码片段 | (code) snippet |
+|  | 词语 | Words | 不归属于上述种类的内容
+
+# 详细功能
+
+编程语言按字母顺序排列。
+
+## JavaScript
+
+此部分 JS 相关,今后逐步补充其他语言。***由于各测试平台的库有所不同,补全项中的自动导入(auto import)相关部分不在测试范围内。***
+
+### 无本插件时
+
+使用 VS Code 默认补全配置。在新工作区中拷贝[测试目录](../供测试/js/)进行测试。
+
+#### 英文标识符、关键词
+
+下面的用例,按照建议弹窗第一项的种类分成几部分。如有更加接近实用的用例,欢迎改进。
+
+***可能不需输入所有字符,就会出现在建议弹窗内容第一项,并且之后还有其他项(种类可能各异)。以下无特殊说明也是如此。***
+
+| 种类 | 输入 |
+| ------------- | ------------- |
+方法(语言内置) | isFinite
+方法(自定义)| add
+变量(语言内置) | console
+变量(自定义) | lib_esm
+域 | add.arguments
+类 | aClass
+关键词 | new
+代码片段 | log
+词语 | zero
+模块 |【待添加】
+枚举 |【待添加】
+接口 |【暂未重现】
+属性 |【暂未重现】
+引用 |【暂未重现】
+
+#### 中文标识符
+
+| 种类 | 输入 |
+| ------------- | ------------- |
+域 | lib_esm.中文
+变量 | 中文变量
+词语 | lib_esm.中文变量
+
+【待补完】
+
+### 安装本插件后
+
+#### 英文标识符、关键词
+
+应与无插件时效果相同。
+
+#### 中文标识符
+
+中文输入状态下,应与无插件时效果相同。
+
+下面为英文输入状态下,不同中文匹配方式。
+
+- 全拼
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+方法 | jf | 加法
+变量 | zwbl | 中文变量
+域 | lib_esm.zw | 中文
+类 | xiaol | 小类
+代码片段 | chux | ChuXianCiShu
+词语 | lingd | 零蛋
+关键词 |【无中文关键词】
+模块 |【待添加】
+枚举 |【待添加】
+
+- 五笔
+
+98全码下,输入“hljw”,出现“战国时代”
+
+## C++
+
+测试时使用[此语言插件](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)。测试源码[在此](../供测试/cpp/main.cpp)。
+
+### 无本插件时
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+方法 | oval.求 | 求面积
+变量 | oval | oval
+变量 | 椭 | 椭圆
+
+### 安装本插件后
+
+无本插件的用例仍可用之外:
+
+注意:“椭圆”的种类本来是“变量”,现在是“词语”
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+方法 | oval.qiu 或 椭圆.qiu | 补全为(仅支持当前文件中的字段)
+***词语*** | tuoyuan | 椭圆
+
+## PHP
+
+测试时使用[此语言插件](https://marketplace.visualstudio.com/items?itemName=ms-python.python)。测试源码[在此](../供测试/斐波那契.py)。
+
+### 无本插件时
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+方法 | join | join
+关键词 | echo | echo
+变量 | $数列 | $数列
+
+### 安装本插件后
+
+无本插件的用例仍可用之外:
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+词语 | shulie | $数列
+
+## Python
+
+测试时使用[此语言插件](https://marketplace.visualstudio.com/items?itemName=ms-python.python)。测试源码[在此](../供测试/斐波那契.py)。
+
+### 无本插件时
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+方法 | print | print
+关键词 | for | for
+变量 | 数 | 数
+
+### 安装本插件后
+无本插件的用例仍可用之外:
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+变量 | feibonaqi | 斐波那契
+
+## TypeScript
+
+测试源码[在此](../供测试/加载词典.ts)。
+
+### 无本插件时
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+方法 | print | print
+关键词 | function | function
+变量 | 词典数据 | 词典数据
+
+### 安装本插件后
+
+无本插件的用例仍可用之外:
+
+| 种类 | 输入 | 补全项文本 |
+| ------------- | ------------- | ------------- |
+变量 | cidianshuju | 词典数据
+
+## 编程语言无关
+
+### 无语言支持插件时
+
+如果并未安装当前源码文件对应的编程语言插件,将按照文本文件处理,支持当前文件中的中文字段的补全。比如在未安装 Kotline 插件时,在[此源码](../供测试/你好.kt) 中输入“ygd”会出现“应该等于”补全。
+
+### 第三方 API
+
+配置项中可以选择百度搜索、谷歌拼音等 API。在输入英文字符时,建议弹窗中会出现对应中文补全项。
+
+下面选择百度搜索,以 [JavaScript例程](../供测试/js/) 为例:
+
+输入“jiafa”,在“加法”方法之外,还有几项拼音相关中文,种类为“词语”,如“假发”。
+
+如果访问 API 受阻,会提示用户。
+
+### 中英文混合
+
+支持中英文混合的标识符补全,在[此源码](../供测试/中英混合.js) 中输入“gettouru”出现“get投入产出比By客户组”
+
+### 多音字
+
+配置项中可以开启多音字。之后在[这里](../供测试/js/index.js) 输入“duozhong”或者“duochong”都会出现“多重笛卡尔积”
+
+### 代码片段
+
+插件中集成了几个编程语言的[代码片段](../片段)。可以通过中、英、拼音等方式触发补全。比如在 JS 源码中输入“array”、“chuxian”或“出”都能触发“出现次数”代码片段。
diff --git "a/\346\226\207\346\241\243/\345\267\262\347\237\245\351\227\256\351\242\230.md" "b/\346\226\207\346\241\243/\345\267\262\347\237\245\351\227\256\351\242\230.md"
new file mode 100644
index 0000000000000000000000000000000000000000..aae26568a2112d869ed27b280577c22e15c34f92
--- /dev/null
+++ "b/\346\226\207\346\241\243/\345\267\262\347\237\245\351\227\256\351\242\230.md"
@@ -0,0 +1,30 @@
+
+## JavaScript
+
+当中文输入状态时,补全项中有时会同时存在带拼音项与不带拼音项,尤其是输入比较慢时更明显。比如输入“中”的过程中,vsc 会在每个字符输入时返回建议(如下)。也许由于每次返回的延时,最后的补全项会有不同。
+```
+"输入词" "z"
+日志.js:3
+"返回对象" ["中文变量\tZhongWenBianLiang","加法\tJiaFa","小类\tXiaoLei","零蛋\tLingDan","使用\tShiYong","语法需要\tYuFaXuYao","或者\tHuoZhe","输入\tShuRu"]
+日志.js:3
+"================"
+日志.js:3
+"输入词" "zhon"
+日志.js:3
+"返回对象" ["中文变量\tZhongWenBianLiang","加法\tJiaFa","小类\tXiaoLei","零蛋\tLingDan","使用\tShiYong","语法需要\tYuFaXuYao","或者\tHuoZhe","输入\tShuRu"]
+日志.js:3
+"================"
+日志.js:3
+"输入词" "zhong"
+日志.js:3
+"返回对象" ["中文变量\tZhongWenBianLiang","加法\tJiaFa","小类\tXiaoLei","零蛋\tLingDan","使用\tShiYong","语法需要\tYuFaXuYao","或者\tHuoZhe","输入\tShuRu"]
+日志.js:3
+"================"
+日志.js:3
+"输入词" "中"
+日志.js:3
+"返回对象" ["中文变量\tZhongWenBianLiang","加法\tJiaFa","小类\tXiaoLei","零蛋\tLingDan","中文\tZhongWen","另一个中文\tLingYiGeZhongWen","使用\tShiYong","语法需要\tYuFaXuYao","或者\tHuoZhe","输入\tShuRu"]
+```
+## 代码片段
+
+输入某些中文,比如 JS 的“出现”时,需要 ctrl+space 触发补全,而且会出现两个同名选项。此时只有选择第一项才有实际代码内容。
diff --git "a/\345\274\200\345\217\221\350\257\264\346\230\216.md" "b/\346\226\207\346\241\243/\345\274\200\345\217\221\350\257\264\346\230\216.md"
similarity index 100%
rename from "\345\274\200\345\217\221\350\257\264\346\230\216.md"
rename to "\346\226\207\346\241\243/\345\274\200\345\217\221\350\257\264\346\230\216.md"
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 fa932438dffba16595c1187a19183242a0744b47..32f18d7baa4055c5b5682868f266c1d47d3f4a50 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,44 +1,12 @@
-const vscode = require('vscode')
-const bopomofo = require('./bopomofo')
-const 五笔 = require('./五笔输入法')
-const 谷歌输入法 = require('./lib/谷歌输入法API')
-const 百度搜索联想 = require('./lib/百度搜索联想')
-var pinyin = require("pinyin")
-var 字符串扩展 = require("./lib/字符串扩展")
-var { 多重笛卡尔积 } = require("./lib/数组扩展")
+var vscode = require('vscode')
var R = require('ramda')
+var { log } = require('./lib/日志')
+var { 包含中文, 查找词组, 是纯字母 } = require('./lib/字符串扩展')
+var { 数组去重 } = require('./lib/数组扩展')
+var 获得中文字符表示 = require('./lib/获得中文字符表示')
+var 谷歌输入法API = require('./lib/谷歌输入法API')
+var 百度搜索联想 = require('./lib/百度搜索联想')
-function 包含中文(str) {
- return /.*[\u4e00-\u9fa5]+.*$/.test(str)
-}
-var 数组去重 = 数组 => Array.from(new Set(数组))
-function 查找词组(s) {
- var wordPattern = /(-?\d*\.\d\w*)|([^\`\~\!\@\^\&\*\(\)\-\#\?\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s?。,、;:?…—·ˉˇ¨“”~〃|《》〔〕(),]+)/g;
- return 数组去重(s.match(wordPattern))
-}
-function 获得文档内容(document, position) {
- var 总行数 = document.lineCount
- var 当前行 = position.line
- var 文档内容 = ""
- for (var i = 0; i < 总行数; i++) {
- if (i != 当前行)
- 文档内容 += document.lineAt(i).text + "\n";
- }
- return 文档内容
-}
-function 获得拼音(提示方式, 文本) {
- var 拼音 = null
- if (提示方式.indexOf("五笔") != -1) {
- 拼音 = [五笔.五笔(文本, 提示方式)]
- } else {
- var 使用多音字 = vscode.workspace.getConfiguration('ChineseInputAssistant').get("InputMethod_polyphone")
- 拼音 = pinyin(文本, { heteronym: 使用多音字 == 'yes', style: pinyin.STYLE_NORMAL })
- 拼音 = 拼音.map(a => a.map(a => 字符串扩展.转换为大写(a[0]) + a.substring(1)))
- 拼音 = 多重笛卡尔积(拼音).map(a => a.join(''))
- if (提示方式 != "全拼") 拼音 = 拼音.map(a => bopomofo.双拼转换(a, 提示方式))
- }
- return 拼音
-}
function 获得当前输入词() {
// 我们需要的是文本被编辑后的情况 而不是编辑前的情况
// 在某些地方调用 会意外的 获得文本被编辑前的情况
@@ -61,97 +29,86 @@ function 获得当前输入词() {
})
}
-var 上次的补全词 = []
-var provideCompletionItems_上次调用输入词 = undefined
+// vscode.executeCompletionItemProvider 会调用 provideCompletionItems 导致无限递归
+// 因为 js 是单线程模型 所以做了一个简单的锁 应该不会有问题
+var 防递归锁 = false
async function provideCompletionItems(document, position, token, context) {
- var 当前文件类型 = R.last(document.fileName.split('.'))
-
- var 当前输入词 = await 获得当前输入词()
- // console.log('当前输入词', 当前输入词)
-
- // 防止无限递归
- if (当前输入词 == provideCompletionItems_上次调用输入词) {
- // console.log('重复调用')
- return []
- }
- provideCompletionItems_上次调用输入词 = 当前输入词
-
- // 获得配置项
- var 使用输入法 = vscode.workspace.getConfiguration('ChineseInputAssistant').get("InputMethod")
- var 提示方式 = vscode.workspace.getConfiguration('中文代码快速补全').get("提示方式")
-
- var 提示文本们 = []
-
- // 获得系统解析出的关键字
- // vscode.executeCompletionItemProvider 会调用provideCompletionItems 所以要防止无限递归
- var 系统解析出的关键字 = await vscode.commands.executeCommand('vscode.executeCompletionItemProvider', document.uri, position)
- 提示文本们 = 提示文本们.concat(系统解析出的关键字.items)
-
- // 对 c/cpp 的特殊处理
- if (当前文件类型 == 'c' || 当前文件类型 == 'cpp') {
- // 加入上次的补全词
- 上次的补全词 = 上次的补全词.map(a => a.label).filter(a => a.indexOf('\t') != -1).map(a => a.split('\t')[0])
- 提示文本们 = 提示文本们.concat(上次的补全词.filter(a => !提示文本们.map(b => b.label).includes(a)).map(a => ({
- label: a,
- kind: vscode.CompletionItemKind.Text,
- })))
-
- // 获得当前文档的所有中文 加入候选项
- var 中文词组 = R.compose(R.filter(包含中文), 查找词组)(获得文档内容(document, position))
- 提示文本们 = 提示文本们.concat(中文词组.filter(a => !提示文本们.map(b => b.label).includes(a)).map(a => ({
- label: a,
- kind: vscode.CompletionItemKind.Text,
- })))
- }
-
- // 获得输入法提供的关键字
- if (使用输入法 != 'no') {
- var func
-
- if (使用输入法 == 'Google Pinyin')
- func = 谷歌输入法
- else if (使用输入法 == 'Baidu Sugrec')
- func = 百度搜索联想
-
- var 输入法结果 = await func(当前输入词)(5).catch(e => {
- console.error('调用输入法api失败:' + e.toString())
- 输入法结果 = []
- })
- 提示文本们 = 提示文本们.concat(输入法结果.map(a => ({
- label: a,
- kind: vscode.CompletionItemKind.Text,
- })))
- }
-
- // 将带中文的标签加入拼音返回
- // 不带中文的不需要包括在返回结果里
- // 这个函数只需要返回新增的提示 不需要返回原有的提示
- var 返回对象 = 提示文本们.map(补全对象 => {
- var 文本 = 补全对象.label
- if (包含中文(文本)) {
- return 获得拼音(提示方式, 文本).map(拼音 => {
- var r = new vscode.CompletionItem(文本)
- r.label = `${文本}\t${拼音}`
- r.kind = 补全对象.kind
- r.insertText = 补全对象.insertText || 文本
- return r
+ var 输入词 = await 获得当前输入词() || ''
+
+ if (防递归锁) return []
+ 防递归锁 = true
+
+ log('================')
+ log('输入词', 输入词)
+
+ // var 文件后缀名 = R.last(document.fileName.split('.'))
+ // log('当前文件后缀名', 文件后缀名)
+
+ var 用户配置 = {}
+ 用户配置.使用输入法 = vscode.workspace.getConfiguration('ChineseInputAssistant').get("InputMethod")
+ 用户配置.使用多音字 = vscode.workspace.getConfiguration('ChineseInputAssistant').get("InputMethod_polyphone")
+ 用户配置.提示方式 = vscode.workspace.getConfiguration('中文代码快速补全').get("提示方式")
+ // log('用户配置', 用户配置)
+
+ var 返回对象 = []
+
+ 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 文档符号 = 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('')
+ var 输入法提供的词 = []
+ var 输入法 = null
+ if (用户配置.使用输入法 == 'Google Pinyin' && 纯字母输入词 != '' && 纯字母输入词 != null) {
+ 输入法 = 谷歌输入法API
+ } else if (用户配置.使用输入法 == 'Baidu Sugrec' && 纯字母输入词 != '' && 纯字母输入词 != null) {
+ 输入法 = 百度搜索联想
+ }
+ if (输入法 != null) {
+ 输入法提供的词 = await 输入法(纯字母输入词).catch(e => {
+ console.error(e)
+ vscode.window.showInformationMessage(`调用输入法接口出错:` + e)
})
+ 输入法提供的词 = 输入法提供的词.map(a => 前缀 + a).map(a => new vscode.CompletionItem(a, vscode.CompletionItemKind.Text))
+ 返回对象 = 返回对象.concat(输入法提供的词)
}
+ }
- // cpp 插件很奇怪 必须要原样返回
- if (当前文件类型 == 'c' || 当前文件类型 == 'cpp')
- return [补全对象]
-
- return []
- }).flat()
+ 返回对象 = 数组去重((a, b) => a.label == b.label, 返回对象)
+ 返回对象 = 返回对象.filter(a => 包含中文(a.label)).filter(a => a.label != 输入词)
+ 返回对象 = 返回对象.map(a => R.set(R.lensProp('insertText'), a.label, a))
- // 对 c/cpp 的特殊处理
- if (当前文件类型 == 'c' || 当前文件类型 == 'cpp') {
- 上次的补全词 = 返回对象
- }
+ 返回对象 = 返回对象.map(a => R.set(R.lensProp('label'), `${a.label}\t${获得中文字符表示({
+ 表示方法: 用户配置.提示方式,
+ 文本: a.label,
+ 选项: { 使用多音字: 用户配置.使用多音字 }
+ })}`, a))
- // console.log(返回对象.map(a => a.label).join(','))
- return 返回对象
+ log('返回对象', 返回对象.map(a => a.label))
+ return new vscode.CompletionList(返回对象, true)
}
function resolveCompletionItem(item, token) {
@@ -159,10 +116,11 @@ function resolveCompletionItem(item, token) {
}
module.exports = function (context) {
- // 注册触发补全功能时调用的函数
- context.subscriptions.push(vscode.languages.registerCompletionItemProvider({ scheme: 'file', language: '*' }, {
+ context.subscriptions.push(vscode.languages.registerCompletionItemProvider({
+ scheme: 'file',
+ language: '*'
+ }, {
provideCompletionItems,
resolveCompletionItem
- }, '.', '$', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'))
+ }, '.', '$'))
}
-