From 461ab98385d978b4096b1e70508a434a92fc09f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E5=B0=8F=E5=A2=A8?= <2291200076@qq.com> Date: Sun, 7 Apr 2024 02:00:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E9=94=AE=20Ctrl=20+=20Shift=20+=20T=20=E6=98=BE=E7=A4=BA=20vsc?= =?UTF-8?q?ode=20QickPick=20=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 ++ package-comment.jsonc | 10 +- package.json | 4 +- src/extension-handler/quick-pick-handler.ts | 100 ++++++++++++--- src/main-code/conversion.ts | 4 +- src/type-definition/QuickPickItemExType.ts | 3 +- src/type-definition/SupportCaseType.ts | 129 ++++++++++++++++++-- 7 files changed, 221 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57aabf0..dcc78fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this extension will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.0.4 + +### Added + +- Add shortcut key `Ctrl + Shift + T` to show vscode QickPick window (添加快捷键 Ctrl + Shift + T 来显示 vscode QickPick 弹窗) +- Write `README.md` (完善 README 文档) + ## 1.0.3 ### Added diff --git a/package-comment.jsonc b/package-comment.jsonc index 4e4886a..6c9d693 100644 --- a/package-comment.jsonc +++ b/package-comment.jsonc @@ -2,9 +2,9 @@ // 插件 id 及名称 "name": "variable-conversion", "displayName": "Variable Conversion [Under development(正在开发中)]", - "description": "A variable naming conversion extension. You can use it through the editer menu, shortcut keys and bottom bar. Support camel, pascal, snake, kebab(spinal), lower, upper case, and more. \n变量名转换插件,支持右键菜单、快捷键、底栏等多种方式使用,支持小驼峰、大驼峰(帕斯卡)、下划线(蛇形)、连字符(脊柱式)、全小写、全大写等常用命名方式(及组合)转换。", + "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), lower, upper case, and more.", // 版本号 - "version": "0.0.3", + "version": "0.0.4", // logo "icon": "image/logo.png", "publisher": "coder-xiaomo", @@ -31,8 +31,10 @@ ], "main": "./out/extension.js", "activationEvents": [ - "onStartupFinished", // 当编辑器完成启动时激活 - "onTextSelected" // 当用户选中文本时激活 + // 当编辑器完成启动时激活 + "onStartupFinished", + // 当用户选中文本时激活 + "onTextSelected" ], "contributes": { "commands": [ diff --git a/package.json b/package.json index 2802ca8..bd89d8b 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "variable-conversion", "displayName": "Variable Conversion [Under development(正在开发中)]", - "description": "A variable naming conversion extension. You can use it through the editer menu, shortcut keys and bottom bar. Support camel, pascal, snake, kebab(spinal), lower, upper case, and more. \n变量名转换插件,支持右键菜单、快捷键、底栏等多种方式使用,支持小驼峰、大驼峰(帕斯卡)、下划线(蛇形)、连字符(脊柱式)、全小写、全大写等常用命名方式(及组合)转换。", - "version": "0.0.3", + "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), lower, upper case, and more.", + "version": "0.0.4", "icon": "image/logo.png", "publisher": "coder-xiaomo", "engines": { diff --git a/src/extension-handler/quick-pick-handler.ts b/src/extension-handler/quick-pick-handler.ts index 4ec738b..93d64be 100644 --- a/src/extension-handler/quick-pick-handler.ts +++ b/src/extension-handler/quick-pick-handler.ts @@ -1,20 +1,71 @@ import * as vscode from 'vscode'; import QuickPickItemEx from "../type-definition/QuickPickItemExType"; +import { qickPickSupportCases } from '../type-definition/SupportCaseType'; +import { TransformTextResult } from '../type-definition/TransformTextResultType'; +import { transformMutliLineText } from '../main-code/transform'; +import { EOL } from '../type-definition/EOLType'; +import { caseConversion } from '../main-code/conversion'; + +const QuickPickLabelMaxLength = 60; + +interface RecommendItem { + conversionText: string + transforTo: string[] + keyword: string[] +} /** * 弹出的提示 */ -function generateOptionsBasedOnText(text: string): Array { +function generateOptionsBasedOnText(text: string, eol: EOL): Array { + // Cut text 切割文本 + const results: Array = transformMutliLineText(text); + + const mergeResultList: Array = []; + for (const qickPick of qickPickSupportCases) { + const conversionResult: string = caseConversion(qickPick.type, text, eol, results); + const recommendItem: RecommendItem | undefined = mergeResultList.find(item => item.conversionText === conversionResult); + + if (recommendItem === undefined) { + let item: RecommendItem = { + conversionText: conversionResult, + transforTo: [qickPick.shortName], // qickPick.name + keyword: qickPick.keyword, + }; + mergeResultList.push(item); + continue; + } + + recommendItem.transforTo.push(qickPick.shortName); // qickPick.name + recommendItem.keyword = Array.from(new Set(recommendItem.keyword.concat(qickPick.keyword))); // 关键词去重 + } + // 根据文本生成选项的逻辑 - return [ - { label: '输入对应项下方任一关键词可快速选择', kind: vscode.QuickPickItemKind.Separator }, - { label: text.toUpperCase(), description: '转换为大写', detail: '关键词:DaXie 大写 UpperCase', value: text.toUpperCase() }, - { label: 'Group 2', kind: vscode.QuickPickItemKind.Separator }, - { label: text.toLowerCase(), description: '转换为小写', value: text.toLowerCase() }, - { label: text.toLowerCase(), description: '转换为小写', value: text.toLowerCase() }, - { label: text.toLowerCase(), description: '转换为下划线', detail: '关键词:_', value: text.toLowerCase() }, - { label: text.toLowerCase(), description: '转换为连字符', detail: '关键词:-', value: text.toLowerCase() }, + const quickPickList = [ + // { label: '输入对应项下方任一关键词可快速选择', kind: vscode.QuickPickItemKind.Separator }, + // { label: text.toUpperCase(), description: '转换为大写', detail: '关键词:DaXie 大写 UpperCase', value: text.toUpperCase() }, + // { label: 'Group 2', kind: vscode.QuickPickItemKind.Separator }, + // { label: text.toLowerCase(), description: '转换为小写', value: text.toLowerCase() }, + // { label: text.toLowerCase(), description: '转换为小写', value: text.toLowerCase() }, + // { label: text.toLowerCase(), description: '转换为下划线', detail: '关键词:_', value: text.toLowerCase() }, + // { label: text.toLowerCase(), description: '转换为连字符', detail: '关键词:-', value: text.toLowerCase() }, ]; + + for (const recommendItem of mergeResultList) { + if (text === recommendItem.conversionText) { + continue; // 如果转换后与转换前相同,那么跳过这一项 + } + let quickPickItem: QuickPickItemEx = { + label: recommendItem.conversionText.length >= QuickPickLabelMaxLength + ? (recommendItem.conversionText.substring(0, QuickPickLabelMaxLength - 3) + '...') + : recommendItem.conversionText, + description: `转换为 ${recommendItem.transforTo.join(' / ')}`, + detail: `关键词 ${recommendItem.keyword.join(' ')}`, + value: recommendItem.conversionText, + }; + quickPickList.push(quickPickItem); + } + return quickPickList; } export function handleQuickPick() { @@ -26,6 +77,7 @@ export function handleQuickPick() { let document = editor.document; let selection = editor.selection; + let eol: EOL = document.eol === vscode.EndOfLine.CRLF ? '\r\n' : '\n'; // 获取选中的文本 let text = document.getText(selection); @@ -36,16 +88,32 @@ export function handleQuickPick() { } // 基于选中的文本生成选项 - const options = generateOptionsBasedOnText(text); + const options = generateOptionsBasedOnText(text, eol); // 显示推荐项列表 vscode.window.showQuickPick(options, { matchOnDetail: true, - title: '标题', - placeHolder: '输入对应项下方任一关键词可快速选择!' - }).then(selection => { - if (selection) { - // 处理用户的选择 - vscode.window.showInformationMessage(`你选择了: ${selection}`); + title: '请选择需要转换的命名类型...', + placeHolder: '点击转换,输入关键词可快速选择' + }).then(pickItem => { + if (pickItem === undefined) { + return; } + + // 处理用户的选择 + // vscode.window.showInformationMessage(`你选择了: ${JSON.stringify(selection)}`); + + const converted = pickItem.value; + + // 当转换后文本与转换前相同时,跳过转换,避免形成 Ctrl + Z 撤销历史记录 + if (converted === text) { + console.log('selection text is same to converted text, skip replace contents.'); + return; + } + + // 替换文本 + console.log('replace selection text', text, 'to', converted); + editor.edit(editBuilder => { + editBuilder.replace(selection, converted); + }); }); } \ No newline at end of file diff --git a/src/main-code/conversion.ts b/src/main-code/conversion.ts index f414b81..027f62d 100644 --- a/src/main-code/conversion.ts +++ b/src/main-code/conversion.ts @@ -12,7 +12,7 @@ import { transformMutliLineText, transformText } from './transform'; * @returns 转换后的文本 * @since 2024-04-04 */ -export function caseConversion(targetCase: SupportCase, str: string, eol: EOL): string { +export function caseConversion(targetCase: SupportCase, str: string, eol: EOL, cutText: Array | undefined = undefined): string { let spaceCharacter: '-' | '_' | ' ' | undefined = undefined; switch (targetCase) { default: @@ -39,7 +39,7 @@ export function caseConversion(targetCase: SupportCase, str: string, eol: EOL): } // Cut text 切割文本 - const results: Array = transformMutliLineText(str); + const results: Array = cutText === undefined ? transformMutliLineText(str) : cutText; // console.log('results', results); const transformedLines: Array = []; diff --git a/src/type-definition/QuickPickItemExType.ts b/src/type-definition/QuickPickItemExType.ts index c9e4497..115e130 100644 --- a/src/type-definition/QuickPickItemExType.ts +++ b/src/type-definition/QuickPickItemExType.ts @@ -4,6 +4,7 @@ interface ExtendedQuickPickItem extends vscode.QuickPickItem { value: string; } -type QuickPickItemEx = ExtendedQuickPickItem | vscode.QuickPickItem; +// type QuickPickItemEx = ExtendedQuickPickItem | vscode.QuickPickItem; +type QuickPickItemEx = ExtendedQuickPickItem; export default QuickPickItemEx; diff --git a/src/type-definition/SupportCaseType.ts b/src/type-definition/SupportCaseType.ts index fd4d8d3..c2e5675 100644 --- a/src/type-definition/SupportCaseType.ts +++ b/src/type-definition/SupportCaseType.ts @@ -140,17 +140,120 @@ export enum SupportCase { UPPER_CASE, } -export const AllSupportCase = [ - SupportCase.CAMEL_CASE, - SupportCase.PASCAL_CASE, - SupportCase.SNAKE_CASE, - SupportCase.SNAKE_CAMEL_CASE, - SupportCase.SNAKE_PASCAL_CASE, - SupportCase.SNAKE_UPPER_CASE, - SupportCase.KEBAB_CASE, - SupportCase.KEBAB_CAMEL_CASE, - SupportCase.KEBAB_PASCAL_CASE, - SupportCase.KEBAB_UPPER_CASE, - SupportCase.LOWER_CASE, - SupportCase.UPPER_CASE, +const keyword = { + camel: [ + '小驼峰', '驼峰', + 'Camel Case', + 'XiaoTuoFeng', 'TuoFeng', + 'XTF', 'TF', + ], + pascal: [ + '大驼峰', '帕斯卡', + 'Pascal Case', + 'DaTuoFeng', 'PaSiKa', + 'DTF', 'PSK', + ], + snake: [ + '下划线', '蛇形', '_', + 'Snake Case', 'Underline Case', + 'XiaHuaXian', 'SheXing', + 'XHX', 'SX', + ], + kebab: [ + '连字符', '脊柱式', '-', + 'Kebab Case', 'Spinal Case', + 'LianZiFu', 'JiZhuShi', + 'LZF', 'JZS', + ], + upper: [ + '全大写', '大写', + 'Upper Case', + 'QuanDaXie', + 'QDX', + ], + lower: [ + '全小写', '小写', + 'Lower Case', + 'QuanXiaoXie', + 'QXX', + ], +}; + +/** + * 所有支持的命名方式 + * @since 2024-04-06 + */ +export const qickPickSupportCases = [ + { + type: SupportCase.CAMEL_CASE, + name: '小驼峰(驼峰)命名', + shortName:'小驼峰', + keyword: keyword.camel, + }, + { + type: SupportCase.PASCAL_CASE, + name: '大驼峰(帕斯卡)命名', + shortName:'帕斯卡', + keyword: keyword.pascal, + }, + { + type: SupportCase.SNAKE_CASE, + name: '下划线(蛇形)命名', + shortName:'蛇形', + keyword: [...keyword.snake, ...keyword.lower], + }, + { + type: SupportCase.SNAKE_CAMEL_CASE, + name: '下划线(蛇形) + 小驼峰(驼峰)命名', + shortName:'蛇形驼峰', + keyword: [...keyword.snake, ...keyword.camel], + }, + { + type: SupportCase.SNAKE_PASCAL_CASE, + name: '下划线(蛇形) + 大驼峰(帕斯卡)命名', + shortName:'蛇形帕斯卡', + keyword: [...keyword.snake, ...keyword.pascal], + }, + { + type: SupportCase.SNAKE_UPPER_CASE, + name: '下划线(蛇形) + 全大写命名', + shortName:'蛇形大写', + keyword: [...keyword.snake, ...keyword.upper], + }, + { + type: SupportCase.KEBAB_CASE, + name: '连字符(脊柱式)命名', + shortName:'脊柱', + keyword: [...keyword.kebab, ...keyword.lower], + }, + { + type: SupportCase.KEBAB_CAMEL_CASE, + name: '连字符(脊柱式) + 小驼峰(驼峰)命名', + shortName:'脊柱驼峰', + keyword: [...keyword.kebab, ...keyword.camel], + }, + { + type: SupportCase.KEBAB_PASCAL_CASE, + name: '连字符(脊柱式) + 大驼峰(帕斯卡)命名', + shortName:'脊柱帕斯卡', + keyword: [...keyword.snake, ...keyword.pascal], + }, + { + type: SupportCase.KEBAB_UPPER_CASE, + name: '连字符(脊柱式) + 全大写命名', + shortName:'脊柱大写', + keyword: [...keyword.snake, ...keyword.upper], + }, + { + type: SupportCase.LOWER_CASE, + name: '全小写', + shortName:'小写', + keyword: keyword.lower, + }, + { + type: SupportCase.UPPER_CASE, + name: '全大写', + shortName:'大写', + keyword: keyword.upper, + }, ];