Merge branch 'main' into release
This commit is contained in:
commit
92db4b1627
17
CHANGELOG.md
17
CHANGELOG.md
@ -23,6 +23,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## 2.0.0
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New: Support path conversions via shortcut keys `Ctrl + Alt + /` and `Ctrl + Shift + Alt + /` (also supports multi-selection conversion). (支持通过 `Ctrl + Alt + /`, `Ctrl + Shift + Alt + /` 快捷键进行路径转换 (同时支持多选区转换))
|
||||||
|
- New: Support following path conversion type: QuickPick menu conversion, context menu conversion, status bar button conversion, shortcut key conversion. (支持以下路径转换方式:QuickPick 菜单转换、右键菜单转换、状态栏按钮转换、快捷键转换)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Do not display the editor context menu `Variable Conversion` option when text is not selected. (当未选中文本时,不显示右键菜单 `变量转换` 选项)
|
||||||
|
|
||||||
|
### Improvement
|
||||||
|
|
||||||
|
- Adjust the project code directory structure. (项目代码目录结构调整)
|
||||||
|
|
||||||
## 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@ -46,7 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- New: Supports multi-selection conversion (支持多选区转换)
|
- New: Supports multi-selection conversion (支持多选区转换)
|
||||||
- New: Supports scrolling conversion via shortcut keys `Ctrl + Alt + [` and `Ctrl + Alt + ]` (also supports multi-selection conversion) 支持通过快捷键循环转换 (同时支持多选区转换)
|
- New: Supports scrolling variable conversion via shortcut keys `Ctrl + Alt + [` and `Ctrl + Alt + ]` (also supports multi-selection conversion). (支持通过 `Ctrl + Alt + [`, `Ctrl + Alt + ]` 快捷键进行变量循环转换 (同时支持多选区转换))
|
||||||
|
|
||||||
## 1.0.7
|
## 1.0.7
|
||||||
|
|
||||||
|
71
README.md
71
README.md
@ -1,19 +1,24 @@
|
|||||||
# 变量命名转换插件 Variable Conversion
|
# 变量命名转换助手 — Variable Conversion (VSCode 扩展)
|
||||||
|
|
||||||
[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)
|
[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>
|
一个强大的变量命名及路径风格转换插件,支持一键转换、循环转换,支持右键菜单、快捷键、状态栏等多种方式使用。<br>
|
||||||
A powerful variable naming conversion extension. Supports one-key conversion & cyclic conversion. You can use it through the editer menu, shortcut keys and bottom bar.
|
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.
|
||||||
|
|
||||||
|
> 【近期更新】v2.0.0 版本 (2024-12-15)
|
||||||
|
>
|
||||||
|
> - 支持 Windows / Unix 路径风格转换(可选中文本中的路径,然后使用 `Ctrl + Alt + /` 快捷键,或点击右键菜单、底部状态栏路径转换按钮轻松实现转换)
|
||||||
|
|
||||||
- ✅ 支持多选区 Support multi-selection
|
- ✅ 支持多选区 Support multi-selection
|
||||||
- ✅ 支持多窗口 (不支持子窗口状态栏) Support subwindow (subwindow status bar are not supported)
|
- ✅ 支持多窗口 Support subwindow
|
||||||
- ✅ 支持撤回 & 重做 Support undo & redo (Ctrl + Z / Ctrl + Y)
|
- ✅ 支持撤回 & 重做 Support undo & redo (Ctrl + Z / Ctrl + Y)
|
||||||
|
- ✅ 支持禁用部分目标转换格式 Supports disabling some target conversion formats
|
||||||
|
|
||||||
> 🔭 Tips for Chinese users: 如果您无法看到下文图片,请[点这里](https://gitee.com/coder-xiaomo/variable-conversion-vscode-extension/blob/main/README.md)查看
|
> 🔭 Tips for Chinese users: 如果您无法看到下文图片,请[点这里](https://gitee.com/coder-xiaomo/variable-conversion-vscode-extension/blob/main/README.md)查看
|
||||||
|
|
||||||
## 如何使用? How to Use?
|
## 如何使用? How to Use?
|
||||||
|
|
||||||
### 循环转换 Cyclic conversion (Beta)
|
### 循环转换 Cyclic conversion
|
||||||
|
|
||||||
选中需要转换的内容,然后按下 `Ctrl + Alt + [` 或 `Ctrl + Alt + ]` 即可前后灵活切换变量命名方式。 <br>
|
选中需要转换的内容,然后按下 `Ctrl + Alt + [` 或 `Ctrl + Alt + ]` 即可前后灵活切换变量命名方式。 <br>
|
||||||
Select what you want to convert in the editor, and then press `Ctrl + Alt + [` or `Ctrl + Alt + ]` to flexibly convert variable name flexibly.
|
Select what you want to convert in the editor, and then press `Ctrl + Alt + [` or `Ctrl + Alt + ]` to flexibly convert variable name flexibly.
|
||||||
@ -47,15 +52,37 @@ Or right-click on the selected text -> Convert string to...
|
|||||||
|
|
||||||
**3. 选择转换目标,转换完成** **Select the conversion target and complete**
|
**3. 选择转换目标,转换完成** **Select the conversion target and complete**
|
||||||
|
|
||||||
|
### 路径转换 Path Conversion (Beta)
|
||||||
|
|
||||||
|
> 该功能仍在 Beta 测试阶段,如您在使用过程中遇到问题,欢迎通过文末联系方式进行反馈。
|
||||||
|
>
|
||||||
|
> This feature is still in Beta testing stage, if you encounter any problems during use, please give feedback via the contact information at the end of the article.
|
||||||
|
|
||||||
|
路径转换与变量转换操作逻辑基本相同,都可以通过 *右键菜单*、*底部状态栏*、*快捷键* 等方式使用,唯一区别是快捷键的不同。
|
||||||
|
|
||||||
|
路径转换快捷键为:
|
||||||
|
|
||||||
|
- 切换下一个路径风格:`Ctrl + Alt + /`
|
||||||
|
- 切换上一个路径风格:`Ctrl + Alt + Shift + /`
|
||||||
|
|
||||||
|
![Path Conversion](image/path-conversion.gif)
|
||||||
|
|
||||||
|
**注:**目前 `v2.0.0` 版本暂仅支持 `Windows 风格路径` 与 `Unix 风格路径` 互转,所以这两个快捷键目前效果相同。**后续会陆续增加其他更多路径风格**(例如 `Windows Git Bash` 风格,浏览器 `file://` 协议风格等),敬请期待。
|
||||||
|
|
||||||
## 快捷键 Shortcut key
|
## 快捷键 Shortcut key
|
||||||
|
|
||||||
| 功能 Feature | 快捷键 shortcut key |
|
| 功能 Feature | 快捷键 shortcut key |
|
||||||
| ------------------------------------------------ | ------------------- |
|
| ------------------------------------------------------------ | ---------------------- |
|
||||||
| 变量转换 快速选择 QuickPick | Shift + Alt + T |
|
| 变量转换 快速选择 Variable Conversion QuickPick | Shift + Alt + T |
|
||||||
| 循环转换→上一个 Cyclic conversion → Previous one | Ctrl + Alt + [ |
|
| 变量循环转换→上一个 Variable Cyclic Conversion → Previous one | Ctrl + Alt + [ |
|
||||||
| 循环转换→下一个 Cyclic conversion → Next one | Ctrl + Alt + ] |
|
| 变量循环转换→下一个 Variable Cyclic Conversion → Next one | Ctrl + Alt + ] |
|
||||||
|
| 路径转换 快速选择 Path Conversion QuickPick | Shift + Alt + / |
|
||||||
|
| 路径循环转换→上一个 Path Cyclic conversion → Previous one | Ctrl + Alt + / |
|
||||||
|
| 路径循环转换→下一个 Path Cyclic conversion → Next one | Ctrl + Shift + Alt + / |
|
||||||
|
|
||||||
## 配置项 configurations
|
> 若您觉得快捷键使用不顺手,您可在 VSCode 左下角齿轮图标⚙ → 键盘快捷方式中自定义修改快捷键。
|
||||||
|
|
||||||
|
## 配置项 Configurations
|
||||||
|
|
||||||
| 配置项 Configuration Key | 描述 Description | 配置示例 | 默认值 |
|
| 配置项 Configuration Key | 描述 Description | 配置示例 | 默认值 |
|
||||||
| ----------------------------------- | ------------------------------------------------------------ | ------------------------------ | ------ |
|
| ----------------------------------- | ------------------------------------------------------------ | ------------------------------ | ------ |
|
||||||
@ -63,6 +90,8 @@ Or right-click on the selected text -> Convert string to...
|
|||||||
|
|
||||||
## 支持的类型 Support Case
|
## 支持的类型 Support Case
|
||||||
|
|
||||||
|
### 变量转换
|
||||||
|
|
||||||
| 类型 | Case | 举例 e.g. |
|
| 类型 | Case | 举例 e.g. |
|
||||||
| ------------------------------------------ | ------------------------ | ---------------- |
|
| ------------------------------------------ | ------------------------ | ---------------- |
|
||||||
| 小驼峰(驼峰)命名 | Camel Case | fooBar |
|
| 小驼峰(驼峰)命名 | Camel Case | fooBar |
|
||||||
@ -86,6 +115,26 @@ Or right-click on the selected text -> Convert string to...
|
|||||||
| 全小写 | Lower Case | foo_bar / foobar |
|
| 全小写 | Lower Case | foo_bar / foobar |
|
||||||
| 全大写 | Upper Case | FOO_BAR / FOOBAR |
|
| 全大写 | Upper Case | FOO_BAR / FOOBAR |
|
||||||
|
|
||||||
|
### 路径转换
|
||||||
|
|
||||||
|
现已支持的路径风格:
|
||||||
|
|
||||||
|
| 路径风格 | Sttyle | 举例 e.g. |
|
||||||
|
| ------------ | ------------- | ---------------------------------------------- |
|
||||||
|
| Windows 风格 | Windows Style | `C:\Windows\System32` <br />`.\public\assets\` |
|
||||||
|
| Unix 风格 | Unix Style | `/usr/bin`<br />`./public/assets/` |
|
||||||
|
|
||||||
|
尚未支持的路径风格:
|
||||||
|
|
||||||
|
| 路径风格 | Case | 举例 e.g. |
|
||||||
|
| -------------------------- | --------------------------------- | ------------------------------------- |
|
||||||
|
| 👇未来计划支持 | | |
|
||||||
|
| Windows 风格(反斜杠转义) | Windows Style (Backslash Escaped) | `C:\\Windows\\System32` |
|
||||||
|
| Unix 风格(反斜杠转义) | Unix Style (Backslash Escaped) | `\/usr\/bin` |
|
||||||
|
| Windows Git Bash 风格 | Windows Git Bash Style | `/c/Windows/System32` |
|
||||||
|
| 👇未来可能支持 | | |
|
||||||
|
| 浏览器 `file://` 协议风格 | | `file:///C:/Program%20Files%20(x86)/` |
|
||||||
|
|
||||||
## 小提示 Tips
|
## 小提示 Tips
|
||||||
|
|
||||||
#### 关于文本选区... About text selections...
|
#### 关于文本选区... About text selections...
|
||||||
|
BIN
image/path-conversion.gif
Normal file
BIN
image/path-conversion.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 241 KiB |
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "variable-conversion",
|
"name": "variable-conversion",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "variable-conversion",
|
"name": "variable-conversion",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mocha": "^10.0.6",
|
"@types/mocha": "^10.0.6",
|
||||||
"@types/node": "18.x",
|
"@types/node": "18.x",
|
||||||
|
86
package.json
86
package.json
@ -2,7 +2,7 @@
|
|||||||
"name": "variable-conversion",
|
"name": "variable-conversion",
|
||||||
"displayName": "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.",
|
"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": "1.1.0",
|
"version": "2.0.0",
|
||||||
"icon": "image/logo.png",
|
"icon": "image/logo.png",
|
||||||
"publisher": "coder-xiaomo",
|
"publisher": "coder-xiaomo",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -52,6 +52,27 @@
|
|||||||
"arrowKey": "]"
|
"arrowKey": "]"
|
||||||
},
|
},
|
||||||
"when": "editorTextFocus"
|
"when": "editorTextFocus"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "variable-conversion.convertPath",
|
||||||
|
"key": "shift+alt+/",
|
||||||
|
"when": "editorTextFocus"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "variable-conversion.cyclicConvertPath.previous",
|
||||||
|
"key": "ctrl+alt+shift+/",
|
||||||
|
"args": {
|
||||||
|
"direction": "<-"
|
||||||
|
},
|
||||||
|
"when": "editorTextFocus"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "variable-conversion.cyclicConvertPath.next",
|
||||||
|
"key": "ctrl+alt+/",
|
||||||
|
"args": {
|
||||||
|
"direction": "->"
|
||||||
|
},
|
||||||
|
"when": "editorTextFocus"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"commands": [
|
"commands": [
|
||||||
@ -138,19 +159,41 @@
|
|||||||
{
|
{
|
||||||
"command": "variable-conversion.toUpperCase",
|
"command": "variable-conversion.toUpperCase",
|
||||||
"title": "全大写 (Upper Case) [ FOOBAR ]"
|
"title": "全大写 (Upper Case) [ FOOBAR ]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "variable-conversion.convertPath",
|
||||||
|
"title": "路径转换"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "variable-conversion.pathFormat.toWindowsStyle",
|
||||||
|
"title": "Windows 风格 [ C:\\Windows\\System32 ]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "variable-conversion.pathFormat.toUnixStyle",
|
||||||
|
"title": "Unix 风格 [ /usr/bin ]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menus": {
|
"menus": {
|
||||||
"editor/context": [
|
"editor/context": [
|
||||||
{
|
{
|
||||||
"when": "editorTextFocus",
|
"when": "editorTextFocus && _textSelectionLength >= 1",
|
||||||
"command": "variable-conversion.convertCase",
|
"command": "variable-conversion.convertCase",
|
||||||
"group": "navigation@9"
|
"group": "navigation@10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"when": "editorTextFocus && _textSelectionLength >= 1",
|
"when": "editorTextFocus && _textSelectionLength >= 1",
|
||||||
"submenu": "variable-conversion.stringConversionMenu",
|
"submenu": "variable-conversion.stringConversionMenu",
|
||||||
"group": "navigation@9"
|
"group": "navigation@11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": "editorTextFocus && _textSelectionLength >= 1",
|
||||||
|
"command": "variable-conversion.convertPath",
|
||||||
|
"group": "navigation@12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": "editorTextFocus && _textSelectionLength >= 1",
|
||||||
|
"submenu": "variable-conversion.pathConversionMenu",
|
||||||
|
"group": "navigation@13"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"variable-conversion.stringConversionMenu": [
|
"variable-conversion.stringConversionMenu": [
|
||||||
@ -254,12 +297,28 @@
|
|||||||
"command": "variable-conversion.toUpperCase",
|
"command": "variable-conversion.toUpperCase",
|
||||||
"group": "group-6-upper-lower@2"
|
"group": "group-6-upper-lower@2"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"variable-conversion.pathConversionMenu": [
|
||||||
|
{
|
||||||
|
"when": "!_isHideSubMenuItem_windows_style",
|
||||||
|
"command": "variable-conversion.pathFormat.toWindowsStyle",
|
||||||
|
"group": "group-1-common-style@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": "!_isHideSubMenuItem_unix_style",
|
||||||
|
"command": "variable-conversion.pathFormat.toUnixStyle",
|
||||||
|
"group": "group-1-common-style@2"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"submenus": [
|
"submenus": [
|
||||||
{
|
{
|
||||||
"id": "variable-conversion.stringConversionMenu",
|
"id": "variable-conversion.stringConversionMenu",
|
||||||
"label": "将变量转换为..."
|
"label": "将变量转换为..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "variable-conversion.pathConversionMenu",
|
||||||
|
"label": "将路径转换为..."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"configuration": {
|
"configuration": {
|
||||||
@ -267,7 +326,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"variable-conversion.disableFormat": {
|
"variable-conversion.disableFormat": {
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"markdownDescription": "定义哪些格式是禁用的\n\nDefine which 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)",
|
"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)",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -317,6 +376,23 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"default": []
|
"default": []
|
||||||
|
},
|
||||||
|
"variable-conversion.disablePathFormat": {
|
||||||
|
"order": 3,
|
||||||
|
"markdownDescription": "定义哪些路径风格是禁用的\n\nDefine which path 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.disablePathFormat\": [ ... ],`\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)",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"windows_style",
|
||||||
|
"unix_style"
|
||||||
|
],
|
||||||
|
"enumDescriptions": [
|
||||||
|
"Windows 风格",
|
||||||
|
"Unix 风格"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
62
src/core/path-convert/conversion.ts
Normal file
62
src/core/path-convert/conversion.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { EOL } from "../../types/EOLType";
|
||||||
|
import { SupportPathFormat } from "./types/SupportPathFormatType";
|
||||||
|
import { TransformTextResult } from '../../types/TransformTextResultType';
|
||||||
|
|
||||||
|
/** / */
|
||||||
|
const LEFT_SLASH = '/';
|
||||||
|
/** \ */
|
||||||
|
const RIGHT_SLASH = '\\';
|
||||||
|
/** \\ */
|
||||||
|
const DOUBLE_RIGHT_SLASH = '\\\\';
|
||||||
|
|
||||||
|
export function pathConversion(targetPathType: SupportPathFormat, input: string, eol: EOL, cutText: Array<TransformTextResult> | undefined = undefined): string {
|
||||||
|
let resultPath;
|
||||||
|
|
||||||
|
let isSeperator = false;
|
||||||
|
switch (targetPathType) {
|
||||||
|
case SupportPathFormat.Windows:
|
||||||
|
// 将其中的 / 替换为 \
|
||||||
|
resultPath = Array.from(input).map((char: string) => {
|
||||||
|
if (char !== LEFT_SLASH) {
|
||||||
|
// 当前字符不是 /
|
||||||
|
isSeperator = false;
|
||||||
|
return char;
|
||||||
|
} else {
|
||||||
|
// 当前字符是 /
|
||||||
|
if (!isSeperator) {
|
||||||
|
// 上一字符不是 /
|
||||||
|
isSeperator = true;
|
||||||
|
return RIGHT_SLASH; // 替换成 \
|
||||||
|
}
|
||||||
|
// 上一字符是 /
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
break;
|
||||||
|
case SupportPathFormat.Unix:
|
||||||
|
// 将其中的 \\ 和 \ 替换为 /
|
||||||
|
resultPath = Array.from(input).map((char: string) => {
|
||||||
|
if (char !== RIGHT_SLASH) {
|
||||||
|
// 当前字符不是 \
|
||||||
|
isSeperator = false;
|
||||||
|
return char;
|
||||||
|
} else {
|
||||||
|
// 当前字符是 \
|
||||||
|
if (!isSeperator) {
|
||||||
|
// 上一字符不是 \
|
||||||
|
isSeperator = true;
|
||||||
|
return LEFT_SLASH; // 替换成 /
|
||||||
|
}
|
||||||
|
// 上一字符是 \
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
break;
|
||||||
|
// case SupportPathFormat.WindowsGitBash:
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultPath;
|
||||||
|
}
|
116
src/core/path-convert/cyclic-conversion.ts
Normal file
116
src/core/path-convert/cyclic-conversion.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { EOL } from "../../types/EOLType";
|
||||||
|
import { cyclicConvertPathOrder } from "./types/SupportPathFormatType";
|
||||||
|
import { pathConversion } from "./conversion";
|
||||||
|
import { isStringArrayEqual, stringListArrayDuplicateRemoval } from '../../utils/utils';
|
||||||
|
import { getUserConfigurations } from '../../utils/user-configuration';
|
||||||
|
|
||||||
|
interface UserSelection {
|
||||||
|
currentEol: EOL
|
||||||
|
currentSelections?: readonly vscode.Selection[]
|
||||||
|
currentSelectionsText: string[]
|
||||||
|
currentIndex: number
|
||||||
|
isConverted: boolean
|
||||||
|
conversionsTarget: Array<string[]>
|
||||||
|
lastConvertedSelectionsText: string[] // 按快捷键后转换的值(如果下次触发 onUserSelectionUpdated 后传入值是这个,那么跳过,避免丢失当前循环转换记录)
|
||||||
|
}
|
||||||
|
|
||||||
|
const userSelection: UserSelection = {
|
||||||
|
currentEol: '\n',
|
||||||
|
// currentSelections: undefined,
|
||||||
|
currentSelectionsText: [],
|
||||||
|
currentIndex: 0,
|
||||||
|
isConverted: false,
|
||||||
|
conversionsTarget: [], // 转换后去重 剩余转换目标
|
||||||
|
lastConvertedSelectionsText: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export function onUserSelectionUpdated(selections: readonly vscode.Selection[], textList: string[], eol: EOL): void {
|
||||||
|
userSelection.currentSelections = selections;
|
||||||
|
if (textList.length !== 0 && isStringArrayEqual(textList, userSelection.lastConvertedSelectionsText)) {
|
||||||
|
// console.log('skip onUserSelectionUpdated');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// console.log('onUserSelectionUpdated', textList, userSelection.lastConvertedSelectionsText);
|
||||||
|
userSelection.currentEol = eol;
|
||||||
|
userSelection.currentSelectionsText = textList;
|
||||||
|
userSelection.currentIndex = 0;
|
||||||
|
userSelection.isConverted = false;
|
||||||
|
userSelection.conversionsTarget = [textList];
|
||||||
|
userSelection.lastConvertedSelectionsText = textList;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function previousOne() {
|
||||||
|
lazyConvert();
|
||||||
|
const length = userSelection.conversionsTarget.length;
|
||||||
|
const oldIndex = userSelection.currentIndex;
|
||||||
|
const newIndex = oldIndex === 0 ? (length - 1) : (oldIndex - 1);
|
||||||
|
userSelection.currentIndex = newIndex;
|
||||||
|
console.log('previousOne oldIndex', oldIndex, 'newIndex', newIndex);
|
||||||
|
replaceTextEditorSelectedText();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nextOne() {
|
||||||
|
lazyConvert();
|
||||||
|
const length = userSelection.conversionsTarget.length;
|
||||||
|
const oldIndex = userSelection.currentIndex;
|
||||||
|
const newIndex = oldIndex >= length - 1 ? 0 : (oldIndex + 1);
|
||||||
|
userSelection.currentIndex = newIndex;
|
||||||
|
console.log('nextOne oldIndex', oldIndex, 'newIndex', newIndex);
|
||||||
|
replaceTextEditorSelectedText();
|
||||||
|
}
|
||||||
|
|
||||||
|
function lazyConvert() {
|
||||||
|
if (userSelection.isConverted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户配置
|
||||||
|
// TODO
|
||||||
|
// const disablePathFormatList = getUserConfigurations<Array<string>>('disablePathFormat') || [];
|
||||||
|
|
||||||
|
const textList = userSelection.currentSelectionsText;
|
||||||
|
// vscode.window.showInformationMessage('lazyConvert' + textList.join('\n'));
|
||||||
|
const eol = userSelection.currentEol;
|
||||||
|
const conversionsTarget: Array<string[]> = [textList];
|
||||||
|
for (const cyclicConvertCase of cyclicConvertPathOrder) {
|
||||||
|
// 跳过禁用的目标格式
|
||||||
|
// TODO
|
||||||
|
// if (disablePathFormatList.includes(cyclicConvertCase.settingsKey)) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 每一个类型
|
||||||
|
const conversionsTargetItem: string[] = [];
|
||||||
|
for (const line of textList) {
|
||||||
|
// 选中区块的每一行
|
||||||
|
const conversionResult: string = pathConversion(cyclicConvertCase.type, line, eol);
|
||||||
|
conversionsTargetItem.push(conversionResult);
|
||||||
|
}
|
||||||
|
conversionsTarget.push(conversionsTargetItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按数组去重
|
||||||
|
const noDuplicate = stringListArrayDuplicateRemoval(conversionsTarget);
|
||||||
|
// console.log('noDuplicate', noDuplicate);
|
||||||
|
|
||||||
|
userSelection.conversionsTarget = noDuplicate;
|
||||||
|
userSelection.isConverted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceTextEditorSelectedText() {
|
||||||
|
let editor = vscode.window.activeTextEditor;
|
||||||
|
if (editor) {
|
||||||
|
const selections = userSelection.currentSelections || [];
|
||||||
|
const textList = userSelection.conversionsTarget[userSelection.currentIndex];
|
||||||
|
console.log('selections', selections, 'textList', textList);
|
||||||
|
editor.edit(editBuilder => {
|
||||||
|
for (let i = 0; i < selections.length; i++) {
|
||||||
|
const selection = selections[i];
|
||||||
|
const converted = textList[i];
|
||||||
|
editBuilder.replace(selection, converted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
userSelection.lastConvertedSelectionsText = textList;
|
||||||
|
}
|
||||||
|
}
|
101
src/core/path-convert/types/SupportPathFormatType.ts
Normal file
101
src/core/path-convert/types/SupportPathFormatType.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* 路径转换类型
|
||||||
|
*
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
export enum SupportPathFormat {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows 风格
|
||||||
|
*
|
||||||
|
* @alias: windows / Windows
|
||||||
|
* @since 2024-12-07
|
||||||
|
*/
|
||||||
|
Windows,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unix 风格
|
||||||
|
*
|
||||||
|
* @alias: unix / Unix
|
||||||
|
* @since 2024-12-07
|
||||||
|
*/
|
||||||
|
Unix,
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyword = {
|
||||||
|
windows: [
|
||||||
|
'Windows', 'win',
|
||||||
|
],
|
||||||
|
unix: [
|
||||||
|
'Unix',
|
||||||
|
'Linux',
|
||||||
|
'macOS',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接管的变量转换命令
|
||||||
|
*
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
export const commands: Array<{ command: string; targetCase: SupportPathFormat; settingsKey: string }> = [
|
||||||
|
{
|
||||||
|
command: 'variable-conversion.pathFormat.toWindowsStyle',
|
||||||
|
targetCase: SupportPathFormat.Windows,
|
||||||
|
settingsKey: 'windows_style'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: 'variable-conversion.pathFormat.toUnixStyle',
|
||||||
|
targetCase: SupportPathFormat.Unix,
|
||||||
|
settingsKey: 'unix_style'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
export interface QuickPickSupportCaseItem {
|
||||||
|
type: SupportPathFormat,
|
||||||
|
name: string,
|
||||||
|
shortName: string,
|
||||||
|
keyword: string[],
|
||||||
|
settingsKey: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有支持的路径风格
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
export const quickPickSupportCases: Array<QuickPickSupportCaseItem> = [
|
||||||
|
{
|
||||||
|
type: SupportPathFormat.Windows,
|
||||||
|
name: 'Microsoft Windows 风格',
|
||||||
|
shortName: 'Windows 风格',
|
||||||
|
keyword: keyword.windows,
|
||||||
|
settingsKey: 'windows_style',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: SupportPathFormat.Unix,
|
||||||
|
name: 'Unix / 类 Unix 风格 (Linux, macOS, ...)',
|
||||||
|
shortName: 'Unix 风格',
|
||||||
|
keyword: keyword.unix,
|
||||||
|
settingsKey: 'unix_style',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
export interface CyclicConvertPathOrderItem {
|
||||||
|
type: SupportPathFormat,
|
||||||
|
settingsKey: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过快捷键循环转换的顺序
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
export const cyclicConvertPathOrder: Array<CyclicConvertPathOrderItem> = [
|
||||||
|
{ type: SupportPathFormat.Windows, settingsKey: 'windows' },
|
||||||
|
{ type: SupportPathFormat.Unix, settingsKey: 'unix' },
|
||||||
|
];
|
@ -1,52 +1,53 @@
|
|||||||
import { EOL } from '../type-definition/EOLType';
|
import { EOL } from '../../types/EOLType';
|
||||||
import { SupportCase } from '../type-definition/SupportCaseType';
|
import { SupportVariableCase } from './types/SupportVariableCaseType';
|
||||||
import { TransformTextResult } from '../type-definition/TransformTextResultType';
|
import { TransformTextResult } from '../../types/TransformTextResultType';
|
||||||
import { transformMutliLineText, transformText } from './transform';
|
import { transformMutliLineText, transformText } from '../../utils/transform';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一文本转换函数
|
* 统一文本转换函数
|
||||||
*
|
*
|
||||||
* @param {SupportCase} targetCase 目标文本情况
|
* @param {SupportVariableCase} targetCase 目标文本情况
|
||||||
* @param {string} str 用户选择的文本 user selection
|
* @param {string} str 用户选择的文本 user selection
|
||||||
* @param {EOL} eol 行结束符
|
* @param {EOL} eol 行结束符
|
||||||
|
* @param {Array<TransformTextResult>?} cutText 行结束符
|
||||||
* @returns 转换后的文本
|
* @returns 转换后的文本
|
||||||
* @since 2024-04-04
|
* @since 2024-04-04
|
||||||
*/
|
*/
|
||||||
export function caseConversion(targetCase: SupportCase, str: string, eol: EOL, cutText: Array<TransformTextResult> | undefined = undefined): string {
|
export function caseConversion(targetCase: SupportVariableCase, str: string, eol: EOL, cutText: Array<TransformTextResult> | undefined = undefined): string {
|
||||||
let spaceCharacter: '-' | '_' | ' ' | '.' | undefined = undefined;
|
let spaceCharacter: '-' | '_' | ' ' | '.' | undefined = undefined;
|
||||||
switch (targetCase) {
|
switch (targetCase) {
|
||||||
default:
|
default:
|
||||||
case SupportCase.CAMEL_CASE: // 小驼峰(驼峰)命名
|
case SupportVariableCase.CAMEL_CASE: // 小驼峰(驼峰)命名
|
||||||
case SupportCase.PASCAL_CASE: // 大驼峰(帕斯卡)命名
|
case SupportVariableCase.PASCAL_CASE: // 大驼峰(帕斯卡)命名
|
||||||
spaceCharacter = undefined;
|
spaceCharacter = undefined;
|
||||||
break;
|
break;
|
||||||
case SupportCase.SNAKE_CASE: // 下划线(蛇形)命名
|
case SupportVariableCase.SNAKE_CASE: // 下划线(蛇形)命名
|
||||||
case SupportCase.SNAKE_CAMEL_CASE: // 下划线(蛇形) + 小驼峰(驼峰)命名
|
case SupportVariableCase.SNAKE_CAMEL_CASE: // 下划线(蛇形) + 小驼峰(驼峰)命名
|
||||||
case SupportCase.SNAKE_PASCAL_CASE: // 下划线(蛇形) + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.SNAKE_PASCAL_CASE: // 下划线(蛇形) + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.SNAKE_UPPER_CASE: // 下划线(蛇形) + 全大写命名
|
case SupportVariableCase.SNAKE_UPPER_CASE: // 下划线(蛇形) + 全大写命名
|
||||||
spaceCharacter = '_';
|
spaceCharacter = '_';
|
||||||
break;
|
break;
|
||||||
case SupportCase.KEBAB_CASE: // 中划线(连字符/脊柱式)命名
|
case SupportVariableCase.KEBAB_CASE: // 中划线(连字符/脊柱式)命名
|
||||||
case SupportCase.KEBAB_CAMEL_CASE: // 中划线(连字符/脊柱式) + 小驼峰(驼峰)命名
|
case SupportVariableCase.KEBAB_CAMEL_CASE: // 中划线(连字符/脊柱式) + 小驼峰(驼峰)命名
|
||||||
case SupportCase.KEBAB_PASCAL_CASE: // 中划线(连字符/脊柱式) + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.KEBAB_PASCAL_CASE: // 中划线(连字符/脊柱式) + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.KEBAB_UPPER_CASE: // 中划线(连字符/脊柱式) + 全大写命名
|
case SupportVariableCase.KEBAB_UPPER_CASE: // 中划线(连字符/脊柱式) + 全大写命名
|
||||||
spaceCharacter = '-';
|
spaceCharacter = '-';
|
||||||
break;
|
break;
|
||||||
case SupportCase.SPACE_CASE: // 空格分隔命名
|
case SupportVariableCase.SPACE_CASE: // 空格分隔命名
|
||||||
case SupportCase.SPACE_CAMEL_CASE: // 空格分隔 + 小驼峰(驼峰)命名
|
case SupportVariableCase.SPACE_CAMEL_CASE: // 空格分隔 + 小驼峰(驼峰)命名
|
||||||
case SupportCase.SPACE_PASCAL_CASE: // 空格分隔 + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.SPACE_PASCAL_CASE: // 空格分隔 + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.SPACE_UPPER_CASE: // 空格分隔 + 全大写命名
|
case SupportVariableCase.SPACE_UPPER_CASE: // 空格分隔 + 全大写命名
|
||||||
spaceCharacter = ' ';
|
spaceCharacter = ' ';
|
||||||
break;
|
break;
|
||||||
case SupportCase.DOT_CASE: // 点分隔命名
|
case SupportVariableCase.DOT_CASE: // 点分隔命名
|
||||||
case SupportCase.DOT_CAMEL_CASE: // 点分隔 + 小驼峰(驼峰)命名
|
case SupportVariableCase.DOT_CAMEL_CASE: // 点分隔 + 小驼峰(驼峰)命名
|
||||||
case SupportCase.DOT_PASCAL_CASE: // 点分隔 + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.DOT_PASCAL_CASE: // 点分隔 + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.DOT_UPPER_CASE: // 点分隔 + 全大写命名
|
case SupportVariableCase.DOT_UPPER_CASE: // 点分隔 + 全大写命名
|
||||||
spaceCharacter = '.';
|
spaceCharacter = '.';
|
||||||
break;
|
break;
|
||||||
case SupportCase.LOWER_CASE: // 全小写
|
case SupportVariableCase.LOWER_CASE: // 全小写
|
||||||
return str.toLowerCase();
|
return str.toLowerCase();
|
||||||
case SupportCase.UPPER_CASE: // 全大写
|
case SupportVariableCase.UPPER_CASE: // 全大写
|
||||||
return str.toUpperCase();
|
return str.toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,11 +85,11 @@ export function caseConversion(targetCase: SupportCase, str: string, eol: EOL, c
|
|||||||
|
|
||||||
// 根据目标情况转换单词
|
// 根据目标情况转换单词
|
||||||
switch (targetCase) {
|
switch (targetCase) {
|
||||||
case SupportCase.CAMEL_CASE: // 小驼峰(驼峰)命名
|
case SupportVariableCase.CAMEL_CASE: // 小驼峰(驼峰)命名
|
||||||
case SupportCase.SNAKE_CAMEL_CASE: // 下划线(蛇形) + 小驼峰(驼峰)命名
|
case SupportVariableCase.SNAKE_CAMEL_CASE: // 下划线(蛇形) + 小驼峰(驼峰)命名
|
||||||
case SupportCase.KEBAB_CAMEL_CASE: // 中划线(连字符/脊柱式) + 小驼峰(驼峰)命名
|
case SupportVariableCase.KEBAB_CAMEL_CASE: // 中划线(连字符/脊柱式) + 小驼峰(驼峰)命名
|
||||||
case SupportCase.SPACE_CAMEL_CASE: // 空格分隔 + 小驼峰(驼峰)命名
|
case SupportVariableCase.SPACE_CAMEL_CASE: // 空格分隔 + 小驼峰(驼峰)命名
|
||||||
case SupportCase.DOT_CAMEL_CASE: // 点分隔 + 小驼峰(驼峰)命名
|
case SupportVariableCase.DOT_CAMEL_CASE: // 点分隔 + 小驼峰(驼峰)命名
|
||||||
if (isFirstWord) {
|
if (isFirstWord) {
|
||||||
transformedWords.push(word);
|
transformedWords.push(word);
|
||||||
if (isCurrentWordNormal) {
|
if (isCurrentWordNormal) {
|
||||||
@ -98,23 +99,23 @@ export function caseConversion(targetCase: SupportCase, str: string, eol: EOL, c
|
|||||||
transformedWords.push(pascalCaseWord);
|
transformedWords.push(pascalCaseWord);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SupportCase.PASCAL_CASE: // 大驼峰(帕斯卡)命名
|
case SupportVariableCase.PASCAL_CASE: // 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.SNAKE_PASCAL_CASE: // 下划线(蛇形) + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.SNAKE_PASCAL_CASE: // 下划线(蛇形) + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.KEBAB_PASCAL_CASE: // 中划线(连字符/脊柱式) + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.KEBAB_PASCAL_CASE: // 中划线(连字符/脊柱式) + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.SPACE_PASCAL_CASE: // 空格分隔 + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.SPACE_PASCAL_CASE: // 空格分隔 + 大驼峰(帕斯卡)命名
|
||||||
case SupportCase.DOT_PASCAL_CASE: // 点分隔 + 大驼峰(帕斯卡)命名
|
case SupportVariableCase.DOT_PASCAL_CASE: // 点分隔 + 大驼峰(帕斯卡)命名
|
||||||
transformedWords.push(pascalCaseWord);
|
transformedWords.push(pascalCaseWord);
|
||||||
break;
|
break;
|
||||||
case SupportCase.SNAKE_CASE: // 下划线(蛇形)命名
|
case SupportVariableCase.SNAKE_CASE: // 下划线(蛇形)命名
|
||||||
case SupportCase.KEBAB_CASE: // 中划线(连字符/脊柱式)命名
|
case SupportVariableCase.KEBAB_CASE: // 中划线(连字符/脊柱式)命名
|
||||||
case SupportCase.SPACE_CASE: // 空格分隔命名
|
case SupportVariableCase.SPACE_CASE: // 空格分隔命名
|
||||||
case SupportCase.DOT_CASE: // 点分隔命名x
|
case SupportVariableCase.DOT_CASE: // 点分隔命名
|
||||||
transformedWords.push(word);
|
transformedWords.push(word);
|
||||||
break;
|
break;
|
||||||
case SupportCase.SNAKE_UPPER_CASE: // 下划线(蛇形) + 全大写命名
|
case SupportVariableCase.SNAKE_UPPER_CASE: // 下划线(蛇形) + 全大写命名
|
||||||
case SupportCase.KEBAB_UPPER_CASE: // 中划线(连字符/脊柱式) + 全大写命名
|
case SupportVariableCase.KEBAB_UPPER_CASE: // 中划线(连字符/脊柱式) + 全大写命名
|
||||||
case SupportCase.SPACE_UPPER_CASE: // 空格分隔 + 全大写命名
|
case SupportVariableCase.SPACE_UPPER_CASE: // 空格分隔 + 全大写命名
|
||||||
case SupportCase.DOT_UPPER_CASE: // 点分隔 + 全大写命名
|
case SupportVariableCase.DOT_UPPER_CASE: // 点分隔 + 全大写命名
|
||||||
transformedWords.push(word.toUpperCase());
|
transformedWords.push(word.toUpperCase());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
@ -1,9 +1,9 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { EOL } from "../type-definition/EOLType";
|
import { EOL } from "../../types/EOLType";
|
||||||
import { cyclicConvertCaseOrder } from "../type-definition/SupportCaseType";
|
import { cyclicConvertCaseOrder } from "./types/SupportVariableCaseType";
|
||||||
import { caseConversion } from "./conversion";
|
import { caseConversion } from "./conversion";
|
||||||
import { isStringArrayEqual, stringListArrayDuplicateRemoval } from './utils';
|
import { isStringArrayEqual, stringListArrayDuplicateRemoval } from '../../utils/utils';
|
||||||
import { getUserConfigurations } from './user-configuration';
|
import { getUserConfigurations } from '../../utils/user-configuration';
|
||||||
|
|
||||||
interface UserSelection {
|
interface UserSelection {
|
||||||
currentEol: EOL
|
currentEol: EOL
|
||||||
@ -66,7 +66,7 @@ function lazyConvert() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户配置
|
// 获取用户配置
|
||||||
const disableFormatList = getUserConfigurations('disableFormat');
|
const disableFormatList = getUserConfigurations<Array<string>>('disableFormat') || [];
|
||||||
|
|
||||||
const textList = userSelection.currentSelectionsText;
|
const textList = userSelection.currentSelectionsText;
|
||||||
// vscode.window.showInformationMessage('lazyConvert' + textList.join('\n'));
|
// vscode.window.showInformationMessage('lazyConvert' + textList.join('\n'));
|
@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* When support a new case, there's something we need to do.
|
* When support a new variable case, there's something we need to do.
|
||||||
*
|
*
|
||||||
* Code:
|
* Code:
|
||||||
* - Add type definition in below `SupportCase` enum and following array
|
* - Add type definition in below `SupportCase` enum and following array
|
||||||
* - Add `commands`, `menus`, `configuration` parts in [package.json] and [package-comment.jsonc]
|
* - Add `commands`, `menus`, `configuration` parts in [package.json] and [package-comment.jsonc]
|
||||||
* - Add main conversion logic in [src/main-code/conversion.ts]
|
* - Add main conversion logic in [src/core/variable-convert/conversion.ts]
|
||||||
*
|
*
|
||||||
* Test:
|
* Test:
|
||||||
* - Add test case type definition in [src/type-definition/TestCaseType.ts]
|
* - Add test case type definition in [src/test/types/TestCaseType.ts]
|
||||||
* - Add test case in [src/test/test-case.ts]
|
* - Add test case in [src/test/test-case.ts]
|
||||||
* - Add test code in [src/test/extension.test.ts]
|
* - Add test code in [src/test/extension.test.ts]
|
||||||
*
|
*
|
||||||
@ -15,7 +15,7 @@
|
|||||||
* - Modify `description` in [package.json] and [package-comment.jsonc]
|
* - Modify `description` in [package.json] and [package-comment.jsonc]
|
||||||
* - Add changes in [CHANGELOG.md] and [README.md]
|
* - Add changes in [CHANGELOG.md] and [README.md]
|
||||||
*/
|
*/
|
||||||
export enum SupportCase {
|
export enum SupportVariableCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小驼峰(驼峰)命名
|
* 小驼峰(驼峰)命名
|
||||||
@ -281,116 +281,116 @@ const keyword = {
|
|||||||
/**
|
/**
|
||||||
* 接管的变量转换命令
|
* 接管的变量转换命令
|
||||||
*/
|
*/
|
||||||
export const commands: Array<{ command: string; targetCase: SupportCase; settingsKey: string }> = [
|
export const commands: Array<{ command: string; targetCase: SupportVariableCase; settingsKey: string }> = [
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toCamelCase',
|
command: 'variable-conversion.toCamelCase',
|
||||||
targetCase: SupportCase.CAMEL_CASE,
|
targetCase: SupportVariableCase.CAMEL_CASE,
|
||||||
settingsKey: 'camel_case'
|
settingsKey: 'camel_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toPascalCase',
|
command: 'variable-conversion.toPascalCase',
|
||||||
targetCase: SupportCase.PASCAL_CASE,
|
targetCase: SupportVariableCase.PASCAL_CASE,
|
||||||
settingsKey: 'pascal_case'
|
settingsKey: 'pascal_case'
|
||||||
},
|
},
|
||||||
// +++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSnakeCase',
|
command: 'variable-conversion.toSnakeCase',
|
||||||
targetCase: SupportCase.SNAKE_CASE,
|
targetCase: SupportVariableCase.SNAKE_CASE,
|
||||||
settingsKey: 'snake_case'
|
settingsKey: 'snake_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSnakeUpperCase',
|
command: 'variable-conversion.toSnakeUpperCase',
|
||||||
targetCase: SupportCase.SNAKE_UPPER_CASE,
|
targetCase: SupportVariableCase.SNAKE_UPPER_CASE,
|
||||||
settingsKey: 'snake_upper_case'
|
settingsKey: 'snake_upper_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSnakePascalCase',
|
command: 'variable-conversion.toSnakePascalCase',
|
||||||
targetCase: SupportCase.SNAKE_PASCAL_CASE,
|
targetCase: SupportVariableCase.SNAKE_PASCAL_CASE,
|
||||||
settingsKey: 'snake_pascal_case'
|
settingsKey: 'snake_pascal_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSnakeCamelCase',
|
command: 'variable-conversion.toSnakeCamelCase',
|
||||||
targetCase: SupportCase.SNAKE_CAMEL_CASE,
|
targetCase: SupportVariableCase.SNAKE_CAMEL_CASE,
|
||||||
settingsKey: 'snake_camel_case'
|
settingsKey: 'snake_camel_case'
|
||||||
},
|
},
|
||||||
// +++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toKebabCase',
|
command: 'variable-conversion.toKebabCase',
|
||||||
targetCase: SupportCase.KEBAB_CASE,
|
targetCase: SupportVariableCase.KEBAB_CASE,
|
||||||
settingsKey: 'kebab_case'
|
settingsKey: 'kebab_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toKebabUpperCase',
|
command: 'variable-conversion.toKebabUpperCase',
|
||||||
targetCase: SupportCase.KEBAB_UPPER_CASE,
|
targetCase: SupportVariableCase.KEBAB_UPPER_CASE,
|
||||||
settingsKey: 'kebab_upper_case'
|
settingsKey: 'kebab_upper_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toKebabPascalCase',
|
command: 'variable-conversion.toKebabPascalCase',
|
||||||
targetCase: SupportCase.KEBAB_PASCAL_CASE,
|
targetCase: SupportVariableCase.KEBAB_PASCAL_CASE,
|
||||||
settingsKey: 'kebab_pascal_case'
|
settingsKey: 'kebab_pascal_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toKebabCamelCase',
|
command: 'variable-conversion.toKebabCamelCase',
|
||||||
targetCase: SupportCase.KEBAB_CAMEL_CASE,
|
targetCase: SupportVariableCase.KEBAB_CAMEL_CASE,
|
||||||
settingsKey: 'kebab_camel_case'
|
settingsKey: 'kebab_camel_case'
|
||||||
},
|
},
|
||||||
// +++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSpaceCase',
|
command: 'variable-conversion.toSpaceCase',
|
||||||
targetCase: SupportCase.SPACE_CASE,
|
targetCase: SupportVariableCase.SPACE_CASE,
|
||||||
settingsKey: 'space_case'
|
settingsKey: 'space_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSpaceUpperCase',
|
command: 'variable-conversion.toSpaceUpperCase',
|
||||||
targetCase: SupportCase.SPACE_UPPER_CASE,
|
targetCase: SupportVariableCase.SPACE_UPPER_CASE,
|
||||||
settingsKey: 'space_upper_case'
|
settingsKey: 'space_upper_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSpacePascalCase',
|
command: 'variable-conversion.toSpacePascalCase',
|
||||||
targetCase: SupportCase.SPACE_PASCAL_CASE,
|
targetCase: SupportVariableCase.SPACE_PASCAL_CASE,
|
||||||
settingsKey: 'space_pascal_case'
|
settingsKey: 'space_pascal_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toSpaceCamelCase',
|
command: 'variable-conversion.toSpaceCamelCase',
|
||||||
targetCase: SupportCase.SPACE_CAMEL_CASE,
|
targetCase: SupportVariableCase.SPACE_CAMEL_CASE,
|
||||||
settingsKey: 'space_camel_case'
|
settingsKey: 'space_camel_case'
|
||||||
},
|
},
|
||||||
// +++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toDotCase',
|
command: 'variable-conversion.toDotCase',
|
||||||
targetCase: SupportCase.DOT_CASE,
|
targetCase: SupportVariableCase.DOT_CASE,
|
||||||
settingsKey: 'dot_case'
|
settingsKey: 'dot_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toDotUpperCase',
|
command: 'variable-conversion.toDotUpperCase',
|
||||||
targetCase: SupportCase.DOT_UPPER_CASE,
|
targetCase: SupportVariableCase.DOT_UPPER_CASE,
|
||||||
settingsKey: 'dot_upper_case'
|
settingsKey: 'dot_upper_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toDotPascalCase',
|
command: 'variable-conversion.toDotPascalCase',
|
||||||
targetCase: SupportCase.DOT_PASCAL_CASE,
|
targetCase: SupportVariableCase.DOT_PASCAL_CASE,
|
||||||
settingsKey: 'dot_pascal_case'
|
settingsKey: 'dot_pascal_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toDotCamelCase',
|
command: 'variable-conversion.toDotCamelCase',
|
||||||
targetCase: SupportCase.DOT_CAMEL_CASE,
|
targetCase: SupportVariableCase.DOT_CAMEL_CASE,
|
||||||
settingsKey: 'dot_camel_case'
|
settingsKey: 'dot_camel_case'
|
||||||
},
|
},
|
||||||
// +++++++++++++++++++++++++++++++++++++++++++++++
|
// +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toLowerCase',
|
command: 'variable-conversion.toLowerCase',
|
||||||
targetCase: SupportCase.LOWER_CASE,
|
targetCase: SupportVariableCase.LOWER_CASE,
|
||||||
settingsKey: 'lower_case'
|
settingsKey: 'lower_case'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: 'variable-conversion.toUpperCase',
|
command: 'variable-conversion.toUpperCase',
|
||||||
targetCase: SupportCase.UPPER_CASE,
|
targetCase: SupportVariableCase.UPPER_CASE,
|
||||||
settingsKey: 'upper_case'
|
settingsKey: 'upper_case'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export interface QuickPickSupportCaseItem {
|
export interface QuickPickSupportCaseItem {
|
||||||
type: SupportCase,
|
type: SupportVariableCase,
|
||||||
name: string,
|
name: string,
|
||||||
shortName: string,
|
shortName: string,
|
||||||
keyword: string[],
|
keyword: string[],
|
||||||
@ -403,140 +403,140 @@ export interface QuickPickSupportCaseItem {
|
|||||||
*/
|
*/
|
||||||
export const quickPickSupportCases: Array<QuickPickSupportCaseItem> = [
|
export const quickPickSupportCases: Array<QuickPickSupportCaseItem> = [
|
||||||
{
|
{
|
||||||
type: SupportCase.CAMEL_CASE,
|
type: SupportVariableCase.CAMEL_CASE,
|
||||||
name: '小驼峰(驼峰)命名',
|
name: '小驼峰(驼峰)命名',
|
||||||
shortName: '小驼峰',
|
shortName: '小驼峰',
|
||||||
keyword: keyword.camel,
|
keyword: keyword.camel,
|
||||||
settingsKey: 'camel_case',
|
settingsKey: 'camel_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.PASCAL_CASE,
|
type: SupportVariableCase.PASCAL_CASE,
|
||||||
name: '大驼峰(帕斯卡)命名',
|
name: '大驼峰(帕斯卡)命名',
|
||||||
shortName: '帕斯卡',
|
shortName: '帕斯卡',
|
||||||
keyword: keyword.pascal,
|
keyword: keyword.pascal,
|
||||||
settingsKey: 'pascal_case',
|
settingsKey: 'pascal_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SNAKE_CASE,
|
type: SupportVariableCase.SNAKE_CASE,
|
||||||
name: '下划线(蛇形)命名',
|
name: '下划线(蛇形)命名',
|
||||||
shortName: '蛇形',
|
shortName: '蛇形',
|
||||||
keyword: [...keyword.snake, ...keyword.lower],
|
keyword: [...keyword.snake, ...keyword.lower],
|
||||||
settingsKey: 'snake_case',
|
settingsKey: 'snake_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SNAKE_CAMEL_CASE,
|
type: SupportVariableCase.SNAKE_CAMEL_CASE,
|
||||||
name: '下划线(蛇形) + 小驼峰(驼峰)命名',
|
name: '下划线(蛇形) + 小驼峰(驼峰)命名',
|
||||||
shortName: '蛇形驼峰',
|
shortName: '蛇形驼峰',
|
||||||
keyword: [...keyword.snake, ...keyword.camel],
|
keyword: [...keyword.snake, ...keyword.camel],
|
||||||
settingsKey: 'snake_camel_case',
|
settingsKey: 'snake_camel_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SNAKE_PASCAL_CASE,
|
type: SupportVariableCase.SNAKE_PASCAL_CASE,
|
||||||
name: '下划线(蛇形) + 大驼峰(帕斯卡)命名',
|
name: '下划线(蛇形) + 大驼峰(帕斯卡)命名',
|
||||||
shortName: '蛇形帕斯卡',
|
shortName: '蛇形帕斯卡',
|
||||||
keyword: [...keyword.snake, ...keyword.pascal],
|
keyword: [...keyword.snake, ...keyword.pascal],
|
||||||
settingsKey: 'snake_pascal_case',
|
settingsKey: 'snake_pascal_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SNAKE_UPPER_CASE,
|
type: SupportVariableCase.SNAKE_UPPER_CASE,
|
||||||
name: '下划线(蛇形) + 全大写命名',
|
name: '下划线(蛇形) + 全大写命名',
|
||||||
shortName: '蛇形大写',
|
shortName: '蛇形大写',
|
||||||
keyword: [...keyword.snake, ...keyword.upper],
|
keyword: [...keyword.snake, ...keyword.upper],
|
||||||
settingsKey: 'snake_upper_case',
|
settingsKey: 'snake_upper_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.KEBAB_CASE,
|
type: SupportVariableCase.KEBAB_CASE,
|
||||||
name: '中划线(连字符/脊柱式)命名',
|
name: '中划线(连字符/脊柱式)命名',
|
||||||
shortName: '脊柱',
|
shortName: '脊柱',
|
||||||
keyword: [...keyword.kebab, ...keyword.lower],
|
keyword: [...keyword.kebab, ...keyword.lower],
|
||||||
settingsKey: 'kebab_case',
|
settingsKey: 'kebab_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.KEBAB_CAMEL_CASE,
|
type: SupportVariableCase.KEBAB_CAMEL_CASE,
|
||||||
name: '中划线(连字符/脊柱式) + 小驼峰(驼峰)命名',
|
name: '中划线(连字符/脊柱式) + 小驼峰(驼峰)命名',
|
||||||
shortName: '脊柱驼峰',
|
shortName: '脊柱驼峰',
|
||||||
keyword: [...keyword.kebab, ...keyword.camel],
|
keyword: [...keyword.kebab, ...keyword.camel],
|
||||||
settingsKey: 'kebab_camel_case',
|
settingsKey: 'kebab_camel_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.KEBAB_PASCAL_CASE,
|
type: SupportVariableCase.KEBAB_PASCAL_CASE,
|
||||||
name: '中划线(连字符/脊柱式) + 大驼峰(帕斯卡)命名',
|
name: '中划线(连字符/脊柱式) + 大驼峰(帕斯卡)命名',
|
||||||
shortName: '脊柱帕斯卡',
|
shortName: '脊柱帕斯卡',
|
||||||
keyword: [...keyword.kebab, ...keyword.pascal],
|
keyword: [...keyword.kebab, ...keyword.pascal],
|
||||||
settingsKey: 'kebab_pascal_case',
|
settingsKey: 'kebab_pascal_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.KEBAB_UPPER_CASE,
|
type: SupportVariableCase.KEBAB_UPPER_CASE,
|
||||||
name: '中划线(连字符/脊柱式) + 全大写命名',
|
name: '中划线(连字符/脊柱式) + 全大写命名',
|
||||||
shortName: '脊柱大写',
|
shortName: '脊柱大写',
|
||||||
keyword: [...keyword.kebab, ...keyword.upper],
|
keyword: [...keyword.kebab, ...keyword.upper],
|
||||||
settingsKey: 'kebab_upper_case',
|
settingsKey: 'kebab_upper_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SPACE_CASE,
|
type: SupportVariableCase.SPACE_CASE,
|
||||||
name: '空格分隔命名',
|
name: '空格分隔命名',
|
||||||
shortName: '脊柱',
|
shortName: '脊柱',
|
||||||
keyword: [...keyword.space, ...keyword.lower],
|
keyword: [...keyword.space, ...keyword.lower],
|
||||||
settingsKey: 'space_case',
|
settingsKey: 'space_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SPACE_CAMEL_CASE,
|
type: SupportVariableCase.SPACE_CAMEL_CASE,
|
||||||
name: '空格分隔 + 小驼峰(驼峰)命名',
|
name: '空格分隔 + 小驼峰(驼峰)命名',
|
||||||
shortName: '脊柱驼峰',
|
shortName: '脊柱驼峰',
|
||||||
keyword: [...keyword.space, ...keyword.camel],
|
keyword: [...keyword.space, ...keyword.camel],
|
||||||
settingsKey: 'space_camel_case',
|
settingsKey: 'space_camel_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SPACE_PASCAL_CASE,
|
type: SupportVariableCase.SPACE_PASCAL_CASE,
|
||||||
name: '空格分隔 + 大驼峰(帕斯卡)命名',
|
name: '空格分隔 + 大驼峰(帕斯卡)命名',
|
||||||
shortName: '脊柱帕斯卡',
|
shortName: '脊柱帕斯卡',
|
||||||
keyword: [...keyword.space, ...keyword.pascal],
|
keyword: [...keyword.space, ...keyword.pascal],
|
||||||
settingsKey: 'space_pascal_case',
|
settingsKey: 'space_pascal_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.SPACE_UPPER_CASE,
|
type: SupportVariableCase.SPACE_UPPER_CASE,
|
||||||
name: '空格分隔 + 全大写命名',
|
name: '空格分隔 + 全大写命名',
|
||||||
shortName: '脊柱大写',
|
shortName: '脊柱大写',
|
||||||
keyword: [...keyword.space, ...keyword.upper],
|
keyword: [...keyword.space, ...keyword.upper],
|
||||||
settingsKey: 'space_upper_case',
|
settingsKey: 'space_upper_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.DOT_CASE,
|
type: SupportVariableCase.DOT_CASE,
|
||||||
name: '点分隔命名',
|
name: '点分隔命名',
|
||||||
shortName: '脊柱',
|
shortName: '脊柱',
|
||||||
keyword: [...keyword.dot, ...keyword.lower],
|
keyword: [...keyword.dot, ...keyword.lower],
|
||||||
settingsKey: 'dot_case',
|
settingsKey: 'dot_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.DOT_CAMEL_CASE,
|
type: SupportVariableCase.DOT_CAMEL_CASE,
|
||||||
name: '点分隔 + 小驼峰(驼峰)命名',
|
name: '点分隔 + 小驼峰(驼峰)命名',
|
||||||
shortName: '脊柱驼峰',
|
shortName: '脊柱驼峰',
|
||||||
keyword: [...keyword.dot, ...keyword.camel],
|
keyword: [...keyword.dot, ...keyword.camel],
|
||||||
settingsKey: 'dot_camel_case',
|
settingsKey: 'dot_camel_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.DOT_PASCAL_CASE,
|
type: SupportVariableCase.DOT_PASCAL_CASE,
|
||||||
name: '点分隔 + 大驼峰(帕斯卡)命名',
|
name: '点分隔 + 大驼峰(帕斯卡)命名',
|
||||||
shortName: '脊柱帕斯卡',
|
shortName: '脊柱帕斯卡',
|
||||||
keyword: [...keyword.dot, ...keyword.pascal],
|
keyword: [...keyword.dot, ...keyword.pascal],
|
||||||
settingsKey: 'dot_pascal_case',
|
settingsKey: 'dot_pascal_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.DOT_UPPER_CASE,
|
type: SupportVariableCase.DOT_UPPER_CASE,
|
||||||
name: '点分隔 + 全大写命名',
|
name: '点分隔 + 全大写命名',
|
||||||
shortName: '脊柱大写',
|
shortName: '脊柱大写',
|
||||||
keyword: [...keyword.dot, ...keyword.upper],
|
keyword: [...keyword.dot, ...keyword.upper],
|
||||||
settingsKey: 'dot_upper_case',
|
settingsKey: 'dot_upper_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.LOWER_CASE,
|
type: SupportVariableCase.LOWER_CASE,
|
||||||
name: '全小写',
|
name: '全小写',
|
||||||
shortName: '小写',
|
shortName: '小写',
|
||||||
keyword: keyword.lower,
|
keyword: keyword.lower,
|
||||||
settingsKey: 'lower_case',
|
settingsKey: 'lower_case',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportCase.UPPER_CASE,
|
type: SupportVariableCase.UPPER_CASE,
|
||||||
name: '全大写',
|
name: '全大写',
|
||||||
shortName: '大写',
|
shortName: '大写',
|
||||||
keyword: keyword.upper,
|
keyword: keyword.upper,
|
||||||
@ -545,7 +545,7 @@ export const quickPickSupportCases: Array<QuickPickSupportCaseItem> = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export interface CyclicConvertCaseOrderItem {
|
export interface CyclicConvertCaseOrderItem {
|
||||||
type: SupportCase,
|
type: SupportVariableCase,
|
||||||
settingsKey: string,
|
settingsKey: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,28 +554,28 @@ export interface CyclicConvertCaseOrderItem {
|
|||||||
* @since 2024-04-08
|
* @since 2024-04-08
|
||||||
*/
|
*/
|
||||||
export const cyclicConvertCaseOrder: Array<CyclicConvertCaseOrderItem> = [
|
export const cyclicConvertCaseOrder: Array<CyclicConvertCaseOrderItem> = [
|
||||||
{ type: SupportCase.CAMEL_CASE, settingsKey: 'camel_case' },
|
{ type: SupportVariableCase.CAMEL_CASE, settingsKey: 'camel_case' },
|
||||||
{ type: SupportCase.SNAKE_CASE, settingsKey: 'snake_case' },
|
{ type: SupportVariableCase.SNAKE_CASE, settingsKey: 'snake_case' },
|
||||||
{ type: SupportCase.PASCAL_CASE, settingsKey: 'pascal_case' },
|
{ type: SupportVariableCase.PASCAL_CASE, settingsKey: 'pascal_case' },
|
||||||
{ type: SupportCase.KEBAB_CASE, settingsKey: 'kebab_case' },
|
{ type: SupportVariableCase.KEBAB_CASE, settingsKey: 'kebab_case' },
|
||||||
{ type: SupportCase.SPACE_CASE, settingsKey: 'space_case' },
|
{ type: SupportVariableCase.SPACE_CASE, settingsKey: 'space_case' },
|
||||||
{ type: SupportCase.DOT_CASE, settingsKey: 'dot_case' },
|
{ type: SupportVariableCase.DOT_CASE, settingsKey: 'dot_case' },
|
||||||
|
|
||||||
{ type: SupportCase.SNAKE_UPPER_CASE, settingsKey: 'snake_upper_case' },
|
{ type: SupportVariableCase.SNAKE_UPPER_CASE, settingsKey: 'snake_upper_case' },
|
||||||
{ type: SupportCase.KEBAB_UPPER_CASE, settingsKey: 'kebab_upper_case' },
|
{ type: SupportVariableCase.KEBAB_UPPER_CASE, settingsKey: 'kebab_upper_case' },
|
||||||
{ type: SupportCase.SPACE_UPPER_CASE, settingsKey: 'space_upper_case' },
|
{ type: SupportVariableCase.SPACE_UPPER_CASE, settingsKey: 'space_upper_case' },
|
||||||
{ type: SupportCase.DOT_UPPER_CASE, settingsKey: 'dot_upper_case' },
|
{ type: SupportVariableCase.DOT_UPPER_CASE, settingsKey: 'dot_upper_case' },
|
||||||
|
|
||||||
{ type: SupportCase.SNAKE_PASCAL_CASE, settingsKey: 'snake_pascal_case' },
|
{ type: SupportVariableCase.SNAKE_PASCAL_CASE, settingsKey: 'snake_pascal_case' },
|
||||||
{ type: SupportCase.KEBAB_PASCAL_CASE, settingsKey: 'kebab_pascal_case' },
|
{ type: SupportVariableCase.KEBAB_PASCAL_CASE, settingsKey: 'kebab_pascal_case' },
|
||||||
{ type: SupportCase.SPACE_PASCAL_CASE, settingsKey: 'space_pascal_case' },
|
{ type: SupportVariableCase.SPACE_PASCAL_CASE, settingsKey: 'space_pascal_case' },
|
||||||
{ type: SupportCase.DOT_PASCAL_CASE, settingsKey: 'dot_pascal_case' },
|
{ type: SupportVariableCase.DOT_PASCAL_CASE, settingsKey: 'dot_pascal_case' },
|
||||||
|
|
||||||
{ type: SupportCase.SNAKE_CAMEL_CASE, settingsKey: 'snake_camel_case' },
|
{ type: SupportVariableCase.SNAKE_CAMEL_CASE, settingsKey: 'snake_camel_case' },
|
||||||
{ type: SupportCase.KEBAB_CAMEL_CASE, settingsKey: 'kebab_camel_case' },
|
{ type: SupportVariableCase.KEBAB_CAMEL_CASE, settingsKey: 'kebab_camel_case' },
|
||||||
{ type: SupportCase.SPACE_CAMEL_CASE, settingsKey: 'space_camel_case' },
|
{ type: SupportVariableCase.SPACE_CAMEL_CASE, settingsKey: 'space_camel_case' },
|
||||||
{ type: SupportCase.DOT_CAMEL_CASE, settingsKey: 'dot_camel_case' },
|
{ type: SupportVariableCase.DOT_CAMEL_CASE, settingsKey: 'dot_camel_case' },
|
||||||
|
|
||||||
{ type: SupportCase.LOWER_CASE, settingsKey: 'lower_case' },
|
{ type: SupportVariableCase.LOWER_CASE, settingsKey: 'lower_case' },
|
||||||
{ type: SupportCase.UPPER_CASE, settingsKey: 'upper_case' },
|
{ type: SupportVariableCase.UPPER_CASE, settingsKey: 'upper_case' },
|
||||||
];
|
];
|
@ -1,36 +0,0 @@
|
|||||||
import * as vscode from 'vscode';
|
|
||||||
|
|
||||||
// docs: https://code.visualstudio.com/api/references/vscode-api#StatusBarItem
|
|
||||||
|
|
||||||
let statusBar: vscode.StatusBarItem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建状态栏按钮
|
|
||||||
*
|
|
||||||
* @since 2024-04-07
|
|
||||||
*/
|
|
||||||
export function createStatusBarItem() {
|
|
||||||
statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
|
||||||
statusBar.text = '$(find-replace)变量转换';
|
|
||||||
statusBar.command = 'variable-conversion.convertCase';
|
|
||||||
// statusBar.color = 'red';
|
|
||||||
// statusBar.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否展示状态栏按钮
|
|
||||||
*
|
|
||||||
* @since 2024-04-07
|
|
||||||
*/
|
|
||||||
export function updateStatusBarItemVisable(selectTextLength: number) {
|
|
||||||
if (!statusBar) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let editor = vscode.window.activeTextEditor;
|
|
||||||
if (editor && selectTextLength > 0) {
|
|
||||||
statusBar.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
statusBar.hide();
|
|
||||||
}
|
|
116
src/extension.ts
116
src/extension.ts
@ -1,13 +1,33 @@
|
|||||||
// The module 'vscode' contains the VS Code extensibility API
|
/**
|
||||||
// Import the module and reference it with the alias vscode in your code below
|
* @file extension.ts
|
||||||
|
* @description 该文件包含了 VS Code 插件的主要扩展逻辑,包括命令注册、菜单配置和编辑器事件监听等。
|
||||||
|
* @author coder-xiaomo
|
||||||
|
* @version 1.0.0
|
||||||
|
* @license MIT
|
||||||
|
*
|
||||||
|
* 本文件是插件的核心文件,负责扩展命令的注册以及编辑器中各种事件的处理。通过监听编辑器的选择状态,
|
||||||
|
* 动态更新命令行为。插件在启动时会初始化必要的命令,并根据编辑器状态决定是否启用相关功能。
|
||||||
|
*
|
||||||
|
* @see https://code.visualstudio.com/api
|
||||||
|
*/
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import handleEditorReplace from './extension-handler/editor-submenu-handler';
|
|
||||||
import { handleQuickPick } from './extension-handler/quick-pick-handler';
|
// Variable Convert
|
||||||
import { commands } from './type-definition/SupportCaseType';
|
import handleEditorReplaceVariable from './handler/variable-convert/editor-submenu-handler';
|
||||||
import { createStatusBarItem, updateStatusBarItemVisable } from './extension-handler/status-bar-handler';
|
import { handleQuickPick as handleQuickPickVariable } from './handler/variable-convert/quick-pick-handler';
|
||||||
import * as CyclicConversion from './main-code/cyclic-conversion';
|
import { commands as variableCommands } from './core/variable-convert/types/SupportVariableCaseType';
|
||||||
import { EOL } from './type-definition/EOLType';
|
import * as CyclicConversionVariable from './core/variable-convert/cyclic-conversion';
|
||||||
import { getUserConfigurations } from './main-code/user-configuration';
|
|
||||||
|
// Path Convert
|
||||||
|
import handleEditorReplacePath from './handler/path-convert/editor-submenu-handler';
|
||||||
|
import { handleQuickPick as handleQuickPickPath } from './handler/path-convert/quick-pick-handler';
|
||||||
|
import { commands as pathCommands } from './core/path-convert/types/SupportPathFormatType';
|
||||||
|
import * as CyclicConversionPath from './core/path-convert/cyclic-conversion';
|
||||||
|
|
||||||
|
// Common
|
||||||
|
import { createStatusBarItem, updateStatusBarItemVisable } from './handler/status-bar-handler';
|
||||||
|
import { EOL } from './types/EOLType';
|
||||||
|
import { getUserConfigurations } from './utils/user-configuration';
|
||||||
|
|
||||||
// This method is called when your extension is activated
|
// This method is called when your extension is activated
|
||||||
// Your extension is activated the very first time the command is executed
|
// Your extension is activated the very first time the command is executed
|
||||||
@ -44,18 +64,27 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
|
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
|
||||||
// 获取用户配置
|
// 获取用户配置
|
||||||
const disableFormatList = getUserConfigurations('disableFormat');
|
const disableFormatList = getUserConfigurations<Array<string>>('disableFormat') || [];
|
||||||
|
const disablePathFormatList = getUserConfigurations<Array<string>>('disablePathFormat') || [];
|
||||||
// 更新右键菜单每一项是否展示
|
// 更新右键菜单每一项是否展示
|
||||||
for (const { settingsKey } of commands) {
|
// 变量转换右键菜单visible 2024.07.29
|
||||||
|
for (const { settingsKey } of variableCommands) {
|
||||||
vscode.commands.executeCommand('setContext', '_isHideSubMenuItem_' + settingsKey, disableFormatList.includes(settingsKey));
|
vscode.commands.executeCommand('setContext', '_isHideSubMenuItem_' + settingsKey, disableFormatList.includes(settingsKey));
|
||||||
}
|
}
|
||||||
|
// 路径转换右键菜单visible 2024.12.14
|
||||||
|
for (const { settingsKey } of pathCommands) {
|
||||||
|
vscode.commands.executeCommand('setContext', '_isHideSubMenuItem_' + settingsKey, disablePathFormatList.includes(settingsKey));
|
||||||
|
}
|
||||||
|
|
||||||
// 判断是否展示状态栏按钮
|
// 判断是否展示状态栏按钮
|
||||||
updateStatusBarItemVisable(selectTextLength);
|
updateStatusBarItemVisable(selectTextLength);
|
||||||
|
|
||||||
// 循环转换:记录当前选中内容,并且进行转换
|
// 循环转换:记录当前选中内容,并且进行转换
|
||||||
let eol: EOL = textEditor.document.eol === vscode.EndOfLine.CRLF ? '\r\n' : '\n';
|
let eol: EOL = textEditor.document.eol === vscode.EndOfLine.CRLF ? '\r\n' : '\n';
|
||||||
CyclicConversion.onUserSelectionUpdated(selections, textList, eol);
|
// 变量循环转换 2024.04.09
|
||||||
|
CyclicConversionVariable.onUserSelectionUpdated(selections, textList, eol);
|
||||||
|
// 路径循环转换 2024.12.14
|
||||||
|
CyclicConversionPath.onUserSelectionUpdated(selections, textList, eol);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 创建状态栏按钮
|
// 创建状态栏按钮
|
||||||
@ -95,29 +124,70 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
onTextEditorSelectionChangeCallback(editor, editor.selections);
|
onTextEditorSelectionChangeCallback(editor, editor.selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变量转换
|
||||||
|
*
|
||||||
|
* @since 2024-04
|
||||||
|
*/
|
||||||
|
|
||||||
// 逐一注册右键菜单-子菜单项 command
|
// 逐一注册右键菜单-子菜单项 command
|
||||||
for (const { command, targetCase } of commands) {
|
for (const { command, targetCase } of variableCommands) {
|
||||||
let disposable = vscode.commands.registerCommand(command, () => {
|
let disposable = vscode.commands.registerCommand(command, () => {
|
||||||
handleEditorReplace(targetCase);
|
// 变量转换右键菜单 2024.04.05
|
||||||
|
handleEditorReplaceVariable(targetCase);
|
||||||
});
|
});
|
||||||
context.subscriptions.push(disposable);
|
context.subscriptions.push(disposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册变量转换 command 状态栏/快捷键/右键[变量转换]菜单均有用到
|
// 注册变量转换 command 状态栏/快捷键/右键[变量转换]菜单均有用到
|
||||||
let convertCaseDisposable = vscode.commands.registerCommand('variable-conversion.convertCase', handleQuickPick);
|
let convertCaseDisposable = vscode.commands.registerCommand('variable-conversion.convertCase', handleQuickPickVariable);
|
||||||
context.subscriptions.push(convertCaseDisposable);
|
context.subscriptions.push(convertCaseDisposable);
|
||||||
|
|
||||||
// 注册循环转换 command
|
// 注册循环转换 command
|
||||||
let disposableLoopConversionPrev = vscode.commands.registerCommand('variable-conversion.cyclicConvertCase.previous', ({ arrowKey }) => {
|
let loopConvertCasePrevDisposable = vscode.commands.registerCommand('variable-conversion.cyclicConvertCase.previous', ({ arrowKey }) => {
|
||||||
console.log('variable-conversion.convertCase', arrowKey);
|
console.log('variable-conversion.cyclicConvertCase.previous', arrowKey);
|
||||||
CyclicConversion.previousOne();
|
CyclicConversionVariable.previousOne();
|
||||||
});
|
});
|
||||||
context.subscriptions.push(disposableLoopConversionPrev);
|
context.subscriptions.push(loopConvertCasePrevDisposable);
|
||||||
let disposableLoopConversionNext = vscode.commands.registerCommand('variable-conversion.cyclicConvertCase.next', ({ arrowKey }) => {
|
let loopConvertCaseNextDisposable = vscode.commands.registerCommand('variable-conversion.cyclicConvertCase.next', ({ arrowKey }) => {
|
||||||
console.log('variable-conversion.convertCase', arrowKey);
|
console.log('variable-conversion.cyclicConvertCase.next', arrowKey);
|
||||||
CyclicConversion.nextOne();
|
CyclicConversionVariable.nextOne();
|
||||||
});
|
});
|
||||||
context.subscriptions.push(disposableLoopConversionNext);
|
context.subscriptions.push(loopConvertCaseNextDisposable);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路径转换
|
||||||
|
* issue: #3 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/3
|
||||||
|
*
|
||||||
|
* @since 2024-12
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 逐一注册右键菜单-子菜单项 command
|
||||||
|
for (const { command, targetCase } of pathCommands) {
|
||||||
|
let disposable = vscode.commands.registerCommand(command, () => {
|
||||||
|
// 变量转换右键菜单 2024.12.14
|
||||||
|
handleEditorReplacePath(targetCase);
|
||||||
|
});
|
||||||
|
context.subscriptions.push(disposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册路径转换 command 状态栏/快捷键/右键[路径转换]菜单均有用到
|
||||||
|
let convertPathDisposable = vscode.commands.registerCommand('variable-conversion.convertPath', handleQuickPickPath);
|
||||||
|
context.subscriptions.push(convertPathDisposable);
|
||||||
|
|
||||||
|
// 注册循环转换 command
|
||||||
|
let loopConvertPathPrevDisposable = vscode.commands.registerCommand('variable-conversion.cyclicConvertPath.previous', ({ direction }) => {
|
||||||
|
console.log('variable-conversion.cyclicConvertPath.previous', direction);
|
||||||
|
CyclicConversionPath.previousOne();
|
||||||
|
});
|
||||||
|
context.subscriptions.push(loopConvertPathPrevDisposable);
|
||||||
|
let loopConvertPathNextDisposable = vscode.commands.registerCommand('variable-conversion.cyclicConvertPath.next', ({ direction }) => {
|
||||||
|
console.log('variable-conversion.cyclicConvertPath.next', direction);
|
||||||
|
CyclicConversionPath.nextOne();
|
||||||
|
});
|
||||||
|
context.subscriptions.push(loopConvertPathNextDisposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is called when your extension is deactivated
|
// This method is called when your extension is deactivated
|
||||||
|
59
src/handler/path-convert/editor-submenu-handler.ts
Normal file
59
src/handler/path-convert/editor-submenu-handler.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { EOL } from '../../types/EOLType';
|
||||||
|
import { pathConversion } from '../../core/path-convert/conversion';
|
||||||
|
import { SupportPathFormat } from '../../core/path-convert/types/SupportPathFormatType';
|
||||||
|
import { isStringArrayEqual } from '../../utils/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑器右键菜单
|
||||||
|
*
|
||||||
|
* @param convertFunction
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const handleEditorReplace = (targetCase: SupportPathFormat) => {
|
||||||
|
// 获取当前编辑器
|
||||||
|
let editor = vscode.window.activeTextEditor;
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = editor.document;
|
||||||
|
const selections = editor.selections;
|
||||||
|
const eol: EOL = document.eol === vscode.EndOfLine.CRLF ? '\r\n' : '\n';
|
||||||
|
|
||||||
|
// 获取选中的文本
|
||||||
|
const textList = selections.map(selection => document.getText(selection));
|
||||||
|
|
||||||
|
if (textList.filter(text => text.length > 0).length === 0) {
|
||||||
|
vscode.window.showInformationMessage('请选择需要转换的路径后重试\nPlease select the path you want to convert and try again.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换文本
|
||||||
|
const convertedList = textList.map(text => pathConversion(targetCase, text, eol));
|
||||||
|
console.log('convertedList', convertedList);
|
||||||
|
|
||||||
|
// 无法转换时,跳过转换
|
||||||
|
if (convertedList.filter(converted => converted !== undefined).length === 0) {
|
||||||
|
console.log('converted text is undefined, skip replace contents.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当转换后文本与转换前相同时,跳过转换,避免形成 Ctrl + Z 撤销历史记录
|
||||||
|
if (isStringArrayEqual(convertedList, textList)) {
|
||||||
|
console.log('selection text is same to converted text, skip replace contents.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换文本
|
||||||
|
console.log('replace selection text', textList, 'to', convertedList);
|
||||||
|
editor.edit(editBuilder => {
|
||||||
|
for (let i = 0; i < selections.length; i++) {
|
||||||
|
const selection = selections[i];
|
||||||
|
const converted = convertedList[i];
|
||||||
|
editBuilder.replace(selection, converted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default handleEditorReplace;
|
144
src/handler/path-convert/quick-pick-handler.ts
Normal file
144
src/handler/path-convert/quick-pick-handler.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
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 { EOL } from '../../types/EOLType';
|
||||||
|
import { pathConversion } from '../../core/path-convert/conversion';
|
||||||
|
import { isStringArrayEqual } from '../../utils/utils';
|
||||||
|
import { getUserConfigurations } from '../../utils/user-configuration';
|
||||||
|
|
||||||
|
const QuickPickLabelMaxLength = 60;
|
||||||
|
|
||||||
|
interface RecommendItem {
|
||||||
|
conversionText: Array<string>
|
||||||
|
transforTo: string[]
|
||||||
|
keyword: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹出的提示
|
||||||
|
*
|
||||||
|
* @since 2024-12-14
|
||||||
|
*/
|
||||||
|
function generateOptionsBasedOnText(textList: string[], eol: EOL, enabledQuickPickSupportCases: Array<QuickPickSupportCaseItem>): Array<QuickPickItemEx> {
|
||||||
|
// Cut text 切割文本
|
||||||
|
const resultsList: Array<TransformTextResult[]> = transformMutliSelectionText(textList);
|
||||||
|
|
||||||
|
const mergeResultList: Array<RecommendItem> = [];
|
||||||
|
for (const quickPick of enabledQuickPickSupportCases) {
|
||||||
|
const conversionResults: Array<string> = [];
|
||||||
|
for (let i = 0; i < textList.length; i++) {
|
||||||
|
const text = textList[i];
|
||||||
|
const results = resultsList[i];
|
||||||
|
const conversionResult: string = pathConversion(quickPick.type, text, eol, results);
|
||||||
|
conversionResults.push(conversionResult);
|
||||||
|
}
|
||||||
|
const recommendItem: RecommendItem | undefined = mergeResultList.find(item => isStringArrayEqual(item.conversionText, conversionResults));
|
||||||
|
|
||||||
|
if (recommendItem === undefined) {
|
||||||
|
let item: RecommendItem = {
|
||||||
|
conversionText: conversionResults,
|
||||||
|
transforTo: [quickPick.shortName], // quickPick.name
|
||||||
|
keyword: quickPick.keyword,
|
||||||
|
};
|
||||||
|
mergeResultList.push(item);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
recommendItem.transforTo.push(quickPick.shortName); // quickPick.name
|
||||||
|
recommendItem.keyword = Array.from(new Set(recommendItem.keyword.concat(quickPick.keyword))); // 关键词去重
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据文本生成选项的逻辑
|
||||||
|
const quickPickList = [];
|
||||||
|
|
||||||
|
for (const recommendItem of mergeResultList) {
|
||||||
|
if (isStringArrayEqual(textList, recommendItem.conversionText)) {
|
||||||
|
continue; // 如果转换后与转换前相同,那么跳过这一项
|
||||||
|
}
|
||||||
|
const conversionTextForDisplay = recommendItem.conversionText.join(' ').replace(/\s+/g, " "); // 友好展示 将连续空格 \n \t 等替换为单一空格
|
||||||
|
let quickPickItem: QuickPickItemEx = {
|
||||||
|
label: conversionTextForDisplay.length >= QuickPickLabelMaxLength
|
||||||
|
? (conversionTextForDisplay.substring(0, QuickPickLabelMaxLength - 3) + '...')
|
||||||
|
: conversionTextForDisplay,
|
||||||
|
description: `转换为 ${recommendItem.transforTo.join(' / ')}`,
|
||||||
|
detail: `关键词 ${recommendItem.keyword.join(' ')}`,
|
||||||
|
value: recommendItem.conversionText,
|
||||||
|
};
|
||||||
|
quickPickList.push(quickPickItem);
|
||||||
|
}
|
||||||
|
return quickPickList;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleQuickPick() {
|
||||||
|
// 获取当前编辑器
|
||||||
|
let editor = vscode.window.activeTextEditor;
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = editor.document;
|
||||||
|
const selections = editor.selections;
|
||||||
|
const eol: EOL = document.eol === vscode.EndOfLine.CRLF ? '\r\n' : '\n';
|
||||||
|
|
||||||
|
// 获取选中的文本
|
||||||
|
const textList = selections.map(selection => document.getText(selection));
|
||||||
|
|
||||||
|
if (textList.filter(text => text.length > 0).length === 0) {
|
||||||
|
vscode.window.showInformationMessage('请选择需要转换的路径后重试\nPlease select the path you want to convert and try again.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// 获取用户配置
|
||||||
|
const disablePathFormatList = getUserConfigurations<Array<string>>('disablePathFormat') || [];
|
||||||
|
// 排除禁用的选项
|
||||||
|
const enabledQuickPickSupportCases = [];
|
||||||
|
for (const quickPick of quickPickSupportCases) {
|
||||||
|
if (disablePathFormatList.includes(quickPick.settingsKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
enabledQuickPickSupportCases.push(quickPick);
|
||||||
|
}
|
||||||
|
if (enabledQuickPickSupportCases.length === 0) {
|
||||||
|
vscode.window.showInformationMessage('所有格式都已被配置为禁用,请修改配置 `variable-conversion.disablePathFormat` 后重试\nAll formats have been configured to disable. Modify the `variable-conversion.disablePathFormat` configuration and try again.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基于选中的文本生成选项
|
||||||
|
const options = generateOptionsBasedOnText(textList, eol, enabledQuickPickSupportCases);
|
||||||
|
if (options.length === 0) {
|
||||||
|
vscode.window.showInformationMessage('所选内容暂无可选转换,请尝试重新选择\nNo conversion candidates are available for the selected content, please try to select another text.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示推荐项列表
|
||||||
|
vscode.window.showQuickPick(options, {
|
||||||
|
matchOnDetail: true,
|
||||||
|
title: '请选择需要转换的路径风格...',
|
||||||
|
placeHolder: '点击转换,输入关键词可快速选择'
|
||||||
|
}).then(pickItem => {
|
||||||
|
if (!editor || pickItem === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertedList = pickItem.value;
|
||||||
|
|
||||||
|
// 当转换后文本与转换前相同时,跳过转换,避免形成 Ctrl + Z 撤销历史记录
|
||||||
|
if (isStringArrayEqual(convertedList, textList)) {
|
||||||
|
console.log('selection text is same to converted text, skip replace contents.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换文本
|
||||||
|
console.log('replace selection text', textList, 'to', convertedList);
|
||||||
|
editor.edit(editBuilder => {
|
||||||
|
for (let i = 0; i < selections.length; i++) {
|
||||||
|
const selection = selections[i];
|
||||||
|
const converted = convertedList[i];
|
||||||
|
editBuilder.replace(selection, converted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
54
src/handler/status-bar-handler.ts
Normal file
54
src/handler/status-bar-handler.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
// docs: https://code.visualstudio.com/api/references/vscode-api#StatusBarItem
|
||||||
|
|
||||||
|
let statusBarItemList: Array<vscode.StatusBarItem> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建状态栏按钮
|
||||||
|
*
|
||||||
|
* @since 2024-04-07
|
||||||
|
*/
|
||||||
|
export function createStatusBarItem() {
|
||||||
|
// 变量转换状态栏 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
|
||||||
|
statusBarItem.text = '$(find-replace)变量转换';
|
||||||
|
statusBarItem.command = 'variable-conversion.convertCase';
|
||||||
|
// statusBarItem.color = 'red';
|
||||||
|
// statusBarItem.show();
|
||||||
|
return statusBarItem;
|
||||||
|
};
|
||||||
|
// 路径转换状态栏 2024.12.14
|
||||||
|
const createPathConvertStatusBarItem = () => {
|
||||||
|
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||||
|
statusBarItem.text = '$(sync-ignored)路径转换'; // italic symbol-null
|
||||||
|
statusBarItem.command = 'variable-conversion.convertPath';
|
||||||
|
statusBarItemList.push(statusBarItem);
|
||||||
|
return statusBarItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
statusBarItemList.push(
|
||||||
|
createVariableConvertStatusBarItem(),
|
||||||
|
createPathConvertStatusBarItem(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否展示状态栏按钮
|
||||||
|
*
|
||||||
|
* @since 2024-04-07
|
||||||
|
*/
|
||||||
|
export function updateStatusBarItemVisable(selectTextLength: number) {
|
||||||
|
let editor = vscode.window.activeTextEditor;
|
||||||
|
if (editor && selectTextLength > 0) {
|
||||||
|
statusBarItemList.forEach(statusBarItem => {
|
||||||
|
statusBarItem.show();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statusBarItemList.forEach(statusBarItem => {
|
||||||
|
statusBarItem.hide();
|
||||||
|
});
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { EOL } from '../type-definition/EOLType';
|
import { EOL } from '../../types/EOLType';
|
||||||
import { caseConversion } from '../main-code/conversion';
|
import { caseConversion } from '../../core/variable-convert/conversion';
|
||||||
import { SupportCase } from '../type-definition/SupportCaseType';
|
import { SupportVariableCase } from '../../core/variable-convert/types/SupportVariableCaseType';
|
||||||
import { isStringArrayEqual } from '../main-code/utils';
|
import { isStringArrayEqual } from '../../utils/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑器右键菜单
|
* 编辑器右键菜单
|
||||||
@ -10,7 +10,7 @@ import { isStringArrayEqual } from '../main-code/utils';
|
|||||||
* @param convertFunction
|
* @param convertFunction
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const handleEditorReplace = (targetCase: SupportCase) => {
|
const handleEditorReplace = (targetCase: SupportVariableCase) => {
|
||||||
// 获取当前编辑器
|
// 获取当前编辑器
|
||||||
let editor = vscode.window.activeTextEditor;
|
let editor = vscode.window.activeTextEditor;
|
||||||
if (!editor) {
|
if (!editor) {
|
@ -1,12 +1,12 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import QuickPickItemEx from "../type-definition/QuickPickItemExType";
|
import QuickPickItemEx from "../types/QuickPickItemExType";
|
||||||
import { QuickPickSupportCaseItem, quickPickSupportCases } from '../type-definition/SupportCaseType';
|
import { QuickPickSupportCaseItem, quickPickSupportCases } from '../../core/variable-convert/types/SupportVariableCaseType';
|
||||||
import { TransformTextResult } from '../type-definition/TransformTextResultType';
|
import { TransformTextResult } from '../../types/TransformTextResultType';
|
||||||
import { transformMutliSelectionText } from '../main-code/transform';
|
import { transformMutliSelectionText } from '../../utils/transform';
|
||||||
import { EOL } from '../type-definition/EOLType';
|
import { EOL } from '../../types/EOLType';
|
||||||
import { caseConversion } from '../main-code/conversion';
|
import { caseConversion } from '../../core/variable-convert/conversion';
|
||||||
import { isStringArrayEqual } from '../main-code/utils';
|
import { isStringArrayEqual } from '../../utils/utils';
|
||||||
import { getUserConfigurations } from '../main-code/user-configuration';
|
import { getUserConfigurations } from '../../utils/user-configuration';
|
||||||
|
|
||||||
const QuickPickLabelMaxLength = 60;
|
const QuickPickLabelMaxLength = 60;
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ export function handleQuickPick() {
|
|||||||
|
|
||||||
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
|
// issue: #1 https://github.com/coder-xiaomo/variable-conversion-vscode-extension/issues/1
|
||||||
// 获取用户配置
|
// 获取用户配置
|
||||||
const disableFormatList = getUserConfigurations('disableFormat');
|
const disableFormatList = getUserConfigurations<Array<string>>('disableFormat') || [];
|
||||||
// 排除禁用的选项
|
// 排除禁用的选项
|
||||||
const enabledQuickPickSupportCases = [];
|
const enabledQuickPickSupportCases = [];
|
||||||
for (const quickPick of quickPickSupportCases) {
|
for (const quickPick of quickPickSupportCases) {
|
||||||
@ -122,7 +122,7 @@ export function handleQuickPick() {
|
|||||||
// 显示推荐项列表
|
// 显示推荐项列表
|
||||||
vscode.window.showQuickPick(options, {
|
vscode.window.showQuickPick(options, {
|
||||||
matchOnDetail: true,
|
matchOnDetail: true,
|
||||||
title: '请选择需要转换的命名类型...',
|
title: '请选择需要转换的命名方式...',
|
||||||
placeHolder: '点击转换,输入关键词可快速选择'
|
placeHolder: '点击转换,输入关键词可快速选择'
|
||||||
}).then(pickItem => {
|
}).then(pickItem => {
|
||||||
if (!editor || pickItem === undefined) {
|
if (!editor || pickItem === undefined) {
|
@ -1,14 +0,0 @@
|
|||||||
const vscode = require('vscode');
|
|
||||||
|
|
||||||
function getUserConfigurations(configKey: string) {
|
|
||||||
const config = vscode.workspace.getConfiguration('variable-conversion');
|
|
||||||
|
|
||||||
// 获取 disableFormat 配置项
|
|
||||||
const configValue = config.get(configKey);
|
|
||||||
console.log('configValue:', configValue);
|
|
||||||
return configValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
getUserConfigurations
|
|
||||||
};
|
|
@ -3,12 +3,16 @@ import * as assert from 'assert';
|
|||||||
// You can import and use all API from the 'vscode' module
|
// You can import and use all API from the 'vscode' module
|
||||||
// as well as import your extension to test it
|
// as well as import your extension to test it
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import testGroups from './test-case';
|
import { variableConvertTestGroups } from './test-case/variable-convert-test-case';
|
||||||
import { TestCase, TestCaseGroup } from '../type-definition/TestCaseType';
|
import { pathConvertTestGroups } from './test-case/path-convert-test-case';
|
||||||
import { transformMutliLineText, transformText } from '../main-code/transform';
|
import { VariableTestCase, VariableTestCaseGroup } from './test-case/types/VariableTestCaseType';
|
||||||
import { caseConversion } from '../main-code/conversion';
|
import { PathTestCase, PathTestCaseGroup } from './test-case/types/PathTestCaseType';
|
||||||
import { SupportCase } from '../type-definition/SupportCaseType';
|
import { transformMutliLineText, transformText } from '../utils/transform';
|
||||||
import { TransformTextResult } from '../type-definition/TransformTextResultType';
|
import { caseConversion } from '../core/variable-convert/conversion';
|
||||||
|
import { pathConversion } from '../core/path-convert/conversion';
|
||||||
|
import { SupportVariableCase } from '../core/variable-convert/types/SupportVariableCaseType';
|
||||||
|
import { SupportPathFormat } from '../core/path-convert/types/SupportPathFormatType';
|
||||||
|
import { TransformTextResult } from '../types/TransformTextResultType';
|
||||||
// import * as myExtension from '../../extension';
|
// import * as myExtension from '../../extension';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,13 +26,18 @@ suite('Extension Test Suite', () => {
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
suite('Extension Test: run test case', () => {
|
/**
|
||||||
vscode.window.showInformationMessage('Start all tests.');
|
* 变量转换 测试函数
|
||||||
|
*
|
||||||
|
* @since 2024-04-02
|
||||||
|
*/
|
||||||
|
suite('Extension Test: run variable convert test case', () => {
|
||||||
|
vscode.window.showInformationMessage('Start all tests for variable conversion.');
|
||||||
|
|
||||||
const groups: Array<TestCaseGroup> = testGroups;
|
const groups: Array<VariableTestCaseGroup> = variableConvertTestGroups;
|
||||||
for (const testGroup of groups) {
|
for (const testGroup of groups) {
|
||||||
const testTitle = testGroup.testTitle;
|
const testTitle = testGroup.testTitle;
|
||||||
const testCases: Array<TestCase> = testGroup.cases;
|
const testCases: Array<VariableTestCase> = testGroup.cases;
|
||||||
for (const testCase of testCases) {
|
for (const testCase of testCases) {
|
||||||
// // 临时
|
// // 临时
|
||||||
// if (testCase.title !== '') {
|
// if (testCase.title !== '') {
|
||||||
@ -48,35 +57,35 @@ suite('Extension Test: run test case', () => {
|
|||||||
assert.strictEqual(correctValue, currentValue);
|
assert.strictEqual(correctValue, currentValue);
|
||||||
}
|
}
|
||||||
// 验证转换
|
// 验证转换
|
||||||
for (let eol of eolList) {
|
for (const eol of eolList) {
|
||||||
assert.strictEqual(testCase.output.camelCase, caseConversion(SupportCase.CAMEL_CASE, input, eol), 'camel case test failed.');
|
assert.strictEqual(testCase.output.camelCase, caseConversion(SupportVariableCase.CAMEL_CASE, input, eol), 'camel case test failed.');
|
||||||
assert.strictEqual(testCase.output.pascalCase, caseConversion(SupportCase.PASCAL_CASE, input, eol), 'pascal case test failed.');
|
assert.strictEqual(testCase.output.pascalCase, caseConversion(SupportVariableCase.PASCAL_CASE, input, eol), 'pascal case test failed.');
|
||||||
|
|
||||||
assert.strictEqual(testCase.output.snakeCase, caseConversion(SupportCase.SNAKE_CASE, input, eol), 'snake case test failed.');
|
assert.strictEqual(testCase.output.snakeCase, caseConversion(SupportVariableCase.SNAKE_CASE, input, eol), 'snake case test failed.');
|
||||||
assert.strictEqual(testCase.output.snakeCamelCase, caseConversion(SupportCase.SNAKE_CAMEL_CASE, input, eol), 'snake camel case test failed.');
|
assert.strictEqual(testCase.output.snakeCamelCase, caseConversion(SupportVariableCase.SNAKE_CAMEL_CASE, input, eol), 'snake camel case test failed.');
|
||||||
assert.strictEqual(testCase.output.snakePascalCase, caseConversion(SupportCase.SNAKE_PASCAL_CASE, input, eol), 'snake pascal case test failed.');
|
assert.strictEqual(testCase.output.snakePascalCase, caseConversion(SupportVariableCase.SNAKE_PASCAL_CASE, input, eol), 'snake pascal case test failed.');
|
||||||
assert.strictEqual(testCase.output.snakeUpperCase, caseConversion(SupportCase.SNAKE_UPPER_CASE, input, eol), 'snake upper case test failed.');
|
assert.strictEqual(testCase.output.snakeUpperCase, caseConversion(SupportVariableCase.SNAKE_UPPER_CASE, input, eol), 'snake upper case test failed.');
|
||||||
|
|
||||||
assert.strictEqual(testCase.output.kebabCase, caseConversion(SupportCase.KEBAB_CASE, input, eol), 'kebab case test failed.');
|
assert.strictEqual(testCase.output.kebabCase, caseConversion(SupportVariableCase.KEBAB_CASE, input, eol), 'kebab case test failed.');
|
||||||
assert.strictEqual(testCase.output.kebabCamelCase, caseConversion(SupportCase.KEBAB_CAMEL_CASE, input, eol), 'kebab camel case test failed.');
|
assert.strictEqual(testCase.output.kebabCamelCase, caseConversion(SupportVariableCase.KEBAB_CAMEL_CASE, input, eol), 'kebab camel case test failed.');
|
||||||
assert.strictEqual(testCase.output.kebabPascalCase, caseConversion(SupportCase.KEBAB_PASCAL_CASE, input, eol), 'kebab pascal case test failed.');
|
assert.strictEqual(testCase.output.kebabPascalCase, caseConversion(SupportVariableCase.KEBAB_PASCAL_CASE, input, eol), 'kebab pascal case test failed.');
|
||||||
assert.strictEqual(testCase.output.kebabUpperCase, caseConversion(SupportCase.KEBAB_UPPER_CASE, input, eol), 'kebab upper case test failed.');
|
assert.strictEqual(testCase.output.kebabUpperCase, caseConversion(SupportVariableCase.KEBAB_UPPER_CASE, input, eol), 'kebab upper case test failed.');
|
||||||
|
|
||||||
assert.strictEqual(testCase.output.spaceCase, caseConversion(SupportCase.SPACE_CASE, input, eol), 'space case test failed.');
|
assert.strictEqual(testCase.output.spaceCase, caseConversion(SupportVariableCase.SPACE_CASE, input, eol), 'space case test failed.');
|
||||||
assert.strictEqual(testCase.output.spaceCamelCase, caseConversion(SupportCase.SPACE_CAMEL_CASE, input, eol), 'space camel case test failed.');
|
assert.strictEqual(testCase.output.spaceCamelCase, caseConversion(SupportVariableCase.SPACE_CAMEL_CASE, input, eol), 'space camel case test failed.');
|
||||||
assert.strictEqual(testCase.output.spacePascalCase, caseConversion(SupportCase.SPACE_PASCAL_CASE, input, eol), 'space pascal case test failed.');
|
assert.strictEqual(testCase.output.spacePascalCase, caseConversion(SupportVariableCase.SPACE_PASCAL_CASE, input, eol), 'space pascal case test failed.');
|
||||||
assert.strictEqual(testCase.output.spaceUpperCase, caseConversion(SupportCase.SPACE_UPPER_CASE, input, eol), 'space upper case test failed.');
|
assert.strictEqual(testCase.output.spaceUpperCase, caseConversion(SupportVariableCase.SPACE_UPPER_CASE, input, eol), 'space upper case test failed.');
|
||||||
|
|
||||||
assert.strictEqual(testCase.output.dotCase, caseConversion(SupportCase.DOT_CASE, input, eol), 'dot case test failed.');
|
assert.strictEqual(testCase.output.dotCase, caseConversion(SupportVariableCase.DOT_CASE, input, eol), 'dot case test failed.');
|
||||||
assert.strictEqual(testCase.output.dotCamelCase, caseConversion(SupportCase.DOT_CAMEL_CASE, input, eol), 'dot camel case test failed.');
|
assert.strictEqual(testCase.output.dotCamelCase, caseConversion(SupportVariableCase.DOT_CAMEL_CASE, input, eol), 'dot camel case test failed.');
|
||||||
assert.strictEqual(testCase.output.dotPascalCase, caseConversion(SupportCase.DOT_PASCAL_CASE, input, eol), 'dot pascal case test failed.');
|
assert.strictEqual(testCase.output.dotPascalCase, caseConversion(SupportVariableCase.DOT_PASCAL_CASE, input, eol), 'dot pascal case test failed.');
|
||||||
assert.strictEqual(testCase.output.dotUpperCase, caseConversion(SupportCase.DOT_UPPER_CASE, input, eol), 'dot upper case test failed.');
|
assert.strictEqual(testCase.output.dotUpperCase, caseConversion(SupportVariableCase.DOT_UPPER_CASE, input, eol), 'dot upper case test failed.');
|
||||||
|
|
||||||
if (testCase.output.lowerCase !== undefined) {
|
if (testCase.output.lowerCase !== undefined) {
|
||||||
assert.strictEqual(testCase.output.lowerCase, caseConversion(SupportCase.LOWER_CASE, input, eol), 'lower case test failed.');
|
assert.strictEqual(testCase.output.lowerCase, caseConversion(SupportVariableCase.LOWER_CASE, input, eol), 'lower case test failed.');
|
||||||
}
|
}
|
||||||
if (testCase.output.upperCase !== undefined) {
|
if (testCase.output.upperCase !== undefined) {
|
||||||
assert.strictEqual(testCase.output.upperCase, caseConversion(SupportCase.UPPER_CASE, input, eol), 'upper case test failed.');
|
assert.strictEqual(testCase.output.upperCase, caseConversion(SupportVariableCase.UPPER_CASE, input, eol), 'upper case test failed.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,3 +93,36 @@ suite('Extension Test: run test case', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路径转换 测试函数
|
||||||
|
*
|
||||||
|
* @since 2024-12-07
|
||||||
|
*/
|
||||||
|
suite('Extension Test: run path convert test case', () => {
|
||||||
|
vscode.window.showInformationMessage('Start all tests for path conversion.');
|
||||||
|
|
||||||
|
const groups: Array<PathTestCaseGroup> = pathConvertTestGroups;
|
||||||
|
for (const testGroup of groups) {
|
||||||
|
const testTitle = testGroup.testTitle;
|
||||||
|
const testCases: Array<PathTestCase> = testGroup.cases;
|
||||||
|
for (const testCase of testCases) {
|
||||||
|
// // 临时
|
||||||
|
// if (testCase.title !== '') {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
test(testTitle + ' - ' + testCase.title, () => {
|
||||||
|
const inputList = Array.isArray(testCase.input) ? testCase.input : [testCase.input];
|
||||||
|
const eolList = Array.isArray(testCase.eol) ? testCase.eol : [testCase.eol];
|
||||||
|
for (const input of inputList) {
|
||||||
|
// console.log('input', '->' + input + '<-');
|
||||||
|
// 验证转换
|
||||||
|
for (const eol of eolList) {
|
||||||
|
assert.strictEqual(testCase.output.Windows.unEscape, pathConversion(SupportPathFormat.Windows, input, eol), 'Windows path format test failed.');
|
||||||
|
assert.strictEqual(testCase.output.Unix.unEscape, pathConversion(SupportPathFormat.Unix, input, eol), 'Unix path format test failed.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
108
src/test/test-case/path-convert-test-case.ts
Normal file
108
src/test/test-case/path-convert-test-case.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import { PathTestCaseGroup } from "./types/PathTestCaseType";
|
||||||
|
|
||||||
|
const LF = '\n';
|
||||||
|
const CRLF = '\r\n';
|
||||||
|
|
||||||
|
export const pathConvertTestGroups: Array<PathTestCaseGroup> = [
|
||||||
|
{
|
||||||
|
group: 'Normal Path Format Convert',
|
||||||
|
testTitle: 'Normal Path Format Convert (常规路径风格转换)',
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
title: 'Windows 风格',
|
||||||
|
input: // E:\Project\variable-conversion-vscode-extension
|
||||||
|
'E:\\Project\\variable-conversion-vscode-extension',
|
||||||
|
eol: [LF, CRLF],
|
||||||
|
output: {
|
||||||
|
Windows: {
|
||||||
|
unEscape: // E:\Project\variable-conversion-vscode-extension
|
||||||
|
'E:\\Project\\variable-conversion-vscode-extension',
|
||||||
|
|
||||||
|
escape: // E:\\Project\\variable-conversion-vscode-extension
|
||||||
|
'E:\\\\Project\\\\variable-conversion-vscode-extension',
|
||||||
|
},
|
||||||
|
Unix: {
|
||||||
|
unEscape:
|
||||||
|
'E:/Project/variable-conversion-vscode-extension',
|
||||||
|
escape: // E:\/Project\/variable-conversion-vscode-extension
|
||||||
|
'E:\\/Project\\/variable-conversion-vscode-extension',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Unix 风格',
|
||||||
|
input: '/home/user/file.txt',
|
||||||
|
eol: [LF, CRLF],
|
||||||
|
output: {
|
||||||
|
Windows: {
|
||||||
|
unEscape: // \home\user\file.txt
|
||||||
|
'\\home\\user\\file.txt',
|
||||||
|
escape: // \\home\\user\\file.txt
|
||||||
|
'\\\\home\\\\user\\\\file.txt',
|
||||||
|
},
|
||||||
|
Unix: {
|
||||||
|
unEscape:
|
||||||
|
'/home/user/file.txt',
|
||||||
|
escape: // \/home\/user\/file.txt
|
||||||
|
'\\/home\\/user\\/file.txt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Windows (Git Bash) 风格',
|
||||||
|
input: '/c/Users/test/file.txt',
|
||||||
|
eol: [LF, CRLF],
|
||||||
|
output: {
|
||||||
|
Windows: {
|
||||||
|
unEscape: // \c\Users\test/file.txt
|
||||||
|
'\\c\\Users\\test\\file.txt',
|
||||||
|
escape: // \\c\\Users\\test\\file.txt
|
||||||
|
'\\\\c\\\\Users\\\\test\\\\file.txt',
|
||||||
|
// TODO need to transform to ↓
|
||||||
|
/*
|
||||||
|
unEscape: // C:\Users\test\file.txt
|
||||||
|
'C:\\Users\\test\\file.txt',
|
||||||
|
escape: // C:\\Users\\test\\file.txt
|
||||||
|
'C:\\\\Users\\\\test\\\\file.txt',
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
Unix: {
|
||||||
|
unEscape:
|
||||||
|
'/c/Users/test/file.txt',
|
||||||
|
escape: // \/c\/Users\/test\/file.txt
|
||||||
|
'\\/c\\/Users\\/test\\/file.txt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// Windows 局域网主机名风格
|
||||||
|
// \\ComputerName
|
||||||
|
// 路径带空格
|
||||||
|
// /home/user/hello world.txt
|
||||||
|
// /home/user/hello world.txt
|
||||||
|
// and more ...
|
||||||
|
|
||||||
|
// {
|
||||||
|
// title: '',
|
||||||
|
// input: //
|
||||||
|
// '',
|
||||||
|
// eol: [LF, CRLF],
|
||||||
|
// output: {
|
||||||
|
// Windows: {
|
||||||
|
// unEscape: //
|
||||||
|
// '',
|
||||||
|
// escape: //
|
||||||
|
// '',
|
||||||
|
// },
|
||||||
|
// Unix: {
|
||||||
|
// unEscape: //
|
||||||
|
// '',
|
||||||
|
// escape: //
|
||||||
|
// '',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
22
src/test/test-case/types/PathTestCaseType.ts
Normal file
22
src/test/test-case/types/PathTestCaseType.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { EOL } from "../../../types/EOLType";
|
||||||
|
|
||||||
|
export type PathTestCaseGroup = {
|
||||||
|
group: string
|
||||||
|
testTitle: string
|
||||||
|
cases: Array<PathTestCase>
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PathTestOutputResult = {
|
||||||
|
unEscape: string;
|
||||||
|
escape: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PathTestCase = {
|
||||||
|
title: string
|
||||||
|
input: string | Array<string>
|
||||||
|
eol: EOL | Array<EOL>
|
||||||
|
output: {
|
||||||
|
Windows: PathTestOutputResult
|
||||||
|
Unix: PathTestOutputResult
|
||||||
|
}
|
||||||
|
};
|
@ -1,12 +1,12 @@
|
|||||||
import { EOL } from "./EOLType";
|
import { EOL } from "../../../types/EOLType";
|
||||||
|
|
||||||
export type TestCaseGroup = {
|
export type VariableTestCaseGroup = {
|
||||||
group: string
|
group: string
|
||||||
testTitle: string
|
testTitle: string
|
||||||
cases: Array<TestCase>
|
cases: Array<VariableTestCase>
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TestCase = {
|
export type VariableTestCase = {
|
||||||
title: string
|
title: string
|
||||||
input: string | Array<string>
|
input: string | Array<string>
|
||||||
eol: EOL | Array<EOL>
|
eol: EOL | Array<EOL>
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
import { TransformTextResult } from "../type-definition/TransformTextResultType";
|
import { TransformTextResult } from "../types/TransformTextResultType";
|
||||||
|
|
||||||
const logDebugInfo = false;
|
const logDebugInfo = false;
|
||||||
|
|
20
src/utils/user-configuration.ts
Normal file
20
src/utils/user-configuration.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import vscode from 'vscode';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户配置项
|
||||||
|
*
|
||||||
|
* @param configKey 配置项的键
|
||||||
|
* @returns 配置项的值
|
||||||
|
* @since 2024-07-29
|
||||||
|
*/
|
||||||
|
function getUserConfigurations<T>(configKey: string): T | undefined {
|
||||||
|
const config = vscode.workspace.getConfiguration('variable-conversion');
|
||||||
|
|
||||||
|
const configValue = config.get<T>(configKey);
|
||||||
|
// console.log('configValue:', configValue);
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getUserConfigurations
|
||||||
|
};
|
@ -1,3 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* 比较两个字符串数组 `Array<string>` 是否相同
|
||||||
|
*
|
||||||
|
* @param array1 数组1
|
||||||
|
* @param array2 数组2
|
||||||
|
* @returns
|
||||||
|
* @since 2024-04-09
|
||||||
|
*/
|
||||||
export function isStringArrayEqual(array1: string[], array2: string[]) {
|
export function isStringArrayEqual(array1: string[], array2: string[]) {
|
||||||
if (array1.length !== array2.length) {
|
if (array1.length !== array2.length) {
|
||||||
return false;
|
return false;
|
||||||
@ -12,6 +20,15 @@ export function isStringArrayEqual(array1: string[], array2: string[]) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 去除二维字符串数组中的重复数组元素
|
||||||
|
*
|
||||||
|
* 例如,输入 [["a", "b"], ["a", "b"], ["c", "d"]],会返回 [[ "a", "b"], ["c", "d"]],去除了重复出现的 ["a", "b"]。
|
||||||
|
*
|
||||||
|
* @param stringArr 要进行去重操作的二维字符串数组,即数组中每个元素又是一个字符串数组,代表一组相关的字符串元素集合。
|
||||||
|
* @returns 返回一个二维字符串数组,其中已经去除了原输入二维数组中重复的元素组合,基于JSON序列化后的字符串比较来判定重复与否。
|
||||||
|
* @since 2024-04-09
|
||||||
|
*/
|
||||||
export function stringListArrayDuplicateRemoval(stringArr: Array<string[]>): Array<string[]> {
|
export function stringListArrayDuplicateRemoval(stringArr: Array<string[]>): Array<string[]> {
|
||||||
const tempArr: Array<string> = [];
|
const tempArr: Array<string> = [];
|
||||||
const newArr: Array<string[]> = [];
|
const newArr: Array<string[]> = [];
|
Loading…
Reference in New Issue
Block a user