1
0
Code Issues Pull Requests Packages Projects Releases Wiki Activity GitHub Gitee

36 Commits
2.0.0 ... 2.2.0

Author SHA1 Message Date
9e2d82ad89 Merge branch 'main' into release 2025-12-05 15:03:45 +08:00
26b2aa344c chore: 版本号更新为 2.2.0 2025-12-05 15:02:31 +08:00
1995529b99 Merge branch 'feature-format-order' 2025-12-05 15:01:21 +08:00
c45061e753 docs: 更新 CHANGELOG.md 2025-12-05 15:00:57 +08:00
2ef3afa29a docs: 更新 README.md 2025-12-05 14:53:09 +08:00
8df92b146f feat: 优化配置项文字表述 2025-12-05 14:44:24 +08:00
4aaa8c8569 chore: showConvertCaseOrderDialog 改为 showConvertCaseDetailDialog 2025-12-05 14:11:05 +08:00
06c842249b feat: 弹窗提示内容优化 2025-12-05 14:05:52 +08:00
4a827f6888 chore: 升级插件依赖版本 2025-12-05 11:55:47 +08:00
4ff696e4bd style: 项目代码按照 .editorconfig 格式化 2025-12-05 11:54:16 +08:00
9b443da441 fix: 配置项 variable-conversion.formatOrder 在转换时不生效问题 2025-12-05 11:51:50 +08:00
d04b03a1dc docs: 更新 README.md 和 CHANGELOG.md 2025-12-05 11:22:23 +08:00
dca8fc8758 feat: 支持从弹窗中点击按钮快捷跳转至设置页对应配置项 2025-12-05 11:17:36 +08:00
dd757e586e feat: 顺序信息弹窗支持展示配置重复项和无效项 2025-12-05 11:08:40 +08:00
2d84be6976 feat: 支持展示当前配置的格式顺序信息弹窗 2025-12-05 11:06:33 +08:00
d83481c6a4 更新 CHANGELOG.md 2025-12-05 10:21:07 +08:00
885f208c80 chore: 完善部分函数注释 2025-12-05 10:01:38 +08:00
87da87d000 feat: 新增 formatOrder 配置项;支持根据 formatOrder 对格式进行排序 2025-12-05 09:59:06 +08:00
e4240b2c5d fix: 修正一处单词拼写错误 2025-12-05 09:50:46 +08:00
05a55c1bdb fix: 修复 README 及代码中的拼写错误 2025-12-05 09:48:05 +08:00
0849fa40f5 升级插件依赖版本 2025-11-22 11:38:19 +08:00
3189ee9a8a chore: package-lock.json 文件变更 2025-11-21 23:02:51 +08:00
c6a2f418e6 Code Spell Checker 插件拼写检查白名单单词 2025-07-14 14:45:00 +08:00
0d2d89329e 修复一处单词拼写错误 2025-07-14 14:41:37 +08:00
6b9ce052e9 调试时禁用其他扩展 2025-07-14 14:39:04 +08:00
bad03a6074 Merge branch 'main' into release 2025-07-14 14:32:45 +08:00
076553967c 版本号更新为 2.1.0;更新 CHANGELOG.md 2025-07-14 14:26:18 +08:00
33d743afc7 Merge branch 'feature-enabled-formats-config' 2025-07-14 14:14:24 +08:00
8f8ae89be5 更新 README.md 2025-07-12 04:38:17 +08:00
c50dfe4f70 获取 disableFormat 配置项改为获取 enabledFormats 配置项 2025-07-12 04:34:24 +08:00
3ff4c068f2 新增 variable-conversion.enabledFormats 配置选项;variable-conversion.disableFormat 标记为弃用 2025-07-12 04:02:18 +08:00
c930475fac Merge branch 'main' into release 2025-07-12 01:44:37 +08:00
5d5bccbf6f 添加 .editorconfig;空格缩进规范化 2025-07-12 01:44:06 +08:00
5290684660 版本号更新为 2.0.1;更新 CHANGELOG.md 2025-07-12 01:28:37 +08:00
2ed3b1c8a0 升级插件依赖版本;调整 eslint 配置 2025-07-12 01:24:02 +08:00
29d892f666 空格&缩进相关小改动 2025-07-12 01:10:13 +08:00
29 changed files with 2078 additions and 1035 deletions

26
.editorconfig Normal file
View File

@@ -0,0 +1,26 @@
# EditorConfig is awesome: https://editorconfig.org
# top-most EditorConfig file
root = true
[*]
end_of_line = lf
# Unix-style newlines with a newline ending every file
insert_final_newline = true
# Set default charset
charset = utf-8
[*.{js,ts}]
# 4 space indentation
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[.vscode/**.json]
indent_style = tab
# 历史原因需要保留 tab 缩进的代码文件
[src/{test/extension.test.ts,extension.ts}]
indent_style = tab

View File

@@ -1,30 +0,0 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "import",
"format": [ "camelCase", "PascalCase" ]
}
],
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off"
},
"ignorePatterns": [
"out",
"dist",
"**/*.d.ts"
]
}

2
.gitignore vendored
View File

@@ -4,4 +4,4 @@ node_modules
.vscode-test/
*.vsix
*.ignore
*.ignore

View File

@@ -3,6 +3,6 @@
// for the documentation about the extensions.json format
"recommendations": [
"dbaeumer.vscode-eslint",
"ms-vscode.extension-test-runner"
"ms-vscode.extension-test-runner"
]
}

3
.vscode/launch.json vendored
View File

@@ -10,7 +10,8 @@
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
"--extensionDevelopmentPath=${workspaceFolder}",
"--disable-extensions", // 调试时禁用其他扩展
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"

25
.vscode/settings.json vendored
View File

@@ -1,11 +1,18 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off",
// Code Spell Checker 插件
"cSpell.words": [
"coder-xiaomo",
"Gitee",
"unconfigured"
],
}

View File

@@ -5,7 +5,7 @@ src/**
.yarnrc
vsc-extension-quickstart.md
**/tsconfig.json
**/.eslintrc.json
**/eslint.config.mjs
**/*.map
**/*.ts
**/.vscode-test.*

View File

