diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 784103a..10369fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,3 +35,6 @@ jobs: - name: Set up Xvfb and Run vscode-test run: xvfb-run -a yarn test:vscode + + - name: Run Mocha tests + run: yarn test:mocha diff --git a/package.json b/package.json index f53ee64..b2cbd3a 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "pretest": "yarn run compile && yarn run lint", "lint": "eslint src --ext ts", "test:vscode": "vscode-test", + "test:mocha": "mocha --require ts-node/register src/test/**/*.spec.ts", "lint-staged": "lint-staged", "prepare": "husky" }, @@ -70,7 +71,9 @@ "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "lint-staged": "^15.2.2", + "mocha": "^10.4.0", "prettier": "^3.2.5", + "ts-node": "^10.9.2", "typescript": "^5.3.3" } -} +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 71f6c38..29794fa 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,4 +1,5 @@ import * as vscode from "vscode"; +import { generateFileNameComment } from "./utils/generateFileNameComment"; export function activate(context: vscode.ExtensionContext) { // YOCO.copyTextWithFilePath @@ -14,13 +15,17 @@ export function activate(context: vscode.ExtensionContext) { const text = document.getText(selection); // settings의 YOCO.includeFilePath가 true일 경우에만 실행 - const includeFilePath = vscode.workspace.getConfiguration("YOCO").get("includeFilePath"); + const includeFilePath = vscode.workspace + .getConfiguration("YOCO") + .get("includeFilePaths", false); + const fileIdentifier = includeFilePath + ? document.uri.path + : document.uri.path.split("/").pop() || "Untitled"; + const comment = generateFileNameComment(document.languageId, fileIdentifier); - const filePath = document.uri.path; + await vscode.env.clipboard.writeText(`${comment}\n${text}`); - const comment = `// ${includeFilePath ? filePath : filePath.split("/").pop()}\n`; - - vscode.env.clipboard.writeText(comment + text); + vscode.window.showInformationMessage("Text with file identifier copied to clipboard!"); }); context.subscriptions.push(disposable); diff --git a/src/test/utils/generateFileNameComment.spec.ts b/src/test/utils/generateFileNameComment.spec.ts new file mode 100644 index 0000000..624da8d --- /dev/null +++ b/src/test/utils/generateFileNameComment.spec.ts @@ -0,0 +1,39 @@ +import assert from "assert"; +import { generateFileNameComment } from "../../utils/generateFileNameComment"; + +describe("generateFileNameComment", function () { + const testCases: Record< + string, + { languageId: string; fileIdentifier: string; expectedComment: string } + > = { + javascript: { + languageId: "javascript", + fileIdentifier: "example.js", + expectedComment: "// example.js", + }, + python: { languageId: "python", fileIdentifier: "example.py", expectedComment: "# example.py" }, + html: { + languageId: "html", + fileIdentifier: "example.html", + expectedComment: "", + }, + css: { languageId: "css", fileIdentifier: "example.css", expectedComment: "/* example.css */" }, + latex: { languageId: "latex", fileIdentifier: "example.tex", expectedComment: "% example.tex" }, + plaintext: { + languageId: "plaintext", + fileIdentifier: "example.txt", + expectedComment: "example.txt", + }, + unrecognized: { + languageId: "nonexistent-language", + fileIdentifier: "example.unknown", + expectedComment: "// example.unknown", + }, + }; + + Object.values(testCases).forEach(({ languageId, fileIdentifier, expectedComment }) => { + it(`should return correct comment format for ${languageId}`, function () { + assert.strictEqual(generateFileNameComment(languageId, fileIdentifier), expectedComment); + }); + }); +}); diff --git a/src/utils/generateFileNameComment.ts b/src/utils/generateFileNameComment.ts new file mode 100644 index 0000000..94e7bb4 --- /dev/null +++ b/src/utils/generateFileNameComment.ts @@ -0,0 +1,86 @@ +/** + * Generates a comment with file name and prefix/suffix based on the given language identifier. + * @param languageId VSCode Language Identifier (https://code.visualstudio.com/docs/languages/identifiers) + * @param fileIdentifier File name or file path + * @returns Comment with file name and prefix/suffix based on the given language identifier + */ +export function generateFileNameComment(languageId: string, fileIdentifier: string): string { + const commentStyles: Record = { + "double-slash": [ + "c", + "cpp", + "csharp", + "cuda-cpp", + "d", + "go", + "groovy", + "java", + "javascript", + "javascriptreact", + "jsonc", + "objective-c", + "objective-cpp", + "rust", + "swift", + "typescript", + "typescriptreact", + "shaderlab", + ], + hash: [ + "coffeescript", + "perl", + "python", + "r", + "ruby", + "shellscript", + "yaml", + "dockercompose", + "dockerfile", + "erlang", + "git-commit", + "git-rebase", + "ini", + "makefile", + "powershell", + ], + "html-like": ["html", "markdown", "svelte", "vue", "vue-html", "xml", "xsl"], + "multi-line": ["css", "less", "scss", "stylus"], + percent: ["bibtex", "latex", "tex"], + semicolon: ["clojure"], + "lua-style": ["lua"], + "razor-style": ["razor"], + "sql-style": ["sql"], + "vb-style": ["vb"], + "handlebars-style": ["handlebars"], + "abap-style": ["abap"], + "batch-style": ["bat"], + "fsharp-style": ["fsharp", "haskell", "ocaml"], + plaintext: ["plaintext"], + }; + + const commentPrefixes: Record = { + "double-slash": `// ${fileIdentifier}`, + hash: `# ${fileIdentifier}`, + "html-like": ``, + "multi-line": `/* ${fileIdentifier} */`, + percent: `% ${fileIdentifier}`, + semicolon: `;; ${fileIdentifier}`, + "lua-style": `-- ${fileIdentifier}`, + "razor-style": `@* ${fileIdentifier} *@`, + "sql-style": `-- ${fileIdentifier}`, + "vb-style": `' ${fileIdentifier}`, + "handlebars-style": `{{!-- ${fileIdentifier} --}}`, + "abap-style": `" ${fileIdentifier}`, + "batch-style": `REM ${fileIdentifier}`, + "fsharp-style": `(* ${fileIdentifier} *)`, + plaintext: fileIdentifier, + }; + + for (const [style, languages] of Object.entries(commentStyles)) { + if (languages.includes(languageId)) { + return commentPrefixes[style]; + } + } + + return `// ${fileIdentifier}`; +} diff --git a/tsconfig.json b/tsconfig.json index 6954702..5707de3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "module": "Node16", "target": "ES2022", "outDir": "out", + "esModuleInterop": true, "lib": [ "ES2022" ], diff --git a/yarn.lock b/yarn.lock index 8c47bc1..aec117f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -191,6 +191,13 @@ "@types/conventional-commits-parser" "^5.0.0" chalk "^5.3.0" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -259,16 +266,24 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jridgewell/resolve-uri@^3.1.0": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.4.14": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.12": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" @@ -313,6 +328,26 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tsconfig/node10@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@types/conventional-commits-parser@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz#8c9d23e0b415b24b91626d07017303755d542dc8" @@ -488,7 +523,12 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.9.0: +acorn-walk@^8.1.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + +acorn@^8.4.1, acorn@^8.9.0: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -567,6 +607,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -829,6 +874,11 @@ cosmiconfig@^9.0.0: js-yaml "^4.1.0" parse-json "^5.2.0" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -865,6 +915,11 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1704,6 +1759,11 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + meow@^12.0.1: version "12.1.1" resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" @@ -1775,7 +1835,7 @@ minimist@^1.2.8: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -mocha@^10.2.0: +mocha@^10.2.0, mocha@^10.4.0: version "10.4.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261" integrity sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA== @@ -2306,6 +2366,25 @@ ts-api-utils@^1.3.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" @@ -2350,6 +2429,11 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-to-istanbul@^9.0.0: version "9.2.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" @@ -2478,6 +2562,11 @@ yargs@^17.0.0, yargs@^17.7.2: y18n "^5.0.5" yargs-parser "^21.1.1" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"