From 2bc72a2d7cdd8e62204c603200190e82f7ff0808 Mon Sep 17 00:00:00 2001 From: xiaohuohumax <1915970986@qq.com> Date: Sun, 24 Mar 2024 22:43:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=8E=AF=E5=A2=83=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改用 Vite 打包, 添加 env 环境, 修改 vscode launch 配置, 更新 eslint 配置, 修复 BUG: 文件夹右键格式化却只能格式化根目录 --- .changeset/strange-guests-lie.md | 5 + .editorconfig | 12 + .eslintignore | 2 + .eslintrc.json | 65 ++--- .vscode/extensions.json | 12 +- .vscode/launch.json | 32 +-- .vscode/settings.json | 16 +- .vscode/tasks.json | 45 ++-- .vscodeignore | 3 + env/.env | 6 + env/.env.production | 4 + package-lock.json | 399 +++++++++++++++++++++++++++---- package.json | 19 +- src/commands/command.ts | 92 +++---- src/commands/formatFolder.ts | 81 ++++--- src/commands/formatWorkspace.ts | 13 +- src/config.ts | 38 +-- src/extension.ts | 26 +- src/util/doc.ts | 66 ++--- src/util/folder.ts | 64 ++--- src/util/logger.ts | 81 +++---- src/util/message.ts | 28 +-- src/util/workspace.ts | 64 +++-- tsconfig.json | 40 ++-- types/env.d.ts | 27 +++ vite.config.mts | 24 ++ 26 files changed, 845 insertions(+), 419 deletions(-) create mode 100644 .changeset/strange-guests-lie.md create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 env/.env create mode 100644 env/.env.production create mode 100644 types/env.d.ts create mode 100644 vite.config.mts diff --git a/.changeset/strange-guests-lie.md b/.changeset/strange-guests-lie.md new file mode 100644 index 0000000..8a22915 --- /dev/null +++ b/.changeset/strange-guests-lie.md @@ -0,0 +1,5 @@ +--- +"format-files-by-ignores": minor +--- + +改用 Vite 打包, 添加 env 环境, 修改 vscode launch 配置, 更新 eslint 配置, 修复 BUG: 文件夹右键格式化却只能格式化根目录 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ebe51d3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..252089d --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +node_modules/ +out/ \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 9156c7e..bd26774 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,33 +1,38 @@ { - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "indent": [ + "error", + 2 ], - "rules": { - "@typescript-eslint/naming-convention": [ - "warn", - { - "selector": "import", - "format": [ - "camelCase", - "PascalCase" - ] - } - ], - "@typescript-eslint/semi": "warn", - "curly": "warn", - "eqeqeq": "warn", - "no-throw-literal": "warn", - "semi": "off" - }, - "ignorePatterns": [ - "out", - "dist", - "**/*.d.ts" - ] + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "no-empty": "off", + "@typescript-eslint/no-unused-vars": "off" + } } \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index fd613da..e1b2079 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,8 +1,8 @@ { - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "dbaeumer.vscode-eslint", - "ms-vscode.extension-test-runner" - ] + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "dbaeumer.vscode-eslint", + "ms-vscode.extension-test-runner" + ] } \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 8880465..b28286e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,19 +3,19 @@ // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 { - "version": "0.2.0", - "configurations": [ - { - "name": "Run Extension", - "type": "extensionHost", - "request": "launch", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "preLaunchTask": "${defaultBuildTask}" - } - ] -} + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ], + "preLaunchTask": "${defaultBuildTask}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 30bf8c2..75a21e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,11 @@ // Place your settings in this file to overwrite default and user settings. { - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off" + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off" } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3b17e53..67ea730 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,20 +1,31 @@ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format { - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "label": "npm: watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": { + "owner": "vite", + "pattern": { + "regexp": "" + }, + "background": { + "activeOnStart": true, + "beginsPattern": "^build started\\.\\.\\.$", + "endsPattern": "^built in (\\d+ms)" + } + } + } + ] +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index 72aa0fe..88db945 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,6 +1,9 @@ .vscode/** .vscode-test/** src/** +images/** +env/** +types/** .gitignore .yarnrc vsc-extension-quickstart.md diff --git a/env/.env b/env/.env new file mode 100644 index 0000000..2fbbc82 --- /dev/null +++ b/env/.env @@ -0,0 +1,6 @@ +# 日志等级 +VITE_LOG_LEVEL = Debug +# 日志打印格式 +VITE_LOG_FORMAT = :time :level: :msg +# 输出窗口名称 +VITE_OUTPUT_CHANNEL_NAME = Format Files By Ignores \ No newline at end of file diff --git a/env/.env.production b/env/.env.production new file mode 100644 index 0000000..6d48be5 --- /dev/null +++ b/env/.env.production @@ -0,0 +1,4 @@ +# 生产发布 + +# 日志打印格式 +VITE_LOG_LEVEL = Info \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9055611..f36957a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "format-files-by-ignores", - "version": "1.0.0", + "version": "1.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "format-files-by-ignores", - "version": "1.0.0", + "version": "1.0.8", "dependencies": { "ignore": "^5.3.1" }, @@ -16,13 +16,14 @@ "@types/mocha": "^10.0.6", "@types/node": "18.x", "@types/vscode": "^1.87.0", - "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "@vscode/test-cli": "^0.0.6", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^2.24.0", "eslint": "^8.56.0", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "vite": "^5.2.5" }, "engines": { "vscode": "^1.87.0" @@ -74,6 +75,32 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/runtime": { "version": "7.24.1", "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.24.1.tgz", @@ -190,6 +217,32 @@ "changeset": "bin.js" } }, + "node_modules/@changesets/cli/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/cli/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@changesets/config": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/@changesets/config/-/config-3.0.0.tgz", @@ -227,6 +280,32 @@ "semver": "^7.5.3" } }, + "node_modules/@changesets/get-dependents-graph/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/get-dependents-graph/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@changesets/get-github-info": { "version": "0.6.0", "resolved": "https://registry.npmmirror.com/@changesets/get-github-info/-/get-github-info-0.6.0.tgz", @@ -282,6 +361,32 @@ "chalk": "^2.1.0" } }, + "node_modules/@changesets/logger/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/logger/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@changesets/parse": { "version": "0.4.0", "resolved": "https://registry.npmmirror.com/@changesets/parse/-/parse-0.4.0.tgz", @@ -321,6 +426,32 @@ "p-filter": "^2.1.0" } }, + "node_modules/@changesets/read/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/read/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@changesets/types": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/@changesets/types/-/types-6.0.0.tgz", @@ -340,6 +471,22 @@ "prettier": "^2.7.1" } }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -667,6 +814,19 @@ "node": ">=14" } }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz", @@ -676,6 +836,12 @@ "node": ">= 6" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -973,6 +1139,20 @@ "concat-map": "0.0.1" } }, + "node_modules/@vscode/vsce/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@vscode/vsce/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", @@ -1026,6 +1206,18 @@ "node": "*" } }, + "node_modules/@vscode/vsce/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@vscode/vsce/node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmmirror.com/tmp/-/tmp-0.2.3.tgz", @@ -1477,32 +1669,6 @@ "node": ">=8" } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmmirror.com/chardet/-/chardet-0.7.0.tgz", @@ -2232,6 +2398,44 @@ "node": ">= 0.4" } }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.2.tgz", @@ -2774,20 +2978,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", @@ -4368,6 +4558,18 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -4761,6 +4963,20 @@ "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prebuild-install": { "version": "7.1.2", "resolved": "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.2.tgz", @@ -5201,6 +5417,38 @@ "node": "*" } }, + "node_modules/rollup": { + "version": "4.13.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5552,6 +5800,15 @@ "node": ">=6" } }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spawndamnit": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/spawndamnit/-/spawndamnit-2.0.0.tgz", @@ -6326,6 +6583,58 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/vite": { + "version": "5.2.5", + "resolved": "https://registry.npmmirror.com/vite/-/vite-5.2.5.tgz", + "integrity": "sha512-a+rTAqkMmJ2hQpC6dfAyyc5M0YLH3BGZKLpA6pU9AhzlcK1YZS8P/ov9OcdHxaf+j0sM0DIh/txH7ydTHUpISg==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.36", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index 23d22b5..d38c51a 100644 --- a/package.json +++ b/package.json @@ -83,13 +83,13 @@ }, "scripts": { "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./", - "watch": "tsc -watch -p ./", - "pretest": "npm run compile && npm run lint", - "lint": "eslint src --ext ts", - "test": "vscode-test", + "compile": "vite build", + "watch": "vite build --watch --mode development --emptyOutDir", + "pretest": "npm run compile && npm run lint:fix", + "lint:fix": "eslint --ext .ts,.mts,.d.ts --fix .", "changeset": "changeset", - "vsce-publish": "vsce publish" + "vsce:publish": "vsce publish", + "vsce:package": "vsce package" }, "devDependencies": { "@changesets/changelog-github": "^0.5.0", @@ -97,13 +97,14 @@ "@types/mocha": "^10.0.6", "@types/node": "18.x", "@types/vscode": "^1.87.0", - "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "@vscode/test-cli": "^0.0.6", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^2.24.0", "eslint": "^8.56.0", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "vite": "^5.2.5" }, "dependencies": { "ignore": "^5.3.1" diff --git a/src/commands/command.ts b/src/commands/command.ts index 9ebdd64..f34540f 100644 --- a/src/commands/command.ts +++ b/src/commands/command.ts @@ -1,15 +1,16 @@ import * as vscode from 'vscode'; import { Message } from '../util/message'; import { OperationAborted } from '../error'; +import { Logger } from '../util/logger'; /** * 配置 */ export interface Options { - /** - * 注册 key - */ - key: string + /** + * 注册 key + */ + key: string } /** @@ -17,43 +18,54 @@ export interface Options { */ export abstract class Command { - constructor(protected options: Options) { } - - /** - * 命令回调 - * @param _args 任意回调参数 - */ - async callback(..._args: any[]): Promise { } - - /** - * 回调抛出异常时执行 - * @param error 异常 - */ - async catch(error: Error) { - if (error instanceof OperationAborted) { - Message.showWarningMessage(error.message); - } else { - Message.showErrorMessage(error.message); - } - } + constructor(protected options: Options) { } + + /** + * 命令回调 + * @param _args 任意回调参数 + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async callback(..._args: any[]): Promise { } - /** - * 注册指令 - * @param context 上下文 - */ - async activate(context: vscode.ExtensionContext) { - let disposable = vscode.commands.registerCommand(this.options.key, async (...args: any[]) => { - try { - return await this.callback(...args); - } catch (error) { - await this.catch(error as Error); - } - }); - context.subscriptions.push(disposable); + /** + * 回调抛出异常时执行 + * @param error 异常 + */ + async catch(error: Error) { + if (error instanceof OperationAborted) { + Message.showWarningMessage(error.message); + return; } + vscode.window.showErrorMessage(error.message); + Logger.error(error.stack ?? error.message); + } + + /** + * 注册指令 + * @param context 上下文 + */ + async activate(context: vscode.ExtensionContext) { + Logger.debug(`Register command: ${this.options.key}`); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const callback = async (...args: any[]) => { + Logger.debug(`Command '${this.options.key}' callback args: ${args}`); + try { + return await this.callback(...args); + } catch (error) { + await this.catch(error as Error); + } + }; + + context.subscriptions.push( + vscode.commands.registerCommand(this.options.key, callback) + ); + } - /** - * 注销指令 - */ - async deactivate() { } + /** + * 注销指令 + */ + async deactivate() { + Logger.debug('Deactivate command: ' + this.options.key); + } } \ No newline at end of file diff --git a/src/commands/formatFolder.ts b/src/commands/formatFolder.ts index ab7f226..d9d2300 100644 --- a/src/commands/formatFolder.ts +++ b/src/commands/formatFolder.ts @@ -6,7 +6,7 @@ import { OperationAborted } from '../error'; import { FormatConfig } from '../config'; import { Logger } from '../util/logger'; import { Message } from '../util/message'; -import { Command } from "./command"; +import { Command } from './command'; import path from 'path'; /** @@ -14,51 +14,54 @@ import path from 'path'; */ export class FormatFolder extends Command { - /** - * 格式化开始前确认 - * @param folder 文件夹路径 - * @throws {OperationAborted} 取消中断 - */ - private async confirmStartFormat(folder: string) { - const result = await window.showQuickPick([`Yes`, `No`], { - title: `Start formatting workspace (${path.basename(folder)}) files?`, - ignoreFocusOut: true, - placeHolder: `Please check '${Logger.outputchannelName}' output for list of files`, - }); + /** + * 格式化开始前确认 + * @param folder 文件夹路径 + * @throws {OperationAborted} 取消中断 + */ + private async confirmStartFormat(folder: string) { + const result = await window.showQuickPick(['Yes', 'No'], { + title: `Start formatting workspace (${path.basename(folder)}) files?`, + ignoreFocusOut: true, + placeHolder: `Please check '${Logger.outputChannelName}' output for list of files`, + }); - if (!result || result === 'No') { - // 中断放弃 - throw new OperationAborted('Format cancelled'); - } + if (!result || result === 'No') { + // 中断放弃 + throw new OperationAborted('Format cancelled'); } + } - async callback(folder: Uri): Promise { + async callback(folder: Uri): Promise { + Logger.debug('Format folder root: ' + folder); - // 工作空间存在多个文件夹时根目录右键选择异常 {} - // 修正为:让用户自行选择文件夹 - folder = (await selectWorkspace(folder)).uri; + // 工作空间存在多个文件夹时根目录右键选择异常 {} + // 修正为:让用户自行选择工作空间文件夹 + if (Object.keys(folder).length === 0) { + folder = (await selectWorkspace()).uri; + } - // 清空日志, 打开输出面板 - Logger.outputChannel.show(true); + // 打开输出面板 + Logger.show(true); - // 筛选全部需要格式化的文件 - const files = filterFolderByignore( - folder.fsPath, - // 全局扩展 - FormatConfig.config.ignoreExtension, - // ignore 文件名称 - FormatConfig.config.ignoreFileNames - ); + // 筛选全部需要格式化的文件 + const files = filterFolderByignore( + folder.fsPath, + // 全局扩展 + FormatConfig.config.ignoreExtension, + // ignore 文件名称 + FormatConfig.config.ignoreFileNames + ); - // 供用户检查 - Logger.instance.info('Format files:'); - files.forEach(files => Logger.instance.info(files)); + // 供用户检查 + Logger.info('Format files:'); + files.forEach(files => Logger.info(files)); - // 用户确认 - await this.confirmStartFormat(folder.fsPath); + // 用户确认 + await this.confirmStartFormat(folder.fsPath); - // 开始格式化 - await formatDocs(files.map(Uri.file)); - Message.showInformationMessage('Format files completed'); - } + // 开始格式化 + await formatDocs(files.map(Uri.file)); + Message.showInformationMessage('Format files completed'); + } } \ No newline at end of file diff --git a/src/commands/formatWorkspace.ts b/src/commands/formatWorkspace.ts index 1d1eea5..862e1d8 100644 --- a/src/commands/formatWorkspace.ts +++ b/src/commands/formatWorkspace.ts @@ -1,14 +1,15 @@ import { FormatFolder } from './formatFolder'; import { selectWorkspace } from '../util/workspace'; +import { Logger } from '../util/logger'; /** * 格式化工作空间 */ export class FilterWorkspace extends FormatFolder { - - async callback(): Promise { - const wp = await selectWorkspace(); - // 开始格式化 - await super.callback(wp.uri); - } + async callback(): Promise { + const wp = await selectWorkspace(); + Logger.debug('Format workspace root: ' + wp.uri); + // 开始格式化 + await super.callback(wp.uri); + } } \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index e2d7786..2b32273 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,28 +1,28 @@ -import { workspace } from "vscode"; +import { workspace } from 'vscode'; export interface Config { - /** - * 忽略扩展(仅限根目录) - */ - ignoreExtension: [] - /** - * ignore 文件名称 - * - * 比如: .gitignore - */ - ignoreFileNames: string[] + + // todo 添加是否开启忽略扩展 + /** + * 忽略扩展(仅限根目录) + */ + ignoreExtension: [] + /** + * ignore 文件名称 + * + * 比如: .gitignore + */ + ignoreFileNames: string[] } /** * 全局配置 */ export class FormatConfig { - - public static get config(): Config { - return workspace.getConfiguration().get('formatFilesByIgnores', { - ignoreExtension: [], - ignoreFileNames: [] - }); - } - + public static get config(): Config { + return workspace.getConfiguration().get('formatFilesByIgnores', { + ignoreExtension: [], + ignoreFileNames: [] + }); + } } \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index c2b8288..e7b939b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -5,23 +5,23 @@ import { FormatFolder } from './commands/formatFolder'; import { FilterWorkspace } from './commands/formatWorkspace'; const commands: Command[] = [ - // 文件夹格式化 - new FormatFolder({ - key: 'formatFilesByIgnores.start.formatFolder' - }), - // 工作空间格式化 - new FilterWorkspace({ - key: 'formatFilesByIgnores.start.formatWorkspace' - }) + // 文件夹格式化 + new FormatFolder({ + key: 'formatFilesByIgnores.start.formatFolder' + }), + // 工作空间格式化 + new FilterWorkspace({ + key: 'formatFilesByIgnores.start.formatWorkspace' + }) ]; export function activate(context: vscode.ExtensionContext) { - Logger.instance.debug('activate'); - // 注册命令 - commands.forEach(c => c.activate(context)); + Logger.debug('activate'); + // 注册命令 + commands.forEach(c => c.activate(context)); } export function deactivate() { - Logger.instance.debug('deactivate'); - commands.forEach(c => c.deactivate()); + Logger.debug('deactivate'); + commands.forEach(c => c.deactivate()); } diff --git a/src/util/doc.ts b/src/util/doc.ts index 2d0ec7b..3068703 100644 --- a/src/util/doc.ts +++ b/src/util/doc.ts @@ -1,5 +1,6 @@ import { ProgressLocation, Uri, ViewColumn, commands, window, workspace } from 'vscode'; import { OperationAborted } from '../error'; +import { Logger } from './logger'; /** * 尝试打开文档 @@ -7,22 +8,23 @@ import { OperationAborted } from '../error'; * @returns */ export async function tryOpenDoc(doc: Uri) { - try { - return await workspace.openTextDocument(doc.fsPath); - } catch (_) { } + try { + return await workspace.openTextDocument(doc.fsPath); + } catch (_) { } } + /** * 利用 vscode 内置指令格式化文件 * @param doc 文档路径 */ export async function formatDoc(doc: Uri): Promise { - if (await tryOpenDoc(doc)) { - await window.showTextDocument(doc, { preview: false, viewColumn: ViewColumn.One }); - await commands.executeCommand('editor.action.formatDocument'); - await commands.executeCommand('workbench.action.files.save'); - // todo 记录执行命令前文件状态, 已经打开的则不关闭 - await commands.executeCommand('workbench.action.closeActiveEditor'); - } + if (await tryOpenDoc(doc)) { + await window.showTextDocument(doc, { preview: false, viewColumn: ViewColumn.One }); + await commands.executeCommand('editor.action.formatDocument'); + await commands.executeCommand('workbench.action.files.save'); + // todo 记录执行命令前文件状态, 已经打开的则不关闭 + await commands.executeCommand('workbench.action.closeActiveEditor'); + } } /** @@ -30,27 +32,29 @@ export async function formatDoc(doc: Uri): Promise { * @param docs 档路径集合 * @throws {OperationAborted} 取消中断 */ -export async function formatDocs(docs: Uri[]): Promise { - // 进度 - const increment = (1 / docs.length) * 100; - // 进度条 - await window.withProgress( - { - cancellable: true, - location: ProgressLocation.Notification, - title: 'Formatting documents' - }, - async (progress, token) => { - for (const file of docs) { - if (token.isCancellationRequested) { - // 中断取消 - throw new OperationAborted('Format cancelled'); - } - progress.report({ message: file.fsPath, increment }); - await formatDoc(file); - } - progress.report({ increment: 100 }); +export async function formatDocs(docs: Uri[]) { + // 进度 + const increment = (1 / docs.length) * 100; + + // 进度条 + await window.withProgress( + { + cancellable: true, + location: ProgressLocation.Notification, + title: 'Formatting documents' + }, + async (progress, token) => { + for (const file of docs) { + if (token.isCancellationRequested) { + // 中断取消 + throw new OperationAborted('Format cancelled'); } - ); + progress.report({ message: file.fsPath, increment }); + Logger.debug('Format: ' + file); + await formatDoc(file); + } + progress.report({ increment: 100 }); + } + ); } diff --git a/src/util/folder.ts b/src/util/folder.ts index a61b6b3..a0dd864 100644 --- a/src/util/folder.ts +++ b/src/util/folder.ts @@ -10,40 +10,46 @@ import { Logger } from './logger'; * @param ignoreFileNames ignore 文件名称 * @returns */ -export function filterFolderByignore(root: string, ext: string[], ignoreFileNames: string[]): string[] { - const res: string[] = []; +export function filterFolderByignore( + root: string, ext: string[], ignoreFileNames: string[] +): string[] { - if (!fs.existsSync(root)) { - return res; - } + const res: string[] = []; + + if (!fs.existsSync(root)) { + Logger.debug('Folder not exists: ' + root); + return res; + } - const filter = ignore({ allowRelativePaths: true }).add(ext); + const filter = ignore({ allowRelativePaths: true }).add(ext); - // 获取过滤规则 - for (const ignoreFileName of ignoreFileNames) { - const ignoreFile = path.resolve(root, ignoreFileName); - if (fs.existsSync(ignoreFile)) { - filter.add(fs.readFileSync(ignoreFile, 'utf-8')); - } + // 获取过滤规则 + for (const ignoreFileName of ignoreFileNames) { + const ignoreFile = path.resolve(root, ignoreFileName); + if (fs.existsSync(ignoreFile)) { + Logger.debug('Find ignore file: ' + ignoreFile); + filter.add(fs.readFileSync(ignoreFile, 'utf-8')); } + } - // 前置文件夹过滤 - const files = filter.filter(fs.readdirSync(root)); - - for (const file of files.map(f => path.join(root, f))) { - // 文件可能不存在异常 - if (!fs.existsSync(file)) { - continue; - } - const fileStat = fs.statSync(file); - if (fileStat.isDirectory()) { - // 递归遍历 - res.push(...filterFolderByignore(file, [], ignoreFileNames)); - } else { - res.push(file); - } + // 前置文件夹过滤 + const files = filter.filter(fs.readdirSync(root)); + + for (const file of files.map(f => path.join(root, f))) { + // 文件可能不存在异常 + if (!fs.existsSync(file)) { + Logger.debug('File not exists: ' + file); + continue; + } + const fileStat = fs.statSync(file); + if (fileStat.isDirectory()) { + // 递归遍历 + res.push(...filterFolderByignore(file, [], ignoreFileNames)); + } else { + res.push(file); } + } - // 后置兜底过滤 - return filter.filter(res); + // 后置兜底过滤 + return filter.filter(res); } \ No newline at end of file diff --git a/src/util/logger.ts b/src/util/logger.ts index 58e9b2e..40bf307 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -1,61 +1,52 @@ -import { LogLevel, window } from "vscode"; - -export interface LoggerOptions { - format: string -} +import { LogLevel, window } from 'vscode'; /** * 日志 */ export class Logger { - // ouput 显示名称 - public static readonly outputchannelName = 'Format Files By Ignores'; - - // output 输出 - public static readonly outputChannel = window.createOutputChannel(Logger.outputchannelName); + public static readonly outputChannelName = import.meta.env.VITE_OUTPUT_CHANNEL_NAME; - // 等级 - // todo 通过 env 获取 - public static logLevel: LogLevel = LogLevel.Debug; + // output 输出 + private static readonly outputChannel = window.createOutputChannel(Logger.outputChannelName); - // 显示格式 - public static instance: Logger = new Logger({ - format: ':time :level: :msg' - }); + // 日志级别 + public static logLevel: LogLevel = LogLevel[import.meta.env.VITE_LOG_LEVEL]; - constructor(private options: LoggerOptions) { } + public static info(msg: string) { + Logger.log(LogLevel.Info, msg); + } - public info(msg: string) { - this.log(LogLevel.Info, msg); - } + public static debug(msg: string) { + Logger.log(LogLevel.Debug, msg); + } - public debug(msg: string) { - this.log(LogLevel.Debug, msg); - } + public static warning(msg: string) { + Logger.log(LogLevel.Warning, msg); + } - public warning(msg: string) { - this.log(LogLevel.Warning, msg); - } - - public error(msg: string) { - this.log(LogLevel.Error, msg); - } + public static error(msg: string) { + Logger.log(LogLevel.Error, msg); + } - public log(level: LogLevel, msg: string) { - if (Logger.logLevel > level || Logger.logLevel === LogLevel.Off) { - return; - } - const replaces: [string, string][] = [ - [':time', new Date().toLocaleString()], - [':msg', msg], - [':level', LogLevel[level]] - ]; - const line = replaces.reduce( - (f, r) => f.replace(r[0], r[1]), - this.options.format - ); - Logger.outputChannel.appendLine(line); + public static log(level: LogLevel, msg: string) { + if (Logger.logLevel > level || Logger.logLevel === LogLevel.Off) { + return; } + const replaces: [string, string][] = [ + [':time', new Date().toLocaleString()], + [':msg', msg], + [':level', LogLevel[level].padStart(6, ' ')] + ]; + const line = replaces.reduce( + (f, r) => f.replace(r[0], r[1]), + import.meta.env.VITE_LOG_FORMAT + ); + Logger.outputChannel.appendLine(line); + } + + public static show(preserveFocus?: boolean) { + Logger.outputChannel.show(preserveFocus); + } } \ No newline at end of file diff --git a/src/util/message.ts b/src/util/message.ts index a5a7847..4de056f 100644 --- a/src/util/message.ts +++ b/src/util/message.ts @@ -1,23 +1,23 @@ -import { window } from "vscode"; -import { Logger } from "./logger"; +import { window } from 'vscode'; +import { Logger } from './logger'; /** * 消息弹窗加日志打印 */ export class Message { - public static showInformationMessage(msg: string, ...items: string[]) { - window.showInformationMessage(msg, ...items); - Logger.instance.info(msg); - } + public static showInformationMessage(msg: string, ...items: string[]) { + window.showInformationMessage(msg, ...items); + Logger.info(msg); + } - public static showErrorMessage(msg: string, ...items: string[]) { - window.showErrorMessage(msg, ...items); - Logger.instance.error(msg); - } + public static showErrorMessage(msg: string, ...items: string[]) { + window.showErrorMessage(msg, ...items); + Logger.error(msg); + } - public static showWarningMessage(msg: string, ...items: string[]) { - window.showWarningMessage(msg, ...items); - Logger.instance.warning(msg); - } + public static showWarningMessage(msg: string, ...items: string[]) { + window.showWarningMessage(msg, ...items); + Logger.warning(msg); + } } \ No newline at end of file diff --git a/src/util/workspace.ts b/src/util/workspace.ts index db48c1d..e5db1c9 100644 --- a/src/util/workspace.ts +++ b/src/util/workspace.ts @@ -1,42 +1,34 @@ -import { Uri, WorkspaceFolder, window, workspace } from 'vscode'; +import { WorkspaceFolder, window, workspace } from 'vscode'; import { OperationAborted } from '../error'; /** - * 通过路径选择工作空间, 不存在则让用户选择 - * @param folder 工作空间路径 - * @throws {OperationAborted} workspace 未打开, 用户取消 中断 + * 选择工作空间 + * @throws {OperationAborted} workspace 未打开, 用户取消 * @returns */ -export async function selectWorkspace(folder?: Uri): Promise { - const wps = workspace.workspaceFolders; - - const fwps = wps?.find(w => w.uri.fsPath === folder?.fsPath); - - if (folder && wps && fwps) { - // 有默认就使用默认 - return fwps; - } - - // 未打开工作空间 - if (wps === undefined || wps.length === 0) { - throw new OperationAborted('Workspace not open'); - } - - // 只有一个工作空间则直接返回不需要选择 - if (wps.length === 1) { - return wps[0]; - } - - const result = await window.showQuickPick(wps.map(w => w.name), { - title: `Select the workspace that needs to be formatted`, - ignoreFocusOut: true, - placeHolder: `Select workspace`, - }); - - // 取消选择 - if (!result) { - throw new OperationAborted('Select workspace cancelled'); - } - - return wps.find(w => w.name === result)!; +export async function selectWorkspace(): Promise { + const wps = workspace.workspaceFolders; + + // 未打开工作空间 + if (wps === undefined || wps.length === 0) { + throw new OperationAborted('Workspace not open'); + } + + // 只有一个工作空间则直接返回不需要选择 + if (wps.length === 1) { + return wps[0]; + } + + const result = await window.showQuickPick(wps.map(w => w.name), { + title: 'Select the workspace that needs to be formatted', + ignoreFocusOut: true, + placeHolder: 'Select workspace', + }); + + // 取消选择 + if (!result) { + throw new OperationAborted('Select workspace cancelled'); + } + + return wps.find(w => w.name === result)!; } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 7127ce7..dcb3036 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,26 @@ { - "compilerOptions": { - "module": "Node16", - "target": "ES2022", - "outDir": "out", - "lib": [ - "ES2022" - ], - "sourceMap": true, - "rootDir": "src", - "moduleResolution": "NodeNext", - "strict": true /* enable all strict type-checking options */ - /* Additional Checks */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - } + "compilerOptions": { + "module": "ESNext", + "target": "ESNext", + "outDir": "out", + "lib": [ + "ESNext" + ], + "types": [ + "vite/client" + ], + "sourceMap": true, + "strict": true, + "declaration": true, + "noEmit": true, + "esModuleInterop": true, + "skipLibCheck": true, + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true + }, + "include": [ + "src", + "types", + "vite.config.mts" + ] } \ No newline at end of file diff --git a/types/env.d.ts b/types/env.d.ts new file mode 100644 index 0000000..047f7d1 --- /dev/null +++ b/types/env.d.ts @@ -0,0 +1,27 @@ +interface ImportMetaEnv { + /** + * 日志等级 + */ + readonly VITE_LOG_LEVEL: keyof typeof import('vscode').LogLevel + + /** + * 日志打印格式 + * + * ``` + * :time 时间戳 + * :level 等级 + * :msg 消息 + * ``` + */ + readonly VITE_LOG_FORMAT: string + + /** + * 输出窗口名称 + */ + readonly VITE_OUTPUT_CHANNEL_NAME: string +} + +interface ImportMeta { + url: string + readonly env: ImportMetaEnv +} \ No newline at end of file diff --git a/vite.config.mts b/vite.config.mts new file mode 100644 index 0000000..3cf7930 --- /dev/null +++ b/vite.config.mts @@ -0,0 +1,24 @@ +import { defineConfig } from 'vite'; +import { dependencies } from './package.json'; + +export default defineConfig({ + envDir: 'env', + build: { + minify: false, + rollupOptions: { + preserveEntrySignatures: 'strict', + input: './src/extension.ts', + external: [ + ...Object.keys(dependencies), + 'vscode', + 'fs', + 'path' + ], + output: { + dir: 'out', + format: 'cjs', + entryFileNames: 'extension.js' + } + } + } +}); \ No newline at end of file