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

Compare commits

...

7 Commits

20 changed files with 2174 additions and 1268 deletions

View File

@ -25,14 +25,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## 2.0.0 ## 2.0.0
### Improvement ### Added
- Adjust the project code directory structure. (项目代码目录结构调整) - 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 ### Changed
- Do not display the editor context menu `Variable Conversion` option when text is not selected. (当未选中文本时,不显示右键菜单 `变量转换` 选项) - 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
@ -56,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

View File

@ -40,6 +40,7 @@
// docs: https://code.visualstudio.com/docs/getstarted/keybindings#_accepted-keys // docs: https://code.visualstudio.com/docs/getstarted/keybindings#_accepted-keys
"keybindings": [ "keybindings": [
// 绑定快捷键 // 绑定快捷键
// ↓ 变量转换快捷键
{ {
"command": "variable-conversion.convertCase", "command": "variable-conversion.convertCase",
"key": "shift+alt+t", "key": "shift+alt+t",
@ -62,6 +63,30 @@
"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": [
@ -171,7 +196,7 @@
{ {
"command": "variable-conversion.toUpperCase", "command": "variable-conversion.toUpperCase",
"title": "全大写 (Upper Case) [ FOOBAR ]" "title": "全大写 (Upper Case) [ FOOBAR ]"
} },
// 隐藏命令 // 隐藏命令
// { // {
// "command": "editor.action.transformToCamelcase", // "command": "editor.action.transformToCamelcase",
@ -202,26 +227,61 @@
// "command": "editor.action.transformToSnakecase", // "command": "editor.action.transformToSnakecase",
// "title": "[VSCode 自带] 转换为蛇形命名法 (Snake Case) [ foo_bar ]", // "title": "[VSCode 自带] 转换为蛇形命名法 (Snake Case) [ foo_bar ]",
// "enablement": "false" // "enablement": "false"
// } // },
/**
* 右键菜单
*/
{
"command": "variable-conversion.convertPath",
"title": "路径转换"
},
/**
* 右键菜单 - 子菜单
*/
// group-1-common-style
{
"command": "variable-conversion.pathFormat.toWindowsStyle",
"title": "Windows 风格 [ C:\\Windows\\System32 ]"
},
{
"command": "variable-conversion.pathFormat.toUnixStyle",
"title": "Unix 风格 [ /usr/bin ]"
}
], ],
// docs: https://code.visualstudio.com/api/references/contribution-points#contributes.menus // docs: https://code.visualstudio.com/api/references/contribution-points#contributes.menus
"menus": { "menus": {
// 编辑器右键菜单 // 编辑器右键菜单
"editor/context": [ "editor/context": [
// 变量转换
{ {
// "when": "editorTextFocus", // "when": "editorTextFocus",
// 2024.12.07 当未选中文字时,隐藏 [变量转换] 右键菜单 // 2024.12.07 当未选中文字时,隐藏 [变量转换] 右键菜单
"when": "editorTextFocus && _textSelectionLength >= 1", "when": "editorTextFocus && _textSelectionLength >= 1",
"command": "variable-conversion.convertCase", "command": "variable-conversion.convertCase",
// "group": "1_modification@9" // "group": "1_modification@9"
"group": "navigation@9" "group": "navigation@10"
}, },
// 将变量转换为...
{ {
"when": "editorTextFocus && _textSelectionLength >= 1", "when": "editorTextFocus && _textSelectionLength >= 1",
"submenu": "variable-conversion.stringConversionMenu", "submenu": "variable-conversion.stringConversionMenu",
// docs: https://code.visualstudio.com/api/references/contribution-points#Sorting-of-groups // docs: https://code.visualstudio.com/api/references/contribution-points#Sorting-of-groups
// "group": "1_modification@9" // "group": "1_modification@9"
"group": "navigation@9" "group": "navigation@11"
},
// 路径转换
{
// "when": "editorTextFocus",
// 2024.12.07 当未选中文字时,隐藏 [变量转换] 右键菜单
"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": [
@ -362,6 +422,21 @@
// "group": "group-vscode", // "group": "group-vscode",
// "when": "false" // "when": "false"
// } // }
],
"variable-conversion.pathConversionMenu": [
// group-1-common-style
{
// Windows 风格
"when": "!_isHideSubMenuItem_windows_style",
"command": "variable-conversion.pathFormat.toWindowsStyle",
"group": "group-1-common-style@1"
},
{
// Unix 风格
"when": "!_isHideSubMenuItem_unix_style",
"command": "variable-conversion.pathFormat.toUnixStyle",
"group": "group-1-common-style@2"
}
] ]
}, },
// docs: https://code.visualstudio.com/api/references/contribution-points#contributes.submenus // docs: https://code.visualstudio.com/api/references/contribution-points#contributes.submenus
@ -369,6 +444,10 @@
{ {
"id": "variable-conversion.stringConversionMenu", "id": "variable-conversion.stringConversionMenu",
"label": "将变量转换为..." "label": "将变量转换为..."
},
{
"id": "variable-conversion.pathConversionMenu",
"label": "将路径转换为..."
} }
], ],
// docs: https://code.visualstudio.com/api/references/contribution-points#contributes.configuration // docs: https://code.visualstudio.com/api/references/contribution-points#contributes.configuration
@ -407,7 +486,7 @@
"variable-conversion.disableFormat": { "variable-conversion.disableFormat": {
"order": 1, "order": 1,
// markdownDescription 最多配置 11 行 // markdownDescription 最多配置 11 行
"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",
@ -537,6 +616,25 @@
"lower_case", "lower_case",
"upper_case" "upper_case"
] ]
},
// TODO
"variable-conversion.disablePathFormat": {
"order": 3,
// markdownDescription 最多配置 11 行
"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": []
} }
} }
} }