@@ -21,8 +21,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
### Internal
-->
## 2.2.0
### Added
- Add new configuration `variable-conversion.formatOrder` to customize the display order of variable naming conventions. (新增 `variable-conversion.formatOrder` 配置项,用于自定义变量命名方式的显示顺序)
- Add new command `variable-conversion.showConvertCaseDetailDialog` to display current format configuration. (新增 `variable-conversion.showConvertCaseDetailDialog` 命令,用于显示当前配置的格式信息)
- Add clickable link for the configuration description. (在配置项描述中添加了点击跳转超链接)
- Add shortcut key `Ctrl + Alt + \` to trigger format order info display dialog. (新增快捷键 `Ctrl + Alt + \` 用于触发显示格式顺序弹窗)
- Support displaying duplicate and invalid items in format information dialog. (支持在信息弹窗中显示配置的重复项和无效项)
- Add buttons in format information dialog for quick navigation to corresponding settings. (在格式弹窗中添加按钮,支持快捷跳转至设置页对应配置项)
### Improved
- Improve cyclic conversion to follow user-configured formatOrder. (改进了循环转换功能使其遵循用户配置的formatOrder顺序)
## 2.1.0
### Changed
- **[BREAKING!!!]** Deprecate `variable-conversion.disableFormat`, please use `variable-conversion.enabledFormats` instead. (移除 `variable-conversion.disableFormat` 配置项,请使用 `variable-conversion.enabledFormats`)
- Support enabling only partial target conversion formats. (支持仅开启部分目标转换格式)
## 2.0.1
### Internal
- Add `.editorconfig` file. (添加 `.editorconfig` 文件)
- Upgrade plugin dependency versions. (升级插件依赖版本)
- Modify eslint configuration. (调整 eslint 配置)
## 2.0.0
### Added
@@ -110,4 +142,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Adds an editor context menu with submenu
- Implement conversion to Camel Case, Pascal Case, Snake Case(Snake Camel, Snake Pascal, Snake Upper), Kebab Case(Kebab Camel, Kebab Pascal, Kebab Upper), Lower Case, Upper Case
- Add test cases
- Initial release
- Initial release

View File

@@ -3,16 +3,28 @@
[Marketplace](https://marketplace.visualstudio.com/items?itemName=coder-xiaomo.variable-conversion) [GitHub](https://github.com/coder-xiaomo/variable-conversion-vscode-extension.git) [Gitee](https://gitee.com/coder-xiaomo/variable-conversion-vscode-extension.git)
一个强大的变量命名及路径风格转换插件,支持一键转换、循环转换,支持右键菜单、快捷键、状态栏等多种方式使用。<br>
A powerful variable and path conversion extension. Supports one-key conversion & cyclic conversion. You can use it through the editer menu, shortcut keys and status bar.
A powerful variable and path conversion extension. Supports one-key conversion & cyclic conversion. You can use it through the editor menu, shortcut keys and status bar.
> 【近期更新】v2.0.0 版本 (2024-12-15)
> **【近期更新】**
>
> **v2.2.0 (2025-12-05)**
>
> - 支持配置目标转换格式顺序
> - 支持展示当前配置的格式顺序信息弹窗,可显示配置重复项和无效项
> - 支持从弹窗中点击按钮快捷跳转至设置页对应配置项
>
> **v2.1.0 (2025-07-14)**
>
> - 支持仅开启部分目标转换格式 (优化 VSCode 配置项)
>
> **v2.0.0 (2024-12-15)**
>
> - 支持 Windows / Unix 路径风格转换(可选中文本中的路径,然后使用 `Ctrl + Alt + /` 快捷键,或点击右键菜单、底部状态栏路径转换按钮轻松实现转换)
- ✅ 支持多选区 Support multi-selection
- ✅ 支持多窗口 Support subwindow
- ✅ 支持撤回 & 重做 Support undo & redo (Ctrl + Z / Ctrl + Y)
- ✅ 支持禁用部分目标转换格式 Supports disabling some target conversion formats
- ✅ 支持仅开启部分目标转换格式 Support enabling only partial target conversion formats
> 🔭 Tips for Chinese users: 如果您无法看到下文图片,请[点这里](https://gitee.com/coder-xiaomo/variable-conversion-vscode-extension/blob/main/README.md)查看
@@ -67,7 +79,7 @@ Or right-click on the selected text -> Convert string to...
![Path Conversion](image/path-conversion.gif)
**注:**目前 `v2.0.0` 版本暂仅支持 `Windows 风格路径` 与 `Unix 风格路径` 互转,所以这两个快捷键目前效果相同。**后续会陆续增加其他更多路径风格**(例如 `Windows Git Bash` 风格,浏览器 `file://` 协议风格等),敬请期待。
**注:** 目前 `v2.0.0` 版本暂仅支持 `Windows 风格路径``Unix 风格路径` 互转,所以这两个快捷键目前效果相同。**后续会陆续增加其他更多路径风格**(例如 `Windows Git Bash` 风格,浏览器 `file://` 协议风格等),敬请期待。
## 快捷键 Shortcut key
@@ -76,6 +88,7 @@ Or right-click on the selected text -> Convert string to...
| 变量转换 快速选择 Variable Conversion QuickPick | Shift + Alt + T |
| 变量循环转换→上一个 Variable Cyclic Conversion → Previous one | Ctrl + Alt + [ |
| 变量循环转换→下一个 Variable Cyclic Conversion → Next one | Ctrl + Alt + ] |
| 显示格式顺序信息弹窗 Show Format Order Info Dialog | Ctrl + Alt + \` |
| 路径转换 快速选择 Path Conversion QuickPick | Shift + Alt + / |
| 路径循环转换→上一个 Path Cyclic conversion → Previous one | Ctrl + Alt + / |
| 路径循环转换→下一个 Path Cyclic conversion → Next one | Ctrl + Shift + Alt + / |
@@ -84,9 +97,42 @@ Or right-click on the selected text -> Convert string to...
## 配置项 Configurations
| 配置项 Configuration Key | 描述 Description | 配置示例 | 默认值 |
| ----------------------------------- | ------------------------------------------------------------ | ------------------------------ | ------ |
| `variable-conversion.disableFormat` | 定义哪些格式是禁用的<br />Define which formats are disabled. | `["lower_case", "upper_case"]` | `[]` |
| 配置项 Configuration Key | 描述 Description | 配置示例 | 默认值 |
| --------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------- | -------- |
| `variable-conversion.enabledFormats` | 配置启用的变量命名方式<br />Configuration of Enabled Variable Naming Conventions. | `{ "xxxCase.enabled": boolean, ... }` | 见配置项 |
| `variable-conversion.formatOrder` | 配置变量命名方式的显示顺序<br />Configure the display order of variable naming conventions. | `[ "camel_case", "pascal_case", "snake_case" ]` | 见配置项 |
| `variable-conversion.disablePathFormat` | 定义哪些路径风格是禁用的<br />Define which path formats are disabled. | `["windows_style", "unix_style"]` | 见配置项 |
配置项如下:
<!--
GitHub 上这种表格高亮行会有问题(表头不会高亮)
| ![Enabled Formats](image/settings-enable-formats.png) | ![Format Order](image/settings-format-order.png) |
| :----------------------------------------------------------: | :----------------------------------------------: |
| **Enabled Formats 配置** | **Format Order 配置** |
| ![Disable Path Format](image/settings-disable-path-format.png) | |
| **Disable Path Format 配置** | |
-->
<table>
<tr>
<td align="center"><strong>Enabled Formats 配置</strong></td>
<td align="center"><strong>Format Order 配置</strong></td>
</tr>
<tr>
<td align="center"><img src="image/settings-enable-formats.png" alt="Enabled Formats"></td>
<td align="center"><img src="image/settings-format-order.png" alt="Format Order"></td>
</tr>
<tr>
<td align="center"><strong>Disable Path Format 配置</strong></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"><img src="image/settings-disable-path-format.png" alt="Disable Path Format"></td>
<td align="center"></td>
</tr>
</table>
## 支持的类型 Support Case
@@ -119,7 +165,7 @@ Or right-click on the selected text -> Convert string to...
现已支持的路径风格:
| 路径风格 | Sttyle | 举例 e.g. |
| 路径风格 | Style | 举例 e.g. |
| ------------ | ------------- | ---------------------------------------------- |
| Windows 风格 | Windows Style | `C:\Windows\System32` <br />`.\public\assets\` |
| Unix 风格 | Unix Style | `/usr/bin`<br />`./public/assets/` |

28
eslint.config.mjs Normal file
View File

@@ -0,0 +1,28 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
export default [{
files: ["**/*.ts"],
}, {
plugins: {
"@typescript-eslint": typescriptEslint,
},
languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: "module",
},
rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],
curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}];

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

2267
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
{
"name": "variable-conversion",
"displayName": "Variable Conversion",
"description": "一个强大的变量名转换插件,支持右键菜单、快捷键、状态栏等多种方式使用,支持小驼峰、大驼峰(帕斯卡)、下划线(蛇形)、中划线(连字符/脊柱式)、空格分隔、点分隔、全小写、全大写等常用命名方式(及组合)转换。 \nA powerful variable naming conversion extension. You can use it through the editer menu, shortcut keys and bottom bar. Support camel, pascal, snake, kebab(spinal), space, dot, lower, upper case, and more.",
"version": "2.0.0",
"description": "一个强大的变量名转换插件,支持右键菜单、快捷键、状态栏等多种方式使用,支持小驼峰、大驼峰(帕斯卡)、下划线(蛇形)、中划线(连字符/脊柱式)、空格分隔、点分隔、全小写、全大写等常用命名方式(及组合)转换。 \nA powerful variable naming conversion extension. You can use it through the editor menu, shortcut keys and bottom bar. Support camel, pascal, snake, kebab(spinal), space, dot, lower, upper case, and more.",
"version": "2.2.0",
"icon": "image/logo.png",
"publisher": "coder-xiaomo",
"engines": {
"vscode": "^1.87.0"
"vscode": "^1.102.0"
},
"categories": [
"Other"
@@ -53,6 +53,10 @@
},
"when": "editorTextFocus"
},
{
"command": "variable-conversion.showConvertCaseDetailDialog",
"key": "ctrl+alt+\\"
},
{
"command": "variable-conversion.convertPath",
"key": "shift+alt+/",
@@ -324,9 +328,194 @@
"configuration": {
"title": "Variable Conversion 变量转换",
"properties": {
"variable-conversion.enabledFormats": {
"type": "object",
"description": "Tags and options configured here will be used by the Add Tags command to add tags to struct fields. If promptForTags is true, then user will be prompted for tags and options. By default, json tags are added.",
"markdownDescription": "配置启用的变量命名方式\n\nConfiguration of Enabled Variable Naming Conventions.\n\n[配置转换顺序](command:workbench.action.openSettings?%5B%22variable-conversion.formatOrder%22%5D)&nbsp;&nbsp;&nbsp;&nbsp;[查看当前配置(对话框)](command:variable-conversion.showConvertCaseDetailDialog)&nbsp;&nbsp;&nbsp;&nbsp;[在 settings.json 中编辑 (Edit in settings.json)](command:workbench.action.openSettingsJson)\n\n&nbsp;\n\n🌰 e.g. *Mike like eat ice-cream*\n\n对于这个句子不同命名方式示例如下\n\nFor this sentence, different naming conventions are as follows:",
"scope": "window",
"properties": {
"lowerCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全小写命名] lower case (全小写)\n 🌰e.g. mike like eat ice-cream"
},
"snakeCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全小写命名] snake case (下划线)\n 🌰e.g. mike_like_eat_ice_cream"
},
"kebabCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全小写命名] kebab case (连字符)\n 🌰e.g. mike-like-eat-ice-cream"
},
"spaceCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全小写命名] space case (空格)\n 🌰e.g. mike like eat ice cream"
},
"dotCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全小写命名] dot case (点)\n 🌰e.g. mike.like.eat.ice.cream"
},
"upperCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全大写命名] upper case (全大写)\n 🌰e.g. MIKE LIKE EAT ICE-CREAM"
},
"snakeUpperCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全大写命名] snake upper case (下划线)\n 🌰e.g. MIKE_LIKE_EAT_ICE_CREAM"
},
"kebabUpperCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全大写命名] kebab upper case (连字符)\n 🌰e.g. MIKE-LIKE-EAT-ICE-CREAM"
},
"spaceUpperCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全大写命名] space upper case (空格)\n 🌰e.g. MIKE LIKE EAT ICE CREAM"
},
"dotUpperCase.enabled": {
"type": "boolean",
"default": false,
"description": "[全大写命名] dot upper case (点)\n 🌰e.g. MIKE.LIKE.EAT.ICE.CREAM"
},
"pascalCase.enabled": {
"type": "boolean",
"default": false,
"description": "[大驼峰命名] pascal case (大驼峰)\n 🌰e.g. MikeLikeEatIceCream"
},
"snakePascalCase.enabled": {
"type": "boolean",
"default": false,
"description": "[大驼峰命名] snake pascal case (下划线)\n 🌰e.g. Mike_Like_Eat_Ice_Cream"
},
"kebabPascalCase.enabled": {
"type": "boolean",
"default": false,
"description": "[大驼峰命名] kebab pascal case (连字符)\n 🌰e.g. Mike-Like-Eat-Ice-Cream"
},
"spacePascalCase.enabled": {
"type": "boolean",
"default": false,
"description": "[大驼峰命名] space pascal case (空格)\n 🌰e.g. Mike Like Eat Ice Cream"
},
"dotPascalCase.enabled": {
"type": "boolean",
"default": false,
"description": "[大驼峰命名] dot pascal case (点)\n 🌰e.g. Mike.Like.Eat.Ice.Cream"
},
"camelCase.enabled": {
"type": "boolean",
"default": false,
"description": "[小驼峰命名] camel case (小驼峰)\n 🌰e.g. mikeLikeEatIceCream"
},
"snakeCamelCase.enabled": {
"type": "boolean",
"default": false,
"description": "[小驼峰命名] snake camel case (下划线)\n 🌰e.g. mike_Like_Eat_Ice_Cream"
},
"kebabCamelCase.enabled": {
"type": "boolean",
"default": false,
"description": "[小驼峰命名] kebab camel case (连字符)\n 🌰e.g. mike-Like-Eat-Ice-Cream"
},
"spaceCamelCase.enabled": {
"type": "boolean",
"default": false,
"description": "[小驼峰命名] space camel case (空格)\n 🌰e.g. mike Like Eat Ice Cream"
},
"dotCamelCase.enabled": {
"type": "boolean",
"default": false,
"description": "[小驼峰命名] dot camel case (点)\n 🌰e.g. mike.Like.Eat.Ice.Cream"
}
},
"additionalProperties": false,
"default": {
"lowerCase.enabled": true,
"snakeCase.enabled": true,
"kebabCase.enabled": true,
"spaceCase.enabled": true,
"dotCase.enabled": false,
"upperCase.enabled": true,
"snakeUpperCase.enabled": true,
"kebabUpperCase.enabled": false,
"spaceUpperCase.enabled": true,
"dotUpperCase.enabled": false,
"pascalCase.enabled": true,
"snakePascalCase.enabled": false,
"kebabPascalCase.enabled": false,
"spacePascalCase.enabled": false,
"dotPascalCase.enabled": false,
"camelCase.enabled": true,
"snakeCamelCase.enabled": false,
"kebabCamelCase.enabled": false,
"spaceCamelCase.enabled": false,
"dotCamelCase.enabled": false
}
},
"variable-conversion.formatOrder": {
"type": "array",
"markdownDescription": "配置变量命名方式的显示顺序\n\nConfigure the display order of variable naming conventions.\n\n如果某个格式在 enabledFormats 中被禁用,则即使在 formatOrder 中配置也不会显示。\n\nIf a format is disabled in enabledFormats, it will not be displayed even if configured in formatOrder.\n\n如您通过 [settings.json](command:workbench.action.openSettingsJson) 进行配置,请确保该配置中的格式名称与 enabledFormats 中的保持一致。\n\nWhen configuring via [settings.json](command:workbench.action.openSettingsJson), please ensure that the format names in this configuration match those in enabledFormats.\n\n🌰 e.g. `[\"camel_case\", \"snake_case\", \"pascal_case\"]`\n\n[配置启用的变量命名方式](command:workbench.action.openSettings?%5B%22variable-conversion.enabledFormats%22%5D)&nbsp;&nbsp;&nbsp;&nbsp;[查看当前配置(对话框)](command:variable-conversion.showConvertCaseDetailDialog)&nbsp;&nbsp;&nbsp;&nbsp;[在 settings.json 中编辑 (Edit in settings.json)](command:workbench.action.openSettingsJson)",
"scope": "window",
"items": {
"type": "string",
"enum": [
"camel_case",
"pascal_case",
"snake_case",
"snake_camel_case",
"snake_pascal_case",
"snake_upper_case",
"kebab_case",
"kebab_camel_case",
"kebab_pascal_case",
"kebab_upper_case",
"space_case",
"space_camel_case",
"space_pascal_case",
"space_upper_case",
"dot_case",
"dot_camel_case",
"dot_pascal_case",
"dot_upper_case",
"lower_case",
"upper_case"
],
"enumDescriptions": [
"驼峰命名 (camel_case)",
"大驼峰命名 (pascal_case)",
"下划线命名 (snake_case)",
"下划线驼峰命名 (snake_camel_case)",
"下划线大驼峰命名 (snake_pascal_case)",
"下划线大写命名 (snake_upper_case)",
"连字符命名 (kebab_case)",
"连字符驼峰命名 (kebab_camel_case)",
"连字符大驼峰命名 (kebab_pascal_case)",
"连字符大写命名 (kebab_upper_case)",
"空格命名 (space_case)",
"空格驼峰命名 (space_camel_case)",
"空格大驼峰命名 (space_pascal_case)",
"空格大写命名 (space_upper_case)",
"点命名 (dot_case)",
"点驼峰命名 (dot_camel_case)",
"点大驼峰命名 (dot_pascal_case)",
"点大写命名 (dot_upper_case)",
"全小写命名 (lower_case)",
"全大写命名 (upper_case)"
]
},
"default": []
},
"variable-conversion.disableFormat": {
"order": 1,
"markdownDescription": "定义哪些变量命名方式是禁用的\n\nDefine which variable formats are disabled.\n\n若您感觉以下配置比较麻烦也可以选择在 `settings.json` 中编辑:\n\nIf you find the following configuration troublesome, you can also edit this configuration item in `settings.json`:\n\n`\"variable-conversion.disableFormat\": [ ... ],`\n\n[在 settings.json 中编辑 (Edit in settings.json)](command:workbench.action.openSettingsJson)\n\n配置后您可能需要*重启扩展宿主*,或*重启当前窗口*才可使该配置完全生效(二选一即可):\n\nYou may need to *restart extension host* or *reload window* after configuration to take full effect (either):\n\n[重启扩展宿主 (Restart Extension Host)](command:workbench.action.restartExtensionHost), [重启当前窗口 (Reload Window)](command:workbench.action.reloadWindow)",
"markdownDeprecationMessage": "**Deprecated**: Please use `#variable-conversion.enabledFormats#` instead.\n\n**已弃用**,请使用 `#variable-conversion.enabledFormats#`。",
"type": "array",
"items": {
"type": "string",
@@ -402,20 +591,20 @@
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"lint": "eslint src",
"test": "vscode-test",
"package": "echo \"start `vsce package`\" & vsce package",
"package": "vsce package",
"publish": "vsce publish"
},
"devDependencies": {
"@types/mocha": "^10.0.6",
"@types/node": "18.x",
"@types/vscode": "^1.87.0",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"@vscode/test-cli": "^0.0.8",
"@vscode/test-electron": "^2.3.9",
"eslint": "^8.57.0",
"typescript": "^5.3.3"
"@types/mocha": "^10.0.10",
"@types/node": "20.x",
"@types/vscode": "^1.102.0",
"@typescript-eslint/eslint-plugin": "^8.31.1",
"@typescript-eslint/parser": "^8.31.1",
"@vscode/test-cli": "^0.0.11",
"@vscode/test-electron": "^2.5.2",
"eslint": "^9.25.1",
"typescript": "^5.8.3"
}
}
}