View File

@ -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,6 +159,18 @@
{ {
"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": {
@ -145,12 +178,22 @@
{ {
"when": "editorTextFocus && _textSelectionLength >= 1", "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": []
} }
} }
} }

View 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;
}

View 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;
}
}

View 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' },
];

View File

@ -1,53 +1,53 @@
import { EOL } from '../../types/EOLType'; import { EOL } from '../../types/EOLType';
import { SupportCase } from './types/SupportCaseType'; import { SupportVariableCase } from './types/SupportVariableCaseType';
import { TransformTextResult } from '../../types/TransformTextResultType'; import { TransformTextResult } from '../../types/TransformTextResultType';
import { transformMutliLineText, transformText } from '../../utils/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 * @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();
} }
@ -85,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) {
@ -99,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: // 点分隔命名x
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:

View File

@ -1,6 +1,6 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { EOL } from "../../types/EOLType"; import { EOL } from "../../types/EOLType";
import { cyclicConvertCaseOrder } from "./types/SupportCaseType"; import { cyclicConvertCaseOrder } from "./types/SupportVariableCaseType";
import { caseConversion } from "./conversion"; import { caseConversion } from "./conversion";
import { isStringArrayEqual, stringListArrayDuplicateRemoval } from '../../utils/utils'; import { isStringArrayEqual, stringListArrayDuplicateRemoval } from '../../utils/utils';
import { getUserConfigurations } from '../../utils/user-configuration'; import { getUserConfigurations } from '../../utils/user-configuration';

View File

@ -1,5 +1,5 @@
/** /**
* 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
@ -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' },
]; ];

View File

@ -11,11 +11,21 @@
* @see https://code.visualstudio.com/api * @see https://code.visualstudio.com/api
*/ */
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import handleEditorReplace from './handler/editor-submenu-handler';
import { handleQuickPick } from './handler/quick-pick-handler'; // Variable Convert
import { commands } from './core/variable-convert/types/SupportCaseType'; import handleEditorReplaceVariable from './handler/variable-convert/editor-submenu-handler';
import { handleQuickPick as handleQuickPickVariable } from './handler/variable-convert/quick-pick-handler';
import { commands as variableCommands } from './core/variable-convert/types/SupportVariableCaseType';
import * as CyclicConversionVariable from './core/variable-convert/cyclic-conversion';
// 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 { createStatusBarItem, updateStatusBarItemVisable } from './handler/status-bar-handler';
import * as CyclicConversion from './core/variable-convert/cyclic-conversion';
import { EOL } from './types/EOLType'; import { EOL } from './types/EOLType';
import { getUserConfigurations } from './utils/user-configuration'; import { getUserConfigurations } from './utils/user-configuration';
@ -55,17 +65,26 @@ 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<Array<string>>('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);
}; };
// 创建状态栏按钮 // 创建状态栏按钮
@ -105,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

View 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;

View 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);
}
});
});
}

View File

@ -2,7 +2,7 @@ import * as vscode from 'vscode';
// docs: https://code.visualstudio.com/api/references/vscode-api#StatusBarItem // docs: https://code.visualstudio.com/api/references/vscode-api#StatusBarItem
let statusBar: vscode.StatusBarItem; let statusBarItemList: Array<vscode.StatusBarItem> = [];
/** /**
* *
@ -10,11 +10,29 @@ let statusBar: vscode.StatusBarItem;
* @since 2024-04-07 * @since 2024-04-07
*/ */
export function createStatusBarItem() { export function createStatusBarItem() {
statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); // 变量转换状态栏 2024.04.07
statusBar.text = '$(find-replace)变量转换'; const createVariableConvertStatusBarItem = () => {
statusBar.command = 'variable-conversion.convertCase'; const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
// statusBar.color = 'red'; // Icon Listing docs: https://code.visualstudio.com/api/references/icons-in-labels#icon-listing
// statusBar.show(); 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(),
);
} }
/** /**
@ -23,14 +41,14 @@ export function createStatusBarItem() {
* @since 2024-04-07 * @since 2024-04-07
*/ */
export function updateStatusBarItemVisable(selectTextLength: number) { export function updateStatusBarItemVisable(selectTextLength: number) {
if (!statusBar) {
return;
}
let editor = vscode.window.activeTextEditor; let editor = vscode.window.activeTextEditor;
if (editor && selectTextLength > 0) { if (editor && selectTextLength > 0) {
statusBar.show(); statusBarItemList.forEach(statusBarItem => {
statusBarItem.show();
});
return; return;
} }
statusBar.hide(); statusBarItemList.forEach(statusBarItem => {
statusBarItem.hide();
});
} }

View File

@ -1,8 +1,8 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { EOL } from '../types/EOLType'; import { EOL } from '../../types/EOLType';
import { caseConversion } from '../core/variable-convert/conversion'; import { caseConversion } from '../../core/variable-convert/conversion';
import { SupportCase } from '../core/variable-convert/types/SupportCaseType'; import { SupportVariableCase } from '../../core/variable-convert/types/SupportVariableCaseType';
import { isStringArrayEqual } from '../utils/utils'; import { isStringArrayEqual } from '../../utils/utils';
/** /**
* *
@ -10,7 +10,7 @@ import { isStringArrayEqual } from '../utils/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) {

View File

@ -1,12 +1,12 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import QuickPickItemEx from "./types/QuickPickItemExType"; import QuickPickItemEx from "../types/QuickPickItemExType";
import { QuickPickSupportCaseItem, quickPickSupportCases } from '../core/variable-convert/types/SupportCaseType'; import { QuickPickSupportCaseItem, quickPickSupportCases } from '../../core/variable-convert/types/SupportVariableCaseType';
import { TransformTextResult } from '../types/TransformTextResultType'; import { TransformTextResult } from '../../types/TransformTextResultType';
import { transformMutliSelectionText } from '../utils/transform'; import { transformMutliSelectionText } from '../../utils/transform';
import { EOL } from '../types/EOLType'; import { EOL } from '../../types/EOLType';
import { caseConversion } from '../core/variable-convert/conversion'; import { caseConversion } from '../../core/variable-convert/conversion';
import { isStringArrayEqual } from '../utils/utils'; import { isStringArrayEqual } from '../../utils/utils';
import { getUserConfigurations } from '../utils/user-configuration'; import { getUserConfigurations } from '../../utils/user-configuration';
const QuickPickLabelMaxLength = 60; const QuickPickLabelMaxLength = 60;

View File

@ -3,11 +3,15 @@ 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 { variableConvertTestGroups } from './test-case/variable-convert-test-case';
import { pathConvertTestGroups } from './test-case/path-convert-test-case'; import { pathConvertTestGroups } from './test-case/path-convert-test-case';
import { TestCase, TestCaseGroup } from './test-case/types/TestCaseType'; import { VariableTestCase, VariableTestCaseGroup } from './test-case/types/VariableTestCaseType';
import { PathTestCase, PathTestCaseGroup } from './test-case/types/PathTestCaseType';
import { transformMutliLineText, transformText } from '../utils/transform'; import { transformMutliLineText, transformText } from '../utils/transform';
import { caseConversion } from '../core/variable-convert/conversion'; import { caseConversion } from '../core/variable-convert/conversion';
import { SupportCase } from '../core/variable-convert/types/SupportCaseType'; 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 { TransformTextResult } from '../types/TransformTextResultType';
// import * as myExtension from '../../extension'; // import * as myExtension from '../../extension';
@ -28,12 +32,12 @@ suite('Extension Test Suite', () => {
* @since 2024-04-02 * @since 2024-04-02
*/ */
suite('Extension Test: run variable convert test case', () => { suite('Extension Test: run variable convert test case', () => {
vscode.window.showInformationMessage('Start all tests.'); vscode.window.showInformationMessage('Start all tests for variable conversion.');
const groups: Array<TestCaseGroup> = pathConvertTestGroups; 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 !== '') {
@ -53,35 +57,35 @@ suite('Extension Test: run variable convert 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.');
} }
} }
} }
@ -89,3 +93,36 @@ suite('Extension Test: run variable convert 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.');
}
}
});
}
}
});

File diff suppressed because it is too large Load Diff

View 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
}
};

View File

@ -1,12 +1,12 @@
import { EOL } from "../../../types/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