View File

@@ -12,20 +12,20 @@ const DOUBLE_RIGHT_SLASH = '\\\\';
export function pathConversion(targetPathType: SupportPathFormat, input: string, eol: EOL, cutText: Array<TransformTextResult> | undefined = undefined): string {
let resultPath;
let isSeperator = false;
let isSeparator = false;
switch (targetPathType) {
case SupportPathFormat.Windows:
// 将其中的 / 替换为 \
resultPath = Array.from(input).map((char: string) => {
if (char !== LEFT_SLASH) {
// 当前字符不是 /
isSeperator = false;
isSeparator = false;
return char;
} else {
// 当前字符是 /
if (!isSeperator) {
if (!isSeparator) {
// 上一字符不是 /
isSeperator = true;
isSeparator = true;
return RIGHT_SLASH; // 替换成 \
}
// 上一字符是 /
@@ -38,13 +38,13 @@ export function pathConversion(targetPathType: SupportPathFormat, input: string,
resultPath = Array.from(input).map((char: string) => {
if (char !== RIGHT_SLASH) {
// 当前字符不是 \
isSeperator = false;
isSeparator = false;
return char;
} else {
// 当前字符是 \
if (!isSeperator) {
if (!isSeparator) {
// 上一字符不是 \
isSeperator = true;
isSeparator = true;
return LEFT_SLASH; // 替换成 /
}
// 上一字符是 \

View File

@@ -25,6 +25,14 @@ const userSelection: UserSelection = {
lastConvertedSelectionsText: [],
};
/**
* 选中文本改变时触发
*
* @param selections
* @param textList
* @param eol
* @returns
*/
export function onUserSelectionUpdated(selections: readonly vscode.Selection[], textList: string[], eol: EOL): void {
userSelection.currentSelections = selections;
if (textList.length !== 0 && isStringArrayEqual(textList, userSelection.lastConvertedSelectionsText)) {
@@ -113,4 +121,4 @@ function replaceTextEditorSelectedText() {
});
userSelection.lastConvertedSelectionsText = textList;
}
}
}

View File

@@ -1,7 +1,7 @@
import { EOL } from '../../types/EOLType';
import { SupportVariableCase } from './types/SupportVariableCaseType';
import { TransformTextResult } from '../../types/TransformTextResultType';
import { transformMutliLineText, transformText } from '../../utils/transform';
import { transformMultiLineText } from '../../utils/transform';
/**
* 统一文本转换函数
@@ -52,7 +52,7 @@ export function caseConversion(targetCase: SupportVariableCase, str: string, eol
}
// Cut text 切割文本
const results: Array<TransformTextResult> = cutText === undefined ? transformMutliLineText(str) : cutText;
const results: Array<TransformTextResult> = cutText === undefined ? transformMultiLineText(str) : cutText;
// console.log('results', results);
const transformedLines: Array<string> = [];

View File

@@ -1,6 +1,6 @@
import * as vscode from 'vscode';
import { EOL } from "../../types/EOLType";
import { cyclicConvertCaseOrder } from "./types/SupportVariableCaseType";
import { cyclicConvertCaseOrder, settingsKeyToEnableSettingsKey } from "./types/SupportVariableCaseType";
import { caseConversion } from "./conversion";
import { isStringArrayEqual, stringListArrayDuplicateRemoval } from '../../utils/utils';
import { getUserConfigurations } from '../../utils/user-configuration';
@@ -25,6 +25,14 @@ const userSelection: UserSelection = {
lastConvertedSelectionsText: [],
};
/**
* 选中文本改变时触发
*
* @param selections
* @param textList
* @param eol
* @returns
*/
export function onUserSelectionUpdated(selections: readonly vscode.Selection[], textList: string[], eol: EOL): void {
userSelection.currentSelections = selections;
if (textList.length !== 0 && isStringArrayEqual(textList, userSelection.lastConvertedSelectionsText)) {
@@ -66,16 +74,25 @@ function lazyConvert() {
}
// 获取用户配置
const disableFormatList = getUserConfigurations<Array<string>>('disableFormat') || [];
const enabledFormats = getUserConfigurations<Record<string, boolean>>('enabledFormats') || {};
const formatOrder = getUserConfigurations<string[]>('formatOrder') || [];
const textList = userSelection.currentSelectionsText;
// vscode.window.showInformationMessage('lazyConvert' + textList.join('\n'));
const eol = userSelection.currentEol;
const conversionsTarget: Array<string[]> = [textList];
// 先收集所有启用的格式及其转换结果
// const conversionsTarget: Array<string[]> = [textList];
const formatMap = new Map<string, string[]>();
for (const cyclicConvertCase of cyclicConvertCaseOrder) {
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
// 跳过禁用的目标格式
if (disableFormatList.includes(cyclicConvertCase.settingsKey)) {
const enableSettingsKey = settingsKeyToEnableSettingsKey.get(cyclicConvertCase.settingsKey);
if (!enableSettingsKey) {
console.warn('Cannot find enableSettingsKey for settingsKey:', cyclicConvertCase.settingsKey);
continue;
}
if (enabledFormats[enableSettingsKey] !== true) {
continue;
}
@@ -86,11 +103,34 @@ function lazyConvert() {
const conversionResult: string = caseConversion(cyclicConvertCase.type, line, eol);
conversionsTargetItem.push(conversionResult);
}
conversionsTarget.push(conversionsTargetItem);
// conversionsTarget.push(conversionsTargetItem);
formatMap.set(cyclicConvertCase.settingsKey, conversionsTargetItem);
}
// 根据formatOrder对格式进行排序
const orderedConversions: Array<string[]> = [textList];
const processedSettingsKeys = new Set<string>();
// 先添加在formatOrder中配置的格式
for (const formatName of formatOrder) {
const conversions = formatMap.get(formatName);
if (conversions && !processedSettingsKeys.has(formatName)) {
orderedConversions.push(conversions);
processedSettingsKeys.add(formatName);
}
}
// 再添加未在formatOrder中配置但启用的格式保持原有顺序
for (const cyclicConvertCase of cyclicConvertCaseOrder) {
const settingsKey = cyclicConvertCase.settingsKey;
const conversions = formatMap.get(settingsKey);
if (conversions && !processedSettingsKeys.has(settingsKey)) {
orderedConversions.push(conversions);
processedSettingsKeys.add(settingsKey);
}
}
// 按数组去重
const noDuplicate = stringListArrayDuplicateRemoval(conversionsTarget);
// const noDuplicate = stringListArrayDuplicateRemoval(conversionsTarget);
const noDuplicate = stringListArrayDuplicateRemoval(orderedConversions);
// console.log('noDuplicate', noDuplicate);
userSelection.conversionsTarget = noDuplicate;
@@ -112,4 +152,4 @@ function replaceTextEditorSelectedText() {
});
userSelection.lastConvertedSelectionsText = textList;
}
}
}

View File

@@ -0,0 +1,141 @@
import * as vscode from 'vscode';
import { cyclicConvertCaseOrder, quickPickSupportCases, commands } from './types/SupportVariableCaseType';
import { getUserConfigurations } from '../../utils/user-configuration';
/**
* 显示当前配置的格式顺序信息
*/
export function showConvertCaseDetailDialog() {
// 获取用户配置的格式顺序
const formatOrder = getUserConfigurations<string[]>('formatOrder') || [];
// 获取启用的格式
const enabledFormats = getUserConfigurations<Record<string, boolean>>('enabledFormats') || {};
// 创建格式名称映射
const formatNameMap: Record<string, string> = {};
quickPickSupportCases.forEach(item => {
formatNameMap[item.settingsKey] = item.name;
});
// 获取所有有效的settingsKey
const validSettingsKeys = new Set(quickPickSupportCases.map(item => item.settingsKey));
// 检测重复项和无效项
const seenSettingsKeys = new Set<string>();
const duplicateSettingsKeys = new Set<string>();
const invalidSettingsKeys = new Set<string>();
formatOrder.forEach(format => {
if (!validSettingsKeys.has(format)) {
invalidSettingsKeys.add(format);
} else if (seenSettingsKeys.has(format)) {
duplicateSettingsKeys.add(format);
} else {
seenSettingsKeys.add(format);
}
});
// 创建settingsKey到enableSettingsKey的映射
const settingsKeyToEnableKeyMap: Record<string, string> = {};
commands.forEach(item => {
settingsKeyToEnableKeyMap[item.settingsKey] = item.enableSettingsKey;
});
// 构建显示内容
const message = [
'当前配置的变量命名格式顺序:\n\n',
];
// 先显示用户配置的顺序
if (formatOrder.length > 0) {
message.push('用户自定义顺序:\n');
formatOrder.forEach((format, index) => {
const enableKey = settingsKeyToEnableKeyMap[format];
const isEnabled = enableKey ? enabledFormats[enableKey] !== false : true;
const status = isEnabled ? '✔️' : '❌'; // ✅✔️☑️
// 添加重复和无效标记
let marker = '';
if (!validSettingsKeys.has(format)) {
marker = ' ❌ (无效格式)';
} else if (duplicateSettingsKeys.has(format)) {
marker = ' ⚠️ (重复配置)';
}
message.push(`${index + 1}. ${formatNameMap[format] || format} (${format}) ${marker || status}\n`);
});
} else {
message.push('未设置自定义顺序,使用默认顺序\n\n');
}
// 显示未配置但已启用的格式
const unconfiguredEnabledFormats = cyclicConvertCaseOrder
.filter(item => {
const enableKey = settingsKeyToEnableKeyMap[item.settingsKey];
const isEnabled = enableKey ? enabledFormats[enableKey] !== false : true;
return isEnabled && !formatOrder.includes(item.settingsKey);
})
.map(item => item.settingsKey);
if (unconfiguredEnabledFormats.length > 0) {
message.push('\n未配置但已启用的格式默认顺序\n');
unconfiguredEnabledFormats.forEach((format, index) => {
message.push(`${formatOrder.length + index + 1}. ${formatNameMap[format] || format} (${format}) ✔️\n`);
});
}
// 显示未启用的格式
const disabledFormats = cyclicConvertCaseOrder
.filter(item => {
const enableKey = settingsKeyToEnableKeyMap[item.settingsKey];
return enableKey ? enabledFormats[enableKey] === false : false;
})
.map(item => item.settingsKey);
if (disabledFormats.length > 0) {
message.push('\n未启用的格式\n');
disabledFormats.forEach(format => {
message.push(`- ${formatNameMap[format] || format} (${format}) ❌\n`);
});
}
// 警告信息
if (duplicateSettingsKeys.size > 0 || invalidSettingsKeys.size > 0) {
message.push('\n');
if (duplicateSettingsKeys.size > 0) {
message.push(`⚠️ 警告:发现重复配置的格式:${Array.from(duplicateSettingsKeys).join(', ')}\n`);
}
if (invalidSettingsKeys.size > 0) {
message.push(`❌ 错误:发现无效格式:${Array.from(invalidSettingsKeys).join(', ')}\n`);
}
}
message.push(
'\n',
'提示:\n',
'- 未启用的格式即使在顺序中配置也不会显示在转换选项中\n',
'- 重复和无效的格式配置可能会导致显示异常\n',
);
// 显示信息弹窗
vscode.window.showInformationMessage<vscode.MessageItem>(
'变量转换功能配置信息',
{ modal: true, detail: message.join('') },
// 弹窗按钮
{ title: '插件全部配置' },
{ title: '配置启用的命名方式' },
{ title: '配置转换顺序' },
).then(selection => {
if (selection) {
// 跳转到设置项
if (selection.title === '插件全部配置') {
vscode.commands.executeCommand('workbench.action.openSettings', 'variable-conversion');
} else if (selection.title === '配置启用的命名方式') {
vscode.commands.executeCommand('workbench.action.openSettings', 'variable-conversion.enabledFormats');
} else if (selection.title === '配置转换顺序') {
vscode.commands.executeCommand('workbench.action.openSettings', 'variable-conversion.formatOrder');
}
}
});
}

View File

@@ -278,117 +278,151 @@ const keyword = {
],
};
interface Command {
command: string;
targetCase: SupportVariableCase;
settingsKey: string;
// variable-conversion.enabledFormats 中的配置项
enableSettingsKey: string;
}
/**
* 接管的变量转换命令
*/
export const commands: Array<{ command: string; targetCase: SupportVariableCase; settingsKey: string }> = [
export const commands: Array<Command> = [
{
command: 'variable-conversion.toCamelCase',
targetCase: SupportVariableCase.CAMEL_CASE,
settingsKey: 'camel_case'
settingsKey: 'camel_case',
enableSettingsKey: 'camelCase.enabled',
},
{
command: 'variable-conversion.toPascalCase',
targetCase: SupportVariableCase.PASCAL_CASE,
settingsKey: 'pascal_case'
settingsKey: 'pascal_case',
enableSettingsKey: 'pascalCase.enabled',
},
// +++++++++++++++++++++++++++++++++++++++++++++++
{
command: 'variable-conversion.toSnakeCase',
targetCase: SupportVariableCase.SNAKE_CASE,
settingsKey: 'snake_case'
settingsKey: 'snake_case',
enableSettingsKey: 'snakeCase.enabled',
},
{
command: 'variable-conversion.toSnakeUpperCase',
targetCase: SupportVariableCase.SNAKE_UPPER_CASE,
settingsKey: 'snake_upper_case'
settingsKey: 'snake_upper_case',
enableSettingsKey: 'snakeUpperCase.enabled',
},
{
command: 'variable-conversion.toSnakePascalCase',
targetCase: SupportVariableCase.SNAKE_PASCAL_CASE,
settingsKey: 'snake_pascal_case'
settingsKey: 'snake_pascal_case',
enableSettingsKey: 'snakePascalCase.enabled',
},
{
command: 'variable-conversion.toSnakeCamelCase',
targetCase: SupportVariableCase.SNAKE_CAMEL_CASE,
settingsKey: 'snake_camel_case'
settingsKey: 'snake_camel_case',
enableSettingsKey: 'snakeCamelCase.enabled',
},
// +++++++++++++++++++++++++++++++++++++++++++++++
{
command: 'variable-conversion.toKebabCase',
targetCase: SupportVariableCase.KEBAB_CASE,
settingsKey: 'kebab_case'
settingsKey: 'kebab_case',
enableSettingsKey: 'kebabCase.enabled',
},
{
command: 'variable-conversion.toKebabUpperCase',
targetCase: SupportVariableCase.KEBAB_UPPER_CASE,
settingsKey: 'kebab_upper_case'
settingsKey: 'kebab_upper_case',
enableSettingsKey: 'kebabUpperCase.enabled',
},
{
command: 'variable-conversion.toKebabPascalCase',
targetCase: SupportVariableCase.KEBAB_PASCAL_CASE,
settingsKey: 'kebab_pascal_case'
settingsKey: 'kebab_pascal_case',
enableSettingsKey: 'kebabPascalCase.enabled',
},
{
command: 'variable-conversion.toKebabCamelCase',
targetCase: SupportVariableCase.KEBAB_CAMEL_CASE,
settingsKey: 'kebab_camel_case'
settingsKey: 'kebab_camel_case',
enableSettingsKey: 'kebabCamelCase.enabled',
},
// +++++++++++++++++++++++++++++++++++++++++++++++
{
command: 'variable-conversion.toSpaceCase',
targetCase: SupportVariableCase.SPACE_CASE,
settingsKey: 'space_case'
settingsKey: 'space_case',
enableSettingsKey: 'spaceCase.enabled',
},
{
command: 'variable-conversion.toSpaceUpperCase',
targetCase: SupportVariableCase.SPACE_UPPER_CASE,
settingsKey: 'space_upper_case'
settingsKey: 'space_upper_case',
enableSettingsKey: 'spaceUpperCase.enabled',
},
{
command: 'variable-conversion.toSpacePascalCase',
targetCase: SupportVariableCase.SPACE_PASCAL_CASE,
settingsKey: 'space_pascal_case'
settingsKey: 'space_pascal_case',
enableSettingsKey: 'spacePascalCase.enabled',
},
{
command: 'variable-conversion.toSpaceCamelCase',
targetCase: SupportVariableCase.SPACE_CAMEL_CASE,
settingsKey: 'space_camel_case'
settingsKey: 'space_camel_case',
enableSettingsKey: 'spaceCamelCase.enabled',
},
// +++++++++++++++++++++++++++++++++++++++++++++++
{
command: 'variable-conversion.toDotCase',
targetCase: SupportVariableCase.DOT_CASE,
settingsKey: 'dot_case'
settingsKey: 'dot_case',
enableSettingsKey: 'dotCase.enabled',
},
{
command: 'variable-conversion.toDotUpperCase',
targetCase: SupportVariableCase.DOT_UPPER_CASE,
settingsKey: 'dot_upper_case'
settingsKey: 'dot_upper_case',
enableSettingsKey: 'dotUpperCase.enabled',
},
{
command: 'variable-conversion.toDotPascalCase',
targetCase: SupportVariableCase.DOT_PASCAL_CASE,
settingsKey: 'dot_pascal_case'
settingsKey: 'dot_pascal_case',
enableSettingsKey: 'dotPascalCase.enabled',
},
{
command: 'variable-conversion.toDotCamelCase',
targetCase: SupportVariableCase.DOT_CAMEL_CASE,
settingsKey: 'dot_camel_case'
settingsKey: 'dot_camel_case',
enableSettingsKey: 'dotCamelCase.enabled',
},
// +++++++++++++++++++++++++++++++++++++++++++++++
{
command: 'variable-conversion.toLowerCase',
targetCase: SupportVariableCase.LOWER_CASE,
settingsKey: 'lower_case'
settingsKey: 'lower_case',
enableSettingsKey: 'lowerCase.enabled',
},
{
command: 'variable-conversion.toUpperCase',
targetCase: SupportVariableCase.UPPER_CASE,
settingsKey: 'upper_case'
settingsKey: 'upper_case',
enableSettingsKey: 'upperCase.enabled',
},
];
// settingsKey 到 enableSettingsKey 的映射
export const settingsKeyToEnableSettingsKey = new Map<string, string>();
commands.forEach(command => {
settingsKeyToEnableSettingsKey.set(command.settingsKey, command.enableSettingsKey);
});
export interface QuickPickSupportCaseItem {
type: SupportVariableCase,
name: string,

View File

@@ -17,6 +17,7 @@ import handleEditorReplaceVariable from './handler/variable-convert/editor-subme
import { handleQuickPick as handleQuickPickVariable } from './handler/variable-convert/quick-pick-handler';
import { commands as variableCommands } from './core/variable-convert/types/SupportVariableCaseType';
import * as CyclicConversionVariable from './core/variable-convert/cyclic-conversion';
import { showConvertCaseDetailDialog } from './core/variable-convert/show-convert-case-order-dialog';
// Path Convert
import handleEditorReplacePath from './handler/path-convert/editor-submenu-handler';
@@ -25,7 +26,7 @@ import { commands as pathCommands } from './core/path-convert/types/SupportPathF
import * as CyclicConversionPath from './core/path-convert/cyclic-conversion';
// Common
import { createStatusBarItem, updateStatusBarItemVisable } from './handler/status-bar-handler';
import { createStatusBarItem, updateStatusBarItemVisible } from './handler/status-bar-handler';
import { EOL } from './types/EOLType';
import { getUserConfigurations } from './utils/user-configuration';
@@ -64,12 +65,12 @@ export function activate(context: vscode.ExtensionContext) {
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
// 获取用户配置
const disableFormatList = getUserConfigurations<Array<string>>('disableFormat') || [];
const enabledFormats = getUserConfigurations<Record<string, boolean>>('enabledFormats') || {};
const disablePathFormatList = getUserConfigurations<Array<string>>('disablePathFormat') || [];
// 更新右键菜单每一项是否展示
// 变量转换右键菜单visible 2024.07.29
for (const { settingsKey } of variableCommands) {
vscode.commands.executeCommand('setContext', '_isHideSubMenuItem_' + settingsKey, disableFormatList.includes(settingsKey));
for (const { settingsKey, enableSettingsKey } of variableCommands) {
vscode.commands.executeCommand('setContext', '_isHideSubMenuItem_' + settingsKey, enabledFormats[enableSettingsKey] === false);
}
// 路径转换右键菜单visible 2024.12.14
for (const { settingsKey } of pathCommands) {
@@ -77,7 +78,7 @@ export function activate(context: vscode.ExtensionContext) {
}
// 判断是否展示状态栏按钮
updateStatusBarItemVisable(selectTextLength);
updateStatusBarItemVisible(selectTextLength);
// 循环转换:记录当前选中内容,并且进行转换
let eol: EOL = textEditor.document.eol === vscode.EndOfLine.CRLF ? '\r\n' : '\n';
@@ -104,7 +105,7 @@ export function activate(context: vscode.ExtensionContext) {
onTextEditorSelectionChangeCallback(textEditor, selections);
} else { // 进入 else 的场景举例: 从[代码编辑器]切换到[设置页]
// 判断是否展示状态栏按钮
updateStatusBarItemVisable(selectTextLength);
updateStatusBarItemVisible(selectTextLength);
}
});
@@ -156,6 +157,10 @@ export function activate(context: vscode.ExtensionContext) {
});
context.subscriptions.push(loopConvertCaseNextDisposable);
// 注册显示格式顺序信息的命令
let showConvertCaseDetailDialogDisposable = vscode.commands.registerCommand('variable-conversion.showConvertCaseDetailDialog', showConvertCaseDetailDialog);
context.subscriptions.push(showConvertCaseDetailDialogDisposable);
/**
* 路径转换

View File

@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
import QuickPickItemEx from "../types/QuickPickItemExType";
import { QuickPickSupportCaseItem, quickPickSupportCases } from '../../core/path-convert/types/SupportPathFormatType';
import { TransformTextResult } from '../../types/TransformTextResultType';
import { transformMutliSelectionText } from '../../utils/transform';
import { transformMultiSelectionText } from '../../utils/transform';
import { EOL } from '../../types/EOLType';
import { pathConversion } from '../../core/path-convert/conversion';
import { isStringArrayEqual } from '../../utils/utils';
@@ -12,18 +12,22 @@ const QuickPickLabelMaxLength = 60;
interface RecommendItem {
conversionText: Array<string>
transforTo: string[]
transformTo: string[]
keyword: string[]
}
/**
* 弹出的提示
*
* @param textList
* @param eol
* @param enabledQuickPickSupportCases
* @returns
* @since 2024-12-14
*/
function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPickSupportCases: Array<QuickPickSupportCaseItem>): Array<QuickPickItemEx> {
// Cut text 切割文本
const resultsList: Array<TransformTextResult[]> = transformMutliSelectionText(textList);
const resultsList: Array<TransformTextResult[]> = transformMultiSelectionText(textList);
const mergeResultList: Array<RecommendItem> = [];
for (const quickPick of enabledQuickPickSupportCases) {
@@ -39,14 +43,14 @@ function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPi
if (recommendItem === undefined) {
let item: RecommendItem = {
conversionText: conversionResults,
transforTo: [quickPick.shortName], // quickPick.name
transformTo: [quickPick.shortName], // quickPick.name
keyword: quickPick.keyword,
};
mergeResultList.push(item);
continue;
}
recommendItem.transforTo.push(quickPick.shortName); // quickPick.name
recommendItem.transformTo.push(quickPick.shortName); // quickPick.name
recommendItem.keyword = Array.from(new Set(recommendItem.keyword.concat(quickPick.keyword))); // 关键词去重
}
@@ -62,7 +66,7 @@ function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPi
label: conversionTextForDisplay.length >= QuickPickLabelMaxLength
? (conversionTextForDisplay.substring(0, QuickPickLabelMaxLength - 3) + '...')
: conversionTextForDisplay,
description: `转换为 ${recommendItem.transforTo.join(' / ')}`,
description: `转换为 ${recommendItem.transformTo.join(' / ')}`,
detail: `关键词 ${recommendItem.keyword.join(' ')}`,
value: recommendItem.conversionText,
};

View File

@@ -10,7 +10,7 @@ let statusBarItemList: Array<vscode.StatusBarItem> = [];
* @since 2024-04-07
*/
export function createStatusBarItem() {
// 变量转换状态栏 2024.04.07
// 变量转换状态栏 2024.04.07
const createVariableConvertStatusBarItem = () => {
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
// Icon Listing docs: https://code.visualstudio.com/api/references/icons-in-labels#icon-listing
@@ -20,7 +20,7 @@ export function createStatusBarItem() {
// statusBarItem.show();
return statusBarItem;
};
// 路径转换状态栏 2024.12.14
// 路径转换状态栏 2024.12.14
const createPathConvertStatusBarItem = () => {
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
statusBarItem.text = '$(sync-ignored)路径转换'; // italic symbol-null
@@ -40,7 +40,7 @@ export function createStatusBarItem() {
*
* @since 2024-04-07
*/
export function updateStatusBarItemVisable(selectTextLength: number) {
export function updateStatusBarItemVisible(selectTextLength: number) {
let editor = vscode.window.activeTextEditor;
if (editor && selectTextLength > 0) {
statusBarItemList.forEach(statusBarItem => {
@@ -51,4 +51,4 @@ export function updateStatusBarItemVisable(selectTextLength: number) {
statusBarItemList.forEach(statusBarItem => {
statusBarItem.hide();
});
}
}

View File

@@ -1,8 +1,8 @@
import * as vscode from 'vscode';
import QuickPickItemEx from "../types/QuickPickItemExType";
import { QuickPickSupportCaseItem, quickPickSupportCases } from '../../core/variable-convert/types/SupportVariableCaseType';
import { QuickPickSupportCaseItem, quickPickSupportCases, settingsKeyToEnableSettingsKey } from '../../core/variable-convert/types/SupportVariableCaseType';
import { TransformTextResult } from '../../types/TransformTextResultType';
import { transformMutliSelectionText } from '../../utils/transform';
import { transformMultiSelectionText } from '../../utils/transform';
import { EOL } from '../../types/EOLType';
import { caseConversion } from '../../core/variable-convert/conversion';
import { isStringArrayEqual } from '../../utils/utils';
@@ -12,16 +12,21 @@ const QuickPickLabelMaxLength = 60;
interface RecommendItem {
conversionText: Array<string>
transforTo: string[]
transformTo: string[]
keyword: string[]
}
/**
* 弹出的提示
*
* @param textList
* @param eol
* @param enabledQuickPickSupportCases
* @returns
*/
function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPickSupportCases: Array<QuickPickSupportCaseItem>): Array<QuickPickItemEx> {
// Cut text 切割文本
const resultsList: Array<TransformTextResult[]> = transformMutliSelectionText(textList);
const resultsList: Array<TransformTextResult[]> = transformMultiSelectionText(textList);
const mergeResultList: Array<RecommendItem> = [];
for (const quickPick of enabledQuickPickSupportCases) {
@@ -37,14 +42,14 @@ function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPi
if (recommendItem === undefined) {
let item: RecommendItem = {
conversionText: conversionResults,
transforTo: [quickPick.shortName], // quickPick.name
transformTo: [quickPick.shortName], // quickPick.name
keyword: quickPick.keyword,
};
mergeResultList.push(item);
continue;
}
recommendItem.transforTo.push(quickPick.shortName); // quickPick.name
recommendItem.transformTo.push(quickPick.shortName); // quickPick.name
recommendItem.keyword = Array.from(new Set(recommendItem.keyword.concat(quickPick.keyword))); // 关键词去重
}
@@ -68,7 +73,7 @@ function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPi
label: conversionTextForDisplay.length >= QuickPickLabelMaxLength
? (conversionTextForDisplay.substring(0, QuickPickLabelMaxLength - 3) + '...')
: conversionTextForDisplay,
description: `转换为 ${recommendItem.transforTo.join(' / ')}`,
description: `转换为 ${recommendItem.transformTo.join(' / ')}`,
detail: `关键词 ${recommendItem.keyword.join(' ')}`,
value: recommendItem.conversionText,
};
@@ -96,22 +101,54 @@ export function handleQuickPick() {
return;
}
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
// 获取用户配置
const disableFormatList = getUserConfigurations<Array<string>>('disableFormat') || [];
const enabledFormats = getUserConfigurations<Record<string, boolean>>('enabledFormats') || {};
const formatOrder = getUserConfigurations<string[]>('formatOrder') || [];
// 排除禁用的选项
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
const enabledQuickPickSupportCases = [];
for (const quickPick of quickPickSupportCases) {
if (disableFormatList.includes(quickPick.settingsKey)) {
const enableSettingsKey = settingsKeyToEnableSettingsKey.get(quickPick.settingsKey);
if (!enableSettingsKey) {
console.warn('Cannot find enableSettingsKey for settingsKey:', quickPick.settingsKey);
continue;
}
if (enabledFormats[enableSettingsKey] !== true) {
continue;
}
enabledQuickPickSupportCases.push(quickPick);
}
if (enabledQuickPickSupportCases.length === 0) {
vscode.window.showInformationMessage('所有格式都已被配置为禁用,请修改配置 `variable-conversion.disableFormat` 后重试\nAll formats have been configured to disable. Modify the `variable-conversion.disableFormat` configuration and try again.');
vscode.window.showInformationMessage('所有格式都已被配置为禁用,请修改配置 `variable-conversion.enabledFormats` 后重试\nAll formats have been configured to disable. Modify the `variable-conversion.enabledFormats` configuration and try again.');
return;
}
// 按用户配置的顺序排序
// issue: #5 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/5
// issue: #6 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/6
if (formatOrder.length > 0) {
enabledQuickPickSupportCases.sort((a, b) => {
const indexA = formatOrder.indexOf(a.settingsKey);
const indexB = formatOrder.indexOf(b.settingsKey);
// 如果两个都在配置中,按配置顺序
if (indexA !== -1 && indexB !== -1) {
return indexA - indexB;
}
// 如果只有一个在配置中,在配置中的排在前面
if (indexA !== -1) {
return -1;
}
if (indexB !== -1) {
return 1;
}
// 如果都不在配置中,保持原有顺序
return 0;
});
}
// 基于选中的文本生成选项
const options = generateOptionsBasedOnText(textList, eol, enabledQuickPickSupportCases);
if (options.length === 0) {

View File

@@ -7,7 +7,7 @@ import { variableConvertTestGroups } from './test-case/variable-convert-test-cas
import { pathConvertTestGroups } from './test-case/path-convert-test-case';
import { VariableTestCase, VariableTestCaseGroup } from './test-case/types/VariableTestCaseType';
import { PathTestCase, PathTestCaseGroup } from './test-case/types/PathTestCaseType';
import { transformMutliLineText, transformText } from '../utils/transform';
import { transformMultiLineText } from '../utils/transform';
import { caseConversion } from '../core/variable-convert/conversion';
import { pathConversion } from '../core/path-convert/conversion';
import { SupportVariableCase } from '../core/variable-convert/types/SupportVariableCaseType';
@@ -49,7 +49,7 @@ suite('Extension Test: run variable convert test case', () => {
for (const input of inputList) {
// console.log('input', '->' + input + '<-');
// 验证 transformText
const transformTextResult: Array<TransformTextResult> = transformMutliLineText(input);
const transformTextResult: Array<TransformTextResult> = transformMultiLineText(input);
const results = transformTextResult.map(res => res.result);
for (let index = 0; index < testCase.transformText.length; index++) {
const correctValue = testCase.transformText[index];

View File

@@ -9,8 +9,8 @@ const logDebugInfo = false;
* @returns
* @since 2024-04-03
*/
export function transformMutliSelectionText(selectionInputs: string[]): Array<TransformTextResult[]> {
return selectionInputs.map(selectionInput => transformMutliLineText(selectionInput));
export function transformMultiSelectionText(selectionInputs: string[]): Array<TransformTextResult[]> {
return selectionInputs.map(selectionInput => transformMultiLineText(selectionInput));
}
/**
@@ -20,7 +20,7 @@ export function transformMutliSelectionText(selectionInputs: string[]): Array<Tr
* @returns
* @since 2024-04-03
*/
export function transformMutliLineText(multiLineInput: string): TransformTextResult[] {
export function transformMultiLineText(multiLineInput: string): TransformTextResult[] {
const results: TransformTextResult[] = [];
const lines = multiLineInput.split(/\r?\n/);
for (const line of lines) {

View File

@@ -41,4 +41,4 @@ export function stringListArrayDuplicateRemoval(stringArr: Array<string[]>): Arr
}
}
return newArr;
}
}

View File

@@ -8,7 +8,7 @@
],
"sourceMap": true,
"rootDir": "src",
"strict": true /* enable all strict type-checking options */
"strict": true, /* enable all strict type-checking options */
/* Additional Checks */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */