├── .commitlintrc.yml ├── .gitattributes ├── .github └── workflows │ ├── publish.yml │ └── tests.yml ├── .gitignore ├── .husky ├── commit-msg ├── pre-commit └── pre-push ├── .lintstagedrc.yml ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets ├── sass.png └── scss-format.gif ├── eslint.config.js ├── package-lock.json ├── package.json ├── package.nls.json ├── scripts └── check-engine.js ├── src ├── FormatProvider.ts ├── FormatService.ts ├── LoggingService.ts ├── StatusBarService.ts ├── extension.ts ├── test │ ├── runTest-web.ts │ ├── runTest.ts │ └── suite │ │ ├── extension.test.ts │ │ ├── index-node.ts │ │ └── index-web.ts └── utils.ts ├── test-workspace ├── fixtures │ ├── play.css │ ├── ugly.css │ └── ugly.scss └── test.code-workspace ├── tsconfig-test-web.json ├── tsconfig.json └── webpack.config.js /.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behavior to automatically normalize line endings. 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | push: 5 | tags: v* 6 | 7 | env: 8 | NODE_VERSION: 20 9 | 10 | jobs: 11 | test: 12 | name: Publish to Markeplace 13 | runs-on: macos-latest 14 | 15 | environment: 16 | name: marketplace 17 | url: ${{ vars.MARKETPLACE_URL }} 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | 23 | - name: Setup Node.js ${{ env.NODE_VERSION }} 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: ${{ env.NODE_VERSION }} 27 | cache: npm 28 | 29 | - name: NPM Install 30 | run: | 31 | npm ci 32 | npm ls --depth=0 33 | 34 | - name: Publish 35 | run: npm run deploy 36 | env: 37 | VSCE_PAT: ${{ secrets.VSCE_PAT }} 38 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: master 6 | pull_request: 7 | branches: master 8 | 9 | env: 10 | NODE_VERSION: 20 11 | 12 | jobs: 13 | test: 14 | name: Extension Tests 15 | runs-on: macos-latest 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - name: Setup Node.js ${{ env.NODE_VERSION }} 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: ${{ env.NODE_VERSION }} 25 | cache: npm 26 | 27 | - name: NPM Install 28 | run: | 29 | npm ci 30 | npm ls --depth=0 31 | 32 | - name: Build 33 | run: npm run compile 34 | 35 | - name: Compile node tests 36 | run: npm run compile-tests 37 | 38 | # - name: Compile web tests 39 | # run: npm run compile-tests-web 40 | 41 | - name: Vscode test 42 | run: npm run test 43 | 44 | # - name: Compile web tests 45 | # run: npm run test-web 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Linux ### 2 | *~ 3 | 4 | # temporary files which can be created if a process still has a handle open of a deleted file 5 | .fuse_hidden* 6 | 7 | # KDE directory preferences 8 | .directory 9 | 10 | # Linux trash folder which might appear on any partition or disk 11 | .Trash-* 12 | 13 | # .nfs files are created when an open file is removed but is still being accessed 14 | .nfs* 15 | 16 | ### macOS ### 17 | # General 18 | .DS_Store 19 | .AppleDouble 20 | .LSOverride 21 | 22 | # Icon must end with two \r 23 | Icon 24 | 25 | # Thumbnails 26 | ._* 27 | 28 | # Files that might appear in the root of a volume 29 | .DocumentRevisions-V100 30 | .fseventsd 31 | .Spotlight-V100 32 | .TemporaryItems 33 | .Trashes 34 | .VolumeIcon.icns 35 | .com.apple.timemachine.donotpresent 36 | 37 | # Directories potentially created on remote AFP share 38 | .AppleDB 39 | .AppleDesktop 40 | Network Trash Folder 41 | Temporary Items 42 | .apdisk 43 | 44 | ### Node ### 45 | # Logs 46 | logs 47 | *.log 48 | npm-debug.log* 49 | yarn-debug.log* 50 | yarn-error.log* 51 | 52 | # Runtime data 53 | pids 54 | *.pid 55 | *.seed 56 | *.pid.lock 57 | 58 | # Directory for instrumented libs generated by jscoverage/JSCover 59 | lib-cov 60 | 61 | # Coverage directory used by tools like istanbul 62 | coverage 63 | 64 | # nyc test coverage 65 | .nyc_output 66 | 67 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 68 | .grunt 69 | 70 | # Bower dependency directory (https://bower.io/) 71 | bower_components 72 | 73 | # node-waf configuration 74 | .lock-wscript 75 | 76 | # Compiled binary addons (https://nodejs.org/api/addons.html) 77 | build/Release 78 | 79 | # Dependency directories 80 | node_modules/ 81 | jspm_packages/ 82 | 83 | # TypeScript v1 declaration files 84 | typings/ 85 | 86 | # Optional npm cache directory 87 | .npm 88 | 89 | # Optional eslint cache 90 | .eslintcache 91 | 92 | # Optional REPL history 93 | .node_repl_history 94 | 95 | # Output of 'npm pack' 96 | *.tgz 97 | 98 | # Yarn Integrity file 99 | .yarn-integrity 100 | 101 | # dotenv environment variables file 102 | .env 103 | 104 | # parcel-bundler cache (https://parceljs.org/) 105 | .cache 106 | 107 | # next.js build output 108 | .next 109 | 110 | # nuxt.js build output 111 | .nuxt 112 | 113 | # vuepress build output 114 | .vuepress/dist 115 | 116 | # Serverless directories 117 | .serverless 118 | 119 | # FuseBox cache 120 | .fusebox/ 121 | 122 | ### Windows ### 123 | # Windows thumbnail cache files 124 | Thumbs.db 125 | ehthumbs.db 126 | ehthumbs_vista.db 127 | 128 | # Dump file 129 | *.stackdump 130 | 131 | # Folder config file 132 | [Dd]esktop.ini 133 | 134 | # Recycle Bin used on file shares 135 | $RECYCLE.BIN/ 136 | 137 | # Windows Installer files 138 | *.cab 139 | *.msi 140 | *.msix 141 | *.msm 142 | *.msp 143 | 144 | # Windows shortcuts 145 | *.lnk 146 | 147 | ### VSCode Files ### 148 | out 149 | dist 150 | .vscode-test/ 151 | .vscode-test-web/ 152 | *.vsix 153 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx --no -- commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | node scripts/check-engine.js 2 | npx --no lint-staged 3 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | npm run compile 2 | npm run compile-tests 3 | npm run test 4 | -------------------------------------------------------------------------------- /.lintstagedrc.yml: -------------------------------------------------------------------------------- 1 | '*.{js,ts}': eslint --fix 2 | '*.md': prettier --write 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint", 6 | "amodio.tsl-problem-matcher" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "${workspaceFolder}/test-workspace/test.code-workspace", 15 | "--disable-extensions", 16 | "--extensionDevelopmentPath=${workspaceFolder}" 17 | ], 18 | "outFiles": [ 19 | "${workspaceFolder}/dist/**/*.js" 20 | ], 21 | "preLaunchTask": "${defaultBuildTask}" 22 | }, 23 | { 24 | "name": "Run Extension Tests", 25 | "type": "extensionHost", 26 | "request": "launch", 27 | "runtimeExecutable": "${execPath}", 28 | "args": [ 29 | "${workspaceFolder}/test-workspace/test.code-workspace", 30 | "--disable-extensions", 31 | "--extensionDevelopmentPath=${workspaceFolder}", 32 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index-node" 33 | ], 34 | "outFiles": [ 35 | "${workspaceFolder}/out/**/*.js", 36 | "${workspaceFolder}/dist/**/*.js", 37 | ], 38 | "preLaunchTask": "npm: watch-tests" 39 | }, 40 | { 41 | "name": "Run Web Extension", 42 | "type": "pwa-extensionHost", 43 | "debugWebWorkerHost": true, 44 | "request": "launch", 45 | "args": [ 46 | "${workspaceFolder}/test-workspace/test.code-workspace", 47 | "--disable-extensions", 48 | "--extensionDevelopmentPath=${workspaceFolder}", 49 | "--extensionDevelopmentKind=web" 50 | ], 51 | "outFiles": [ 52 | "${workspaceFolder}/dist/web/**/*.js" 53 | ], 54 | "preLaunchTask": "${defaultBuildTask}" 55 | }, 56 | { 57 | "name": "Run Web Extension Tests", 58 | "type": "extensionHost", 59 | "debugWebWorkerHost": true, 60 | "request": "launch", 61 | "args": [ 62 | "${workspaceFolder}/test-workspace/test.code-workspace", 63 | "--disable-extensions", 64 | "--extensionDevelopmentPath=${workspaceFolder}", 65 | "--extensionDevelopmentKind=web", 66 | "--extensionTestsPath=${workspaceFolder}/dist/web/test/suite/index-web" 67 | ], 68 | "outFiles": [ 69 | "${workspaceFolder}/dist/web/**/*.js" 70 | ], 71 | "preLaunchTask": "${defaultBuildTask}" 72 | } 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "editor.detectIndentation": false, 4 | "editor.tabSize": 2, 5 | "files.insertFinalNewline": true, 6 | "files.trimFinalNewlines": true, 7 | "files.trimTrailingWhitespace": true, 8 | "files.exclude": { 9 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 10 | "dist": false // set this to true to hide the "dist" folder with the compiled JS files 11 | }, 12 | "search.exclude": { 13 | "out": true, // set this to false to include "out" folder in search results 14 | "dist": true // set this to false to include "dist" folder in search results 15 | }, 16 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 17 | "typescript.tsc.autoDetect": "off" 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "compile", 9 | "group": { 10 | "kind": "build", 11 | "isDefault": true 12 | }, 13 | "presentation": { 14 | "reveal": "never" 15 | }, 16 | "problemMatcher": [ 17 | "$ts-webpack", 18 | "$tslint-webpack" 19 | ] 20 | }, 21 | { 22 | "type": "npm", 23 | "script": "watch-tests", 24 | "problemMatcher": "$tsc-watch", 25 | "isBackground": true, 26 | "presentation": { 27 | "reveal": "never", 28 | "group": "watchers" 29 | }, 30 | "group": "build" 31 | }, 32 | { 33 | "label": "tasks: watch-tests", 34 | "dependsOn": [ 35 | "npm: watch", 36 | "npm: watch-tests" 37 | ], 38 | "problemMatcher": [] 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .vscode-test-web/** 4 | src/** 5 | out/** 6 | node_modules/** 7 | build/** 8 | .gitignore 9 | .yarnrc 10 | package-lock.json 11 | vsc-extension-quickstart.md 12 | webpack.config.js 13 | **/tsconfig.json 14 | **/.eslintrc.json 15 | **/*.map 16 | **/*.ts 17 | .gitattributes 18 | .huskyrc.json 19 | tsconfig.json 20 | dist/web/test/** 21 | 22 | # project 23 | .github/ 24 | !node_modules/prettier 25 | test-workspace/ 26 | scripts/ 27 | commitlint.config.js 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | > **Tags** 6 | > 7 | > - Features 8 | > - Bug Fixes 9 | > - Performance Improvements 10 | > - Enhancements 11 | > - Dependency Updates 12 | > - Breaking Changes 13 | > - Documentation 14 | > - Internal 15 | 16 | ## v3.0.0 (2023-07-10) 17 | 18 | #### Breaking Changes 19 | 20 | - update `prettier` to v3.0.0 ([a2b8372](https://github.com/sibiraj-s/vscode-scss-formatter/commit/a2b8372)) 21 | 22 | ## v2.5.0 (2023-04-11) 23 | 24 | #### Dependency Updates 25 | 26 | - update `prettier` to v2.8.7 ([d4f69ee](https://github.com/sibiraj-s/vscode-scss-formatter/commit/d4f69ee)) 27 | 28 | ## v2.4.5 (2023-02-04) 29 | 30 | #### Dependency Updates 31 | 32 | - update `prettier` to v2.8.3 ([1e01cda](https://github.com/sibiraj-s/vscode-scss-formatter/commit/1e01cda)) 33 | - update `@vscode/vsce` to v2.17.0 ([6b325fb](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6b325fb)) 34 | - update `typescript` to v4.9.5 ([6b325fb](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6b325fb)) 35 | 36 | #### Enhancements 37 | 38 | - remove deprecated activation events ([be469f7](https://github.com/sibiraj-s/vscode-scss-formatter/commit/be469f7)) 39 | 40 | ## v2.4.4 (2022-12-11) 41 | 42 | #### Dependency Updates 43 | 44 | - update `prettier` to v2.8.1 ([a682729](https://github.com/sibiraj-s/vscode-scss-formatter/commit/a682729)) 45 | - update `typescript` to v4.9.4 ([212a61e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/212a61e)) 46 | - update `webpack` to v5.75.0 ([96fb1e5](https://github.com/sibiraj-s/vscode-scss-formatter/commit/96fb1e5)) 47 | - update `vsce` to v2.15.0 ([14439b6](https://github.com/sibiraj-s/vscode-scss-formatter/commit/14439b6)) 48 | - update `@types/vscode` to v1.74.0 ([327d0cd](https://github.com/sibiraj-s/vscode-scss-formatter/commit/327d0cd)) 49 | - update nodejs to v18 ([c8f266f](https://github.com/sibiraj-s/vscode-scss-formatter/commit/c8f266f)) 50 | 51 | ## v2.4.3 (2022-06-11) 52 | 53 | #### Dependency Updates 54 | 55 | - update `typescript` to v4.7.3 ([85d09ee](https://github.com/sibiraj-s/vscode-scss-formatter/commit/85d09ee)) 56 | - update `webpack` to v5.73.0 ([238ea6a](https://github.com/sibiraj-s/vscode-scss-formatter/commit/238ea6a)) 57 | - update `vsce` to v2.9.1 ([0bacef6](https://github.com/sibiraj-s/vscode-scss-formatter/commit/0bacef6)) 58 | 59 | ## v2.4.2 (2022-04-05) 60 | 61 | #### Dependency Updates 62 | 63 | - update `prettier` to v2.6.2 ([e326370](https://github.com/sibiraj-s/vscode-scss-formatter/commit/e326370)) 64 | - update `webpack` to v5.71.0 ([9526dba](https://github.com/sibiraj-s/vscode-scss-formatter/commit/9526dba)) 65 | - update `@types/vscode` to v1.66.0 ([1c73a52](https://github.com/sibiraj-s/vscode-scss-formatter/commit/1c73a52)) 66 | 67 | ## v2.4.1 (2022-03-26) 68 | 69 | #### Bug Fixes 70 | 71 | - fix language selectors for vscode web ([c973401](https://github.com/sibiraj-s/vscode-scss-formatter/commit/c973401)) 72 | 73 | ## v2.4.0 (2022-03-26) 74 | 75 | #### Dependency Updates 76 | 77 | - update `prettier` to v2.6.1 ([b863255](https://github.com/sibiraj-s/vscode-scss-formatter/commit/b863255)) 78 | 79 | #### Features 80 | 81 | - support vscode web ([5b47eb5](https://github.com/sibiraj-s/vscode-scss-formatter/commit/5b47eb5)) 82 | 83 | ## v2.3.3 (2021-12-08) 84 | 85 | #### Dependency Updates 86 | 87 | - update `prettier` to v2.5.1 ([6b614fc](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6b614fc)) 88 | 89 | ## v2.3.2 (2021-10-19) 90 | 91 | #### Breaking Changes 92 | 93 | - remove useless activate command ([579eb5c](https://github.com/sibiraj-s/vscode-scss-formatter/commit/579eb5c)) 94 | 95 | #### Internal 96 | 97 | - update to eslint v8 ([af214d7](https://github.com/sibiraj-s/vscode-scss-formatter/commit/af214d7)) 98 | - enable webpack infrastructureLogging ([7ce9c3f](https://github.com/sibiraj-s/vscode-scss-formatter/commit/7ce9c3f)) 99 | - update recommended extensions ([2b99970](https://github.com/sibiraj-s/vscode-scss-formatter/commit/2b99970)) 100 | 101 | ## v2.3.1 (2021-10-16) 102 | 103 | #### Bug Fixes 104 | 105 | - ignore prettier from webpack compilation ([0016c0d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/0016c0d)) 106 | - ignore project releated files from publish ([b51b897](https://github.com/sibiraj-s/vscode-scss-formatter/commit/b51b897)) 107 | 108 | #### Dependency Updates 109 | 110 | - update devDependencies ([5151ece](https://github.com/sibiraj-s/vscode-scss-formatter/commit/5151ece)) 111 | 112 | ## v2.3.0 (2021-10-14) 113 | 114 | #### Features 115 | 116 | - add support for untrusted workspaces ([bc0dc37](https://github.com/sibiraj-s/vscode-scss-formatter/commit/bc0dc37)) 117 | - apply error bg on stausbar item during format error ([811de84](https://github.com/sibiraj-s/vscode-scss-formatter/commit/811de84)) 118 | 119 | #### Dependency Updates 120 | 121 | - update `prettier` to v2.4.1 ([ea54976](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ea54976)) 122 | 123 | ## v2.2.4 (2021-09-10) 124 | 125 | #### Dependency Updates 126 | 127 | - update `prettier` to v2.4.0 ([88baa4e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/88baa4e)) 128 | - update devDependencies ([88baa4e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/88baa4e)) 129 | 130 | ## v2.2.3 (2021-07-16) 131 | 132 | #### Bug Fixes 133 | 134 | - remove duplicate commands ([cf22803](https://github.com/sibiraj-s/vscode-scss-formatter/commit/cf22803)) 135 | 136 | #### Dependency Updates 137 | 138 | - update `prettier` to v2.3.1 ([d4dd1eb](https://github.com/sibiraj-s/vscode-scss-formatter/commit/d4dd1eb)) 139 | - update devDependencies ([80d3de6](https://github.com/sibiraj-s/vscode-scss-formatter/commit/80d3de6)) 140 | 141 | ## v2.2.2 (2021-06-21) 142 | 143 | #### Enhancements 144 | 145 | - reset statusbar icon while switching files ([f1f36c0](https://github.com/sibiraj-s/vscode-scss-formatter/commit/f1f36c0)) 146 | - update statusbar icons ([69074b9](https://github.com/sibiraj-s/vscode-scss-formatter/commit/69074b9)) 147 | 148 | ## v2.2.1 (2021-06-06) 149 | 150 | #### Dependency Updates 151 | 152 | - update `prettier` to v2.3.1 ([740e901](https://github.com/sibiraj-s/vscode-scss-formatter/commit/740e901)) 153 | - update devDependencies ([6d6a0e9](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6d6a0e9)) 154 | 155 | ## v2.2.0 (2021-05-10) 156 | 157 | #### Dependency Updates 158 | 159 | - update `prettier` to v2.3.0 ([0e1cf7a](https://github.com/sibiraj-s/vscode-scss-formatter/commit/0e1cf7a)) 160 | 161 | #### Internal 162 | 163 | - update to nodejs v16/npm v7 ([9e8bceb](https://github.com/sibiraj-s/vscode-scss-formatter/commit/9e8bceb)) 164 | 165 | ## v2.1.0 (2021-01-24) 166 | 167 | #### Features 168 | 169 | - add option `trailingComma`, defaults to `es5` ([6d5f091](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6d5f091)) 170 | 171 | #### Dependency Updates 172 | 173 | - update devDependencies ([7e4aa79](https://github.com/sibiraj-s/vscode-scss-formatter/commit/7e4aa79)), ([8479872](https://github.com/sibiraj-s/vscode-scss-formatter/commit/8479872)) 174 | 175 | ## v2.0.5 (2020-12-14) 176 | 177 | #### Internal 178 | 179 | - update LICENSE ([af91dd0](https://github.com/sibiraj-s/vscode-scss-formatter/commit/af91dd0)) 180 | 181 | ## v2.0.4 (2020-12-12) 182 | 183 | #### Dependency Updates 184 | 185 | - update `prettier` to v2.2.1 ([3baa058](https://github.com/sibiraj-s/vscode-scss-formatter/commit/3baa058)) 186 | 187 | ## v2.0.3 (2020-11-26) 188 | 189 | #### Dependency Updates 190 | 191 | - update `prettier` to v2.2.0 ([6f6d625](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6f6d625)) 192 | - update devDependencies ([6f6d625](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6f6d625)) 193 | 194 | ## v2.0.2 (2020-08-24) 195 | 196 | #### Dependency Updates 197 | 198 | - update `prettier` to v2.0.2 ([8bb6d86](https://github.com/sibiraj-s/vscode-scss-formatter/commit/8bb6d86)) 199 | - update devDependencies ([e4874cd](https://github.com/sibiraj-s/vscode-scss-formatter/commit/e4874cd)) 200 | - downgrade typescript to v4 ([711a6dc](https://github.com/sibiraj-s/vscode-scss-formatter/commit/711a6dc)) 201 | 202 | ## v2.0.1 (2020-05-09) 203 | 204 | #### Bug Fixes 205 | 206 | - fix a typo in configuration ([4f35669](https://github.com/sibiraj-s/vscode-scss-formatter/commit/4f35669)) 207 | 208 | #### Dependency Updates 209 | 210 | - update `prettier` to v2.0.5 ([3e3c1b4](https://github.com/sibiraj-s/vscode-scss-formatter/commit/3e3c1b4)) 211 | - update `husky` to v4.2.5 ([6c437fd](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6c437fd)) 212 | 213 | ## v2.0.0 (2020-03-29) 214 | 215 | #### Breaking Changes 216 | 217 | - removed `scssFormatter.tabWidth` in favour of `editor.tabSize` ([403e46d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/403e46d)) 218 | - removed `scssFormatter.useTabs` in favour of `editor.insertSpaces` ([403e46d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/403e46d)) 219 | 220 | #### Dependency Updates 221 | 222 | - update `@types/node` to v13.9.5 ([e00a06a](https://github.com/sibiraj-s/vscode-scss-formatter/commit/e00a06a)) 223 | 224 | ## v1.4.6 (2020-03-24) 225 | 226 | #### Internal 227 | 228 | - cleanup internal services ([8952533](https://github.com/sibiraj-s/vscode-scss-formatter/commit/8952533)) 229 | 230 | ## v1.4.5 (2020-03-24) 231 | 232 | #### Dependency Updates 233 | 234 | - update `prettier` to v2.0.2 ([d00a0eb](https://github.com/sibiraj-s/vscode-scss-formatter/commit/d00a0eb)) 235 | - update `typescript-eslint` ([b2b0ff0](https://github.com/sibiraj-s/vscode-scss-formatter/commit/b2b0ff0)) 236 | 237 | ## v1.4.4 (2020-03-23) 238 | 239 | #### Dependency Updates 240 | 241 | - update `prettier` to v2.0.1 ([6228630](https://github.com/sibiraj-s/vscode-scss-formatter/commit/6228630)) 242 | - bump devDependencies version to latest ([aa0922d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/aa0922d)) 243 | 244 | #### Internal 245 | 246 | - replace `tslint` with `typescript-eslint` ([f514b64](https://github.com/sibiraj-s/vscode-scss-formatter/commit/f514b64)) 247 | 248 | ## v1.4.3 (2019-12-24) 249 | 250 | #### Dependency Updates 251 | 252 | - update `prettier` to v1.19.1 ([62d881b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/62d881b)) 253 | - bump devDependencies version to latest ([62d881b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/62d881b)) 254 | 255 | #### Internal 256 | 257 | - migrate to github actions from travis-ci ([8ad81a8](https://github.com/sibiraj-s/vscode-scss-formatter/commit/8ad81a8)) 258 | - update node version requirement ([0d7f3fc](https://github.com/sibiraj-s/vscode-scss-formatter/commit/0d7f3fc)) 259 | - set `defaultBuildTask` as `preLaunchTask` in vscode launch config ([5e86c93](https://github.com/sibiraj-s/vscode-scss-formatter/commit/5e86c93)) 260 | 261 | ## v1.4.2 (2019-08-15) 262 | 263 | #### Dependency Updates 264 | 265 | - update `prettier` to v1.18.2 ([82ffd3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/82ffd3d)) 266 | - update `@types/mocha` to v5.2.7 ([82ffd3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/82ffd3d)) 267 | - update `@types/prettier` to v1.18.2 ([82ffd3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/82ffd3d)) 268 | - update `husky` to v3.0.3 ([82ffd3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/82ffd3d)) 269 | - update `tslint` to v5.18.0 ([82ffd3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/82ffd3d)) 270 | - update `typescript` to v3.5.3 ([82ffd3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/82ffd3d)) 271 | - update `@types/node` to v10.14.15 ([ffcf4e1](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ffcf4e1)) 272 | - update vscode test runner ([1b6e6a6](https://github.com/sibiraj-s/vscode-scss-formatter/commit/1b6e6a6)) 273 | 274 | ## v1.4.1 (2019-03-04) 275 | 276 | #### Dependency Updates 277 | 278 | - update `@types/node` to v10.12.29 ([02c294b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/02c294b)) 279 | - update `@types/mocha` to v5.2.6 ([02c294b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/02c294b)) 280 | - update `vscode` to v1.1.30 ([02c294b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/02c294b)) 281 | - update `@types/prettier` to v1.16.1 ([02c294b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/02c294b)) 282 | - update `prettier` to v1.16.4 ([02c294b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/02c294b)) 283 | 284 | #### Internal 285 | 286 | - file rename scssFormatterProvider to FormatterProvider ([eb5f15d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/eb5f15d)) 287 | - remove unncessary use strict statement ([00c1eb7](https://github.com/sibiraj-s/vscode-scss-formatter/commit/00c1eb7)) 288 | - fix warnings in package.json ([02c294b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/02c294b)) 289 | 290 | ## v1.4.0 (2019-01-24) 291 | 292 | #### Features 293 | 294 | - add an option to specify `printWidth`, defaults to `120` ([2dbc172](https://github.com/sibiraj-s/vscode-scss-formatter/commit/2dbc172)) 295 | 296 | #### Internal 297 | 298 | - update `@types/node` to v10.12.18 ([ee7bc09](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ee7bc09)) 299 | - update `husky` to v1.3.1 ([ee7bc09](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ee7bc09)) 300 | - update `tslint` to v5.12.1 ([ee7bc09](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ee7bc09)) 301 | - update `typescript` to v3.2.4 ([ee7bc09](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ee7bc09)) 302 | - update `vscode` to v1.1.28 ([ee7bc09](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ee7bc09)) 303 | 304 | ## v1.3.4 (2018-11-30) 305 | 306 | #### Performance Improvements 307 | 308 | - remove multiple event handlers ([0c22a10](https://github.com/sibiraj-s/vscode-scss-formatter/commit/0c22a10)) 309 | - update `prettier` to v1.15.3 ([d8bf27e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/d8bf27e)) 310 | 311 | #### Dependency Updates 312 | 313 | - update `typescript` to v3.2.1 ([dcc6d59](https://github.com/sibiraj-s/vscode-scss-formatter/commit/dcc6d59)) 314 | - update `@types/prettier` to v1.15.2 ([d8bf27e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/d8bf27e)) 315 | - package-lock.json maintenance update ([def591e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/def591e)) 316 | 317 | ## v1.3.3 (2018-11-25) 318 | 319 | #### Internal 320 | 321 | - move @types/prettier to devDependencies ([59e489e](https://github.com/sibiraj-s/vscode-scss-formatter/commit/59e489e)) 322 | 323 | ## v1.3.2 (2018-11-24) 324 | 325 | #### Internal 326 | 327 | - use type definitions for prettier ([25b9b35](https://github.com/sibiraj-s/vscode-scss-formatter/commit/25b9b35)) 328 | 329 | ## v1.3.1 (2018-11-23) 330 | 331 | #### Internal 332 | 333 | - update homepage link in package.json ([7420978](https://github.com/sibiraj-s/vscode-scss-formatter/commit/7420978)) 334 | 335 | ## v1.3.0 (2018-11-23) 336 | 337 | #### Features 338 | 339 | - add commands to show/clear formatter output logs ([a347d1c](https://github.com/sibiraj-s/vscode-scss-formatter/commit/a347d1c)) 340 | - add message to output console on format success ([7420978](https://github.com/sibiraj-s/vscode-scss-formatter/commit/7420978)) 341 | 342 | #### Enhancements 343 | 344 | - clear statusbarItem if active editor's file scheme doesn't match supported file types ([459c1d2](https://github.com/sibiraj-s/vscode-scss-formatter/commit/459c1d2)) 345 | - remove package-lock.json from extension bundle ([3be1f3d](https://github.com/sibiraj-s/vscode-scss-formatter/commit/3be1f3d)) 346 | 347 | #### Performance Improvements 348 | 349 | - handle extension registration efficiently ([9a6fd40](https://github.com/sibiraj-s/vscode-scss-formatter/commit/9a6fd40)) 350 | 351 | ## v1.2.3 (2018-11-22) 352 | 353 | #### Enhancements 354 | 355 | - show extension version instead of prettier version ([ca4f516](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ca4f516)) 356 | 357 | #### Dependency Updates 358 | 359 | - update `@types/node` to v10.12.10 ([ea49c29](https://github.com/sibiraj-s/vscode-scss-formatter/commit/ea49c29)) 360 | 361 | ## v1.2.2 (2018-11-21) 362 | 363 | #### Enhancements 364 | 365 | - use proper menu category for commands ([de74a9c](https://github.com/sibiraj-s/vscode-scss-formatter/commit/de74a9c)) 366 | 367 | ## v1.2.1 (2018-11-21) 368 | 369 | #### Performance Improvements 370 | 371 | - remove redundant code in deactivate method ([7f59324](https://github.com/sibiraj-s/vscode-scss-formatter/commit/7f59324)) 372 | 373 | ## v1.2.0 (2018-11-21) 374 | 375 | #### Features 376 | 377 | - new command `SCSS Formatter: Activate` to activate the extension ([754d2fd](https://github.com/sibiraj-s/vscode-scss-formatter/commit/754d2fd)) 378 | 379 | #### Performance Improvements 380 | 381 | - revert: don't activate extension on startup ([754d2fd](https://github.com/sibiraj-s/vscode-scss-formatter/commit/754d2fd)) 382 | 383 | #### Dependency Updates 384 | 385 | - update `husky` to v1.2.0 ([e4e17d8](https://github.com/sibiraj-s/vscode-scss-formatter/commit/e4e17d8)) 386 | 387 | ## v1.1.2 (2018-11-21) 388 | 389 | #### Performance Improvements 390 | 391 | - activate extension on startup ([b070fa3](https://github.com/sibiraj-s/vscode-scss-formatter/commit/b070fa3)) 392 | - remove unwanted files from extension bundle ([141e5aa](https://github.com/sibiraj-s/vscode-scss-formatter/commit/141e5aa)) 393 | 394 | #### Internal 395 | 396 | - add extension tests ([b070fa3](https://github.com/sibiraj-s/vscode-scss-formatter/commit/b070fa3)) 397 | 398 | ## v1.1.1 (2018-11-20) 399 | 400 | #### Performance Improvements 401 | 402 | - set minimum vscode requirement to v1.29.0 ([a4195b7](https://github.com/sibiraj-s/vscode-scss-formatter/commit/a4195b7)) 403 | 404 | ## v1.1.0 (2018-11-18) 405 | 406 | #### Features 407 | 408 | - add format errors to vscode console ([c110235](https://github.com/sibiraj-s/vscode-scss-formatter/commit/c110235)) 409 | - update vscode statusbar with format status ([c110235](https://github.com/sibiraj-s/vscode-scss-formatter/commit/c110235)) 410 | 411 | #### Dependency Updates 412 | 413 | - update `prettier` to v1.15.2 ([f3a3a70](https://github.com/sibiraj-s/vscode-scss-formatter/commit/f3a3a70)) 414 | - update `@types/node` to v10.12.9 ([f3a3a70](https://github.com/sibiraj-s/vscode-scss-formatter/commit/f3a3a70)) 415 | - update `husky` to v1.1.4 ([f3a3a70](https://github.com/sibiraj-s/vscode-scss-formatter/commit/f3a3a70)) 416 | 417 | ## v1.0.4 (2018-11-07) 418 | 419 | #### Dependency Updates 420 | 421 | - update `prettier` to v1.15.1 ([618050b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/618050b)) 422 | - update `@types/node` to v10.12.2 ([618050b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/618050b)) 423 | - update `typescript` to v3.1.6 ([618050b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/618050b)) 424 | - update `husky` to v1.1.3 ([618050b](https://github.com/sibiraj-s/vscode-scss-formatter/commit/618050b)) 425 | 426 | ## v1.0.3 (2018-10-05) 427 | 428 | #### Dependency Updates 429 | 430 | - update `prettier` to v1.14.3 ([21df4ad](https://github.com/sibiraj-s/vscode-scss-formatter/commit/21df4ad)) 431 | - update `@types/node` to v10.11.4 ([21df4ad](https://github.com/sibiraj-s/vscode-scss-formatter/commit/21df4ad)) 432 | - update `typescript` to v3.1.1 ([21df4ad](https://github.com/sibiraj-s/vscode-scss-formatter/commit/21df4ad)) 433 | - update `husky` to v1.1.0 ([21df4ad](https://github.com/sibiraj-s/vscode-scss-formatter/commit/21df4ad)) 434 | 435 | #### Internal 436 | 437 | - don't use standard-version for generating changelogs ([768e1d6](https://github.com/sibiraj-s/vscode-scss-formatter/commit/768e1d6)) 438 | 439 | ## v1.0.2 (2018-08-26) 440 | 441 | #### Documentation 442 | 443 | - update README.md with installation instructions 444 | 445 | ## v1.0.1 (2018-08-26) 446 | 447 | #### Bug Fixes 448 | 449 | - disable `singleQuote` enabled by default([db9cd59](https://github.com/sibiraj-s/vscode-scss-formatter/commit/db9cd59)) 450 | 451 | ## v1.0.0 (2018-08-26) 452 | 453 | #### Features 454 | 455 | - **Initial Release**: A VS Code Extension to format SCSS 456 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sibiraj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VS Code SCSS Formatter 2 | 3 | [![Tests](https://github.com/sibiraj-s/vscode-scss-formatter/workflows/Tests/badge.svg)](https://github.com/sibiraj-s/vscode-scss-formatter/actions) 4 | [![Version](https://badgen.net/vs-marketplace/v/sibiraj-s.vscode-scss-formatter)](https://marketplace.visualstudio.com/items?itemName=sibiraj-s.vscode-scss-formatter) 5 | [![Installs](https://badgen.net/vs-marketplace/i/sibiraj-s.vscode-scss-formatter)](https://marketplace.visualstudio.com/items?itemName=sibiraj-s.vscode-scss-formatter) 6 | [![Downloads](https://badgen.net/vs-marketplace/d/sibiraj-s.vscode-scss-formatter)](https://marketplace.visualstudio.com/items?itemName=sibiraj-s.vscode-scss-formatter) 7 | [![Ratings](https://badgen.net/vs-marketplace/rating/sibiraj-s.vscode-scss-formatter)](https://marketplace.visualstudio.com/items?itemName=sibiraj-s.vscode-scss-formatter&ssr=false#review-details) 8 | 9 | SCSS Formatter is an extension for Visual Studio Code to format [SCSS](https://sass-lang.com/). 10 | 11 | SCSS Formatter uses [Prettier] under the hood to format files. Though Prettier supports formatting various file types. This extension focuses only on `SCSS`. Additionally it supports `CSS`. 12 | 13 | Checkout [prettier-vscode] for an extended language support 14 | 15 | Any issues related to formatting, open an issue [here](https://github.com/prettier/prettier/issues) 16 | 17 | ## Installation 18 | 19 | Refer to [Visual Studio MarketPlace](https://marketplace.visualstudio.com/items?itemName=sibiraj-s.vscode-scss-formatter) to install or download the extension 20 | 21 | To install via [command line](https://code.visualstudio.com/docs/editor/command-line), you should have installed `code` command in `PATH` 22 | 23 | ```bash 24 | code --install-extension sibiraj-s.vscode-scss-formatter 25 | ``` 26 | 27 | ## Usage 28 | 29 | Files can be formatted by the **Format Document** option available in the **context menu**, by using the associated **Keyboard Shortcut** or running the **Format Document** command from the **command pallete** 30 | 31 | Default keyboard shortcuts for **Format Document** command: 32 | 33 | - MacOS: **⇧⌥F** or **Shift+Option+F** 34 | - Linux: **Ctrl+Shift+I** 35 | - Windows: **Shift+Alt+F** 36 | 37 | ### Formatter Demo 38 | 39 | ![SCSS Formatter Demo](assets/scss-format.gif) 40 | 41 | ### Extension Settings 42 | 43 | This extension contributes the following settings: 44 | 45 | - `scssFormatter.printWidth`: Line length that the formatter will wrap on. 46 | - `scssFormatter.singleQuote`: Use single quotes instead of double quotes. 47 | - `scssFormatter.trailingComma`: Print trailing commas wherever possible when multi-line. 48 | 49 | ### Known Issues 50 | 51 | - `formatOnPaste` is not supported as [Prettier] does not support formatting a selection or range of text for css/scss. 52 | 53 | [prettier]: https://github.com/prettier/prettier 54 | [prettier-vscode]: https://github.com/prettier/prettier-vscode 55 | -------------------------------------------------------------------------------- /assets/sass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sibiraj-s/vscode-scss-formatter/7f3e679d3f4ce66ce65e6e8e092d10a42b3b1d78/assets/sass.png -------------------------------------------------------------------------------- /assets/scss-format.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sibiraj-s/vscode-scss-formatter/7f3e679d3f4ce66ce65e6e8e092d10a42b3b1d78/assets/scss-format.gif -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import pegasus from "eslint-config-pegasus"; 2 | 3 | export default [ 4 | pegasus.configs.default, 5 | pegasus.configs.node, 6 | ...pegasus.tsConfig({ 7 | files: ['*.ts'], 8 | extends: pegasus.configs.typescript, 9 | }), 10 | ]; 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-scss-formatter", 3 | "displayName": "SCSS Formatter", 4 | "description": "%scssFormatter.description%", 5 | "version": "3.0.0", 6 | "author": "sibiraj-s", 7 | "licence": "MIT", 8 | "private": true, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/sibiraj-s/vscode-scss-formatter.git" 12 | }, 13 | "bugs": "https://github.com/sibiraj-s/vscode-scss-formatter/issues", 14 | "homepage": "https://marketplace.visualstudio.com/items?itemName=sibiraj-s.vscode-scss-formatter", 15 | "engines": { 16 | "node": ">=18.0.0", 17 | "vscode": "^1.95.0" 18 | }, 19 | "scripts": { 20 | "deploy": "vsce publish", 21 | "vscode:prepublish": "npm run package", 22 | "compile": "webpack", 23 | "watch": "webpack --watch", 24 | "package": "webpack --mode production --devtool hidden-source-map", 25 | "compile-tests": "tsc -p . --outDir out", 26 | "watch-tests": "tsc -p . -w --outDir out", 27 | "compile-tests-web": "tsc -p tsconfig-test-web.json --outDir dist/web", 28 | "watch-tests-web": "tsc -p tsconfig-test-web.json -w --outDir dist/web", 29 | "test-web": "node ./dist/web/test/runTest-web.js", 30 | "test": "node ./out/test/runTest.js", 31 | "run-in-browser": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. test-workspace", 32 | "lint": "eslint . --ext js,ts --ignore-path .gitignore", 33 | "prepare": "is-ci || husky install" 34 | }, 35 | "dependencies": { 36 | "prettier": "^3.0.0" 37 | }, 38 | "devDependencies": { 39 | "@commitlint/cli": "^19.5.0", 40 | "@commitlint/config-conventional": "^19.5.0", 41 | "@types/mocha": "^10.0.9", 42 | "@types/node": "^22.8.7", 43 | "@types/vscode": "^1.95.0", 44 | "@types/webpack-env": "^1.18.5", 45 | "@vscode/test-electron": "^2.4.1", 46 | "@vscode/test-web": "^0.0.63", 47 | "assert": "^2.1.0", 48 | "eslint": "^9.14.0", 49 | "eslint-config-pegasus": "^6.0.1", 50 | "fast-glob": "^3.3.2", 51 | "husky": "^9.1.6", 52 | "is-ci": "^3.0.1", 53 | "lint-staged": "^15.2.10", 54 | "mocha": "^10.8.2", 55 | "picocolors": "^1.1.1", 56 | "process": "^0.11.10", 57 | "ts-loader": "^9.5.1", 58 | "typescript": "^5.6.3", 59 | "@vscode/vsce": "^3.2.1", 60 | "webpack": "^5.96.1", 61 | "webpack-cli": "^5.1.4" 62 | }, 63 | "publisher": "sibiraj-s", 64 | "icon": "assets/sass.png", 65 | "categories": [ 66 | "Formatters" 67 | ], 68 | "activationEvents": [ 69 | "onLanguage:css", 70 | "onLanguage:scss" 71 | ], 72 | "main": "./dist/extension.js", 73 | "browser": "./dist/web/extension.js", 74 | "capabilities": { 75 | "virtualWorkspaces": true, 76 | "untrustedWorkspaces": { 77 | "supported": true 78 | } 79 | }, 80 | "contributes": { 81 | "commands": [ 82 | { 83 | "command": "scssFormatter.showOutput", 84 | "title": "%scssFormatter.commands.showOutput.title%", 85 | "category": "SCSS Formatter" 86 | }, 87 | { 88 | "command": "scssFormatter.clearOutput", 89 | "title": "%scssFormatter.commands.clearOutput.title%", 90 | "category": "SCSS Formatter" 91 | } 92 | ], 93 | "configuration": [ 94 | { 95 | "type": "object", 96 | "title": "SCSS Formatter", 97 | "properties": { 98 | "scssFormatter.printWidth": { 99 | "type": "number", 100 | "default": 120, 101 | "description": "%scssFormatter.config.printWidth.description%" 102 | }, 103 | "scssFormatter.singleQuote": { 104 | "type": "boolean", 105 | "default": false, 106 | "description": "%scssFormatter.config.singleQuote.description%" 107 | }, 108 | "scssFormatter.trailingComma": { 109 | "type": "string", 110 | "default": "es5", 111 | "enum": [ 112 | "es5", 113 | "none", 114 | "all" 115 | ], 116 | "description": "%scssFormatter.config.trailingComma.description%" 117 | } 118 | } 119 | } 120 | ] 121 | }, 122 | "sponsor": { 123 | "url": "https://github.com/sponsors/sibiraj-s" 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /package.nls.json: -------------------------------------------------------------------------------- 1 | { 2 | "scssFormatter.description": "A Visual Studio Code Extension to format SCSS", 3 | "scssFormatter.commands.showOutput.title": "Show Output", 4 | "scssFormatter.commands.clearOutput.title": "Clear Output", 5 | "scssFormatter.config.printWidth.description": "Specify the line length that the formatter will wrap on", 6 | "scssFormatter.config.singleQuote.description": "Use single quotes instead of double quotes", 7 | "scssFormatter.config.trailingComma.description": "Print trailing commas wherever possible when multi-line" 8 | } 9 | -------------------------------------------------------------------------------- /scripts/check-engine.js: -------------------------------------------------------------------------------- 1 | const color = require('picocolors'); 2 | 3 | const pkg = require('../package.json'); 4 | const pkgLock = require('../package-lock.json'); 5 | 6 | const vscodeVersion = pkg.engines.vscode.substring(1); 7 | const typesVscodeVersion = pkg.devDependencies['@types/vscode'].substring(1); 8 | 9 | if (vscodeVersion !== typesVscodeVersion) { 10 | const msg = color.red('Err: Version specified in engines.vscode and \'@types/vscode\' doesn\'t match'); 11 | console.error(msg); 12 | process.exit(1); 13 | } 14 | 15 | if (pkg.version !== pkgLock.version) { 16 | console.error(color.red('Err: Manifest and lock file version mismatch')); 17 | process.exit(1); 18 | } 19 | -------------------------------------------------------------------------------- /src/FormatProvider.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Range, TextDocument, TextEdit, 3 | type DocumentFormattingEditProvider, type Position, type FormattingOptions, 4 | } from 'vscode'; 5 | 6 | // get range for the current document 7 | const fullDocumentRange = (document: TextDocument): Range => { 8 | const rangeStart: Position = document.lineAt(0).range.start; 9 | const rangeEnd: Position = document.lineAt(document.lineCount - 1).range.end; 10 | return new Range(rangeStart, rangeEnd); 11 | }; 12 | 13 | type Formatter = (document: TextDocument, options: FormattingOptions) => Promise; 14 | 15 | class FormatProvider implements DocumentFormattingEditProvider { 16 | constructor(private format: Formatter) { } 17 | 18 | public async provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions): Promise { 19 | const formattedDocument = await this.format(document, options); 20 | return [TextEdit.replace(fullDocumentRange(document), formattedDocument)]; 21 | } 22 | } 23 | 24 | export default FormatProvider; 25 | -------------------------------------------------------------------------------- /src/FormatService.ts: -------------------------------------------------------------------------------- 1 | import type { BuiltInParserName, Options as PrettierOptions } from 'prettier'; 2 | import { format } from 'prettier/standalone'; 3 | import * as postcssPlugin from 'prettier/plugins/postcss'; 4 | import { TextDocument, workspace, type WorkspaceConfiguration, type FormattingOptions, languages } from 'vscode'; 5 | 6 | import LoggingService from './LoggingService'; 7 | import StatusBarService, { FormatterStatus } from './StatusBarService'; 8 | import FormatProvider from './FormatProvider'; 9 | import { languageSelector } from './utils'; 10 | 11 | // add filepath to the output message 12 | const addFilePathToMesssage = (message: string, fileName: string): string => { 13 | const lines = message.split('\n'); 14 | if (lines.length > 0) { 15 | lines[0] = lines[0].replace(/(?:\d*):(?:\d*)/g, `${fileName}:$1:$2`); 16 | return lines.join('\n'); 17 | } 18 | return message; 19 | }; 20 | 21 | const getPrettierOptions = (document: TextDocument, options: FormattingOptions): PrettierOptions => { 22 | const wsConfig: WorkspaceConfiguration = workspace.getConfiguration('scssFormatter'); 23 | 24 | return { 25 | ...wsConfig, 26 | tabWidth: options.tabSize, 27 | useTabs: !options.insertSpaces, 28 | parser: document.languageId as BuiltInParserName, 29 | plugins: [ 30 | postcssPlugin, 31 | ], 32 | }; 33 | }; 34 | 35 | class FormatService { 36 | private provider: FormatProvider; 37 | 38 | constructor(private loggingService: LoggingService, private statusbarService: StatusBarService) { 39 | this.provider = new FormatProvider(this.formatDocument); 40 | } 41 | 42 | private formatDocument = async (document: TextDocument, options: FormattingOptions): Promise => { 43 | const rawDocumentText = document.getText(); 44 | const { fileName } = document; 45 | 46 | const prettierOptions = getPrettierOptions(document, options); 47 | 48 | try { 49 | const formattedDocument = format(rawDocumentText, prettierOptions); 50 | this.loggingService.addToOutput(`${fileName} : Formatted Successfully`); 51 | this.statusbarService.updateStatusBarItem(FormatterStatus.Success); 52 | return await formattedDocument; 53 | } catch (err) { 54 | const errMessage = err instanceof Error ? err.message : String(err); 55 | this.loggingService.addToOutput(addFilePathToMesssage(errMessage, fileName)); 56 | this.statusbarService.updateStatusBarItem(FormatterStatus.Error); 57 | return rawDocumentText; 58 | } 59 | }; 60 | 61 | public registerDisposables() { 62 | return [ 63 | languages.registerDocumentFormattingEditProvider(languageSelector, this.provider), 64 | ]; 65 | } 66 | } 67 | 68 | export default FormatService; 69 | -------------------------------------------------------------------------------- /src/LoggingService.ts: -------------------------------------------------------------------------------- 1 | import { commands, type Disposable, type OutputChannel, window } from 'vscode'; 2 | 3 | import StatusBarService from './StatusBarService'; 4 | import { EXTENSION_NAME } from './utils'; 5 | 6 | class LoggingService { 7 | private outputChannel: OutputChannel = window.createOutputChannel(EXTENSION_NAME); 8 | 9 | private statusbarService: StatusBarService; 10 | 11 | constructor(statusbarService: StatusBarService) { 12 | this.statusbarService = statusbarService; 13 | } 14 | 15 | // add message to the output channel 16 | public addToOutput(message: string): void { 17 | const title = `${new Date().toLocaleString()}:`; 18 | 19 | // Create a sort of title, to differentiate between messages 20 | this.outputChannel.appendLine(title); 21 | this.outputChannel.appendLine('-'.repeat(title.length)); 22 | 23 | // Append actual output 24 | this.outputChannel.appendLine(`${message}\n`); 25 | } 26 | 27 | public registerDisposables(): Disposable[] { 28 | return [ 29 | commands.registerCommand('scssFormatter.showOutput', () => { 30 | this.outputChannel.show(); 31 | }), 32 | commands.registerCommand('scssFormatter.clearOutput', () => { 33 | this.outputChannel.clear(); 34 | this.statusbarService.reset(); 35 | }), 36 | ]; 37 | } 38 | } 39 | 40 | export default LoggingService; 41 | -------------------------------------------------------------------------------- /src/StatusBarService.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type Disposable, languages, StatusBarAlignment, 3 | type StatusBarItem, TextEditor, ThemeColor, window, 4 | } from 'vscode'; 5 | 6 | import { EXTENSION_NAME, EXTENSION_VERSION, supportedLanguages } from './utils'; 7 | 8 | export enum FormatterStatus { 9 | Ready = 'check-all', 10 | Success = 'check', 11 | Error = 'alert', 12 | } 13 | 14 | const checkForInConsoleTabSwitch = (editor: TextEditor): boolean => { 15 | // output and debug console is also seen as an editor 16 | // hence switching tabs will trigger the function 17 | // this prevents hiding statusBarItem when switching between tabs 18 | return ['debug', 'output'].some( 19 | (part) => editor.document.uri.scheme === part, 20 | ); 21 | }; 22 | 23 | class StatusBarService { 24 | private statusBarItem: StatusBarItem; 25 | 26 | constructor() { 27 | this.statusBarItem = window.createStatusBarItem(StatusBarAlignment.Right, -1); 28 | this.updateStatusBarItem(FormatterStatus.Ready); 29 | this.statusBarItem.tooltip = `${EXTENSION_NAME}: v${EXTENSION_VERSION}`; 30 | this.statusBarItem.command = 'scssFormatter.showOutput'; 31 | 32 | this.toggleStatusBarItem(window.activeTextEditor); 33 | } 34 | 35 | public registerDisposables(): Disposable[] { 36 | return [ 37 | // Keep track whether to show/hide the statusbar 38 | window.onDidChangeActiveTextEditor((editor: TextEditor | undefined) => { 39 | this.updateStatusBarItem(FormatterStatus.Ready); 40 | this.toggleStatusBarItem(editor); 41 | }), 42 | ]; 43 | } 44 | 45 | // toggle statusBarItem when document changes 46 | private toggleStatusBarItem(editor: TextEditor | undefined): void { 47 | if (!this.statusBarItem) { 48 | return; 49 | } 50 | 51 | if (!editor) { 52 | this.statusBarItem.hide(); 53 | } else { 54 | if (checkForInConsoleTabSwitch(editor)) { 55 | return; 56 | } 57 | 58 | // hide statusBarItem if document changes and doesn't match supported languages 59 | const score = languages.match(supportedLanguages, editor.document); 60 | if (score) { 61 | this.statusBarItem.show(); 62 | } else { 63 | this.statusBarItem.hide(); 64 | } 65 | } 66 | } 67 | 68 | // update statusBarItem text and tooltip 69 | public updateStatusBarItem(status: FormatterStatus): void { 70 | this.statusBarItem.backgroundColor = new ThemeColor( 71 | status === FormatterStatus.Error ? 'statusBarItem.errorBackground' : '', 72 | ); 73 | 74 | this.statusBarItem.text = `${EXTENSION_NAME}: $(${status.toString()})`; 75 | this.statusBarItem.show(); 76 | } 77 | 78 | public reset() { 79 | this.statusBarItem.text = EXTENSION_NAME; 80 | } 81 | } 82 | 83 | export default StatusBarService; 84 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import type { ExtensionContext } from 'vscode'; 2 | 3 | import StatusBarService from './StatusBarService'; 4 | import LoggingService from './LoggingService'; 5 | import FormatService from './FormatService'; 6 | 7 | // method is called when extension is activated 8 | export const activate = (context: ExtensionContext) => { 9 | const statusbarService = new StatusBarService(); 10 | const loggingService = new LoggingService(statusbarService); 11 | 12 | const formatter = new FormatService( 13 | loggingService, 14 | statusbarService, 15 | ); 16 | 17 | context.subscriptions.push(...loggingService.registerDisposables()); 18 | context.subscriptions.push(...statusbarService.registerDisposables()); 19 | context.subscriptions.push(...formatter.registerDisposables()); 20 | }; 21 | 22 | export const deactivate = () => { 23 | // method is called when extension is deactivated 24 | }; 25 | -------------------------------------------------------------------------------- /src/test/runTest-web.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from '@vscode/test-web'; 4 | 5 | const main = async () => { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index-web'); 14 | 15 | // extension test workspace 16 | const extensionTestWorkspace = path.resolve(extensionDevelopmentPath, 'test-workspace'); 17 | 18 | const attachArgName = '--waitForDebugger='; 19 | const waitForDebugger = process.argv.find((arg) => arg.startsWith(attachArgName)); 20 | 21 | // Download VS Code, unzip it and run the integration test 22 | await runTests({ 23 | browserType: 'chromium', 24 | extensionDevelopmentPath, 25 | extensionTestsPath, 26 | folderPath: extensionTestWorkspace, 27 | waitForDebugger: waitForDebugger ? Number(waitForDebugger.slice(attachArgName.length)) : undefined, 28 | }); 29 | } catch (err) { 30 | console.error('Failed to run tests'); 31 | process.exit(1); 32 | } 33 | }; 34 | 35 | main(); 36 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from '@vscode/test-electron'; 4 | 5 | const main = async () => { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index-node'); 14 | 15 | // extension test workspace 16 | const extensionTestWorkspace = path.resolve(extensionDevelopmentPath, 'test-workspace', 'test.code-workspace'); 17 | 18 | // Download VS Code, unzip it and run the integration test 19 | await runTests({ 20 | extensionDevelopmentPath, 21 | extensionTestsPath, 22 | launchArgs: [ 23 | extensionTestWorkspace, 24 | '--disable-extensions', 25 | ], 26 | }); 27 | } catch (err) { 28 | console.error('Failed to run tests'); 29 | process.exit(1); 30 | } 31 | }; 32 | 33 | main(); 34 | -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable: no-console */ 2 | import * as assert from 'assert'; 3 | import { format } from 'prettier/standalone'; 4 | import * as postcssPlugin from 'prettier/plugins/postcss'; 5 | import { commands, Uri, window, workspace } from 'vscode'; 6 | 7 | const showOutputConsole = async () => { 8 | await commands.executeCommand('scssFormatter.showOutput'); 9 | }; 10 | 11 | // clear console output from formatter 12 | const clearOutput = async () => { 13 | await commands.executeCommand('scssFormatter.clearOutput'); 14 | }; 15 | 16 | /** 17 | * loads and format a file. 18 | * @param workspaceFolderName folder name in the workspace 19 | * @param file path relative to base URI (a workspaceFolder's URI) 20 | * @returns source code and resulting code 21 | */ 22 | const formatWithVscode = async ( 23 | workspaceFolderName: string, 24 | file: string, 25 | ): Promise<{ 26 | result: string; 27 | source: string; 28 | } | null> => { 29 | const workspaceFolder = workspace.workspaceFolders?.find((folder) => folder.name === workspaceFolderName); 30 | 31 | if (!workspaceFolder) { 32 | throw new Error(`Unable to find workspace: ${workspaceFolder}`); 33 | } 34 | 35 | const absPath = Uri.joinPath(workspaceFolder.uri, file).path; 36 | const doc = await workspace.openTextDocument(absPath); 37 | const text = doc.getText(); 38 | 39 | try { 40 | await window.showTextDocument(doc); 41 | console.time(file); 42 | await commands.executeCommand('editor.action.formatDocument'); 43 | console.timeEnd(file); 44 | return { result: doc.getText(), source: text }; 45 | } catch (e) { 46 | console.error(e); 47 | return null; 48 | } 49 | }; 50 | 51 | /** 52 | * Compare prettier's output (default settings) 53 | * with the output from extension. 54 | * @param file path relative to workspace root 55 | */ 56 | const formatSameAsPrettier = async (file: string) => { 57 | const result = await formatWithVscode('fixtures', file); 58 | 59 | if (result) { 60 | const prettierFormatted = await format(result.source, { 61 | filepath: file, 62 | printWidth: 120, 63 | singleQuote: false, 64 | tabWidth: 2, 65 | useTabs: false, 66 | trailingComma: 'es5', 67 | plugins: [ 68 | postcssPlugin, 69 | ], 70 | }); 71 | assert.strictEqual(result.result, prettierFormatted); 72 | } 73 | }; 74 | 75 | suite('SCSS Formatter Extension Tests', () => { 76 | test('it should show the output console', async () => showOutputConsole()); 77 | test('it should fromat CSS', async () => formatSameAsPrettier('./ugly.css')); 78 | test('it should format SCSS', async () => formatSameAsPrettier('./ugly.scss')); 79 | test('it should clear the logs from output console', async () => clearOutput()); 80 | }); 81 | -------------------------------------------------------------------------------- /src/test/suite/index-node.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'fast-glob'; 4 | 5 | export const run = async (): Promise => { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | color: true, 10 | timeout: 10 * 1000, 11 | }); 12 | 13 | const testsRoot = path.resolve(__dirname, '..'); 14 | 15 | try { 16 | const files = await glob('**/**.test.js', { cwd: testsRoot }); 17 | files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); 18 | 19 | await new Promise((c, e) => { 20 | mocha.run((failures) => { 21 | if (failures > 0) { 22 | e(new Error(`${failures} tests failed.`)); 23 | } else { 24 | c(null); 25 | } 26 | }); 27 | }); 28 | } catch (err) { 29 | console.error(err); 30 | throw err; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/test/suite/index-web.ts: -------------------------------------------------------------------------------- 1 | // imports mocha for the browser, defining the `mocha` global. 2 | require('mocha/mocha'); 3 | 4 | export const run = (): Promise => { 5 | return new Promise((c, e) => { 6 | mocha.setup({ 7 | ui: 'tdd', 8 | reporter: undefined, 9 | timeout: 10 * 1000, 10 | }); 11 | 12 | // bundles all files in the current directory matching `*.test` 13 | const importAll = (r: __WebpackModuleApi.RequireContext) => r.keys().forEach(r); 14 | importAll(require.context('.', true, /\.test$/)); 15 | 16 | try { 17 | // Run the mocha test 18 | mocha.run((failures) => { 19 | if (failures > 0) { 20 | e(new Error(`${failures} tests failed.`)); 21 | } else { 22 | c(); 23 | } 24 | }); 25 | } catch (err) { 26 | console.error(err); 27 | e(err); 28 | } 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import type { BuiltInParserName } from 'prettier'; 2 | import { type DocumentSelector, extensions } from 'vscode'; 3 | 4 | /** 5 | * @returns {string} package version 6 | */ 7 | const getExtensionVersion = (): string | null => { 8 | const extension = extensions.getExtension('sibiraj-s.vscode-scss-formatter'); 9 | if (extension && extension.packageJSON) { 10 | return extension.packageJSON.version; 11 | } 12 | return null; 13 | }; 14 | 15 | /** languages supported by scss formatter */ 16 | export const supportedLanguages: BuiltInParserName[] = [ 17 | 'css', 18 | 'scss', 19 | ]; 20 | 21 | /** files to format by language */ 22 | export const languageSelector: DocumentSelector = supportedLanguages.map((language) => ({ language })); 23 | 24 | export const EXTENSION_NAME = 'SCSS Formatter'; 25 | export const EXTENSION_VERSION: string | null = getExtensionVersion(); 26 | -------------------------------------------------------------------------------- /test-workspace/fixtures/play.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 16px; 3 | } 4 | 5 | body { 6 | padding: 0; 7 | margin: 0; 8 | font-size: 1rem; 9 | } 10 | 11 | *, 12 | *::before, 13 | *::after { 14 | box-sizing: border-box; 15 | } 16 | -------------------------------------------------------------------------------- /test-workspace/fixtures/ugly.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-size: 12px; 3 | font-family: monospace; 4 | --color: #FF555B; 5 | --bg: #FDFDF2; 6 | } 7 | 8 | * { margin: 0; 9 | padding: 0; 10 | box-sizing: border-box; user-select: none; -webkit-tap-highlight-color: transparent; 11 | } 12 | 13 | html, body { 14 | overflow: hidden; 15 | } 16 | 17 | body { 18 | width: 100vw; 19 | height: 100vh; 20 | color: var(--color); background-color: var(--bg); 21 | } 22 | 23 | a { 24 | color: inherit; 25 | } svg { 26 | display: block; 27 | fill: currentColor; 28 | } .credits { 29 | position: fixed; 30 | bottom: 1rem; right: 1rem; 31 | font-size: 0.75rem; 32 | } 33 | 34 | .credits > span { 35 | display: flex; 36 | align-items: center; 37 | justify-content: flex-end; 38 | } 39 | 40 | .hide { opacity: 0; } 41 | -------------------------------------------------------------------------------- /test-workspace/fixtures/ugly.scss: -------------------------------------------------------------------------------- 1 | html { box-sizing: box-model; } 2 | *, *:before, *:after { box-sizing: inherit; outline:0; } 3 | header,main,nav,article,section,figure,figcaption,code{ display:block;position: relative; } 4 | 5 | 6 | @mixin aspect-ratio($arglist... /*$width/$ratio, $height*/){ 7 | $map : keywords($arglist); 8 | $height: map-get($map, height) or nth-or-null($arglist, 2); 9 | $width: map-get($map, width) or nth-or-null($arglist, 1); 10 | $ratio: map-get($map, ratio) or if($width and $height, $width/$height, nth-or-null($arglist, 1)) or 1; 11 | $padding: 1/$ratio * 100%; 12 | &:before { content: ''; float:left; padding-bottom: $padding; } 13 | &:after { content: ''; display:table; clear: both; } 14 | } 15 | // Helper function 16 | // Return null rather than throwing an error if index is outside list range. 17 | @function nth-or-null($list, $index) { 18 | @return if(length($list) >= $index, nth($list, $index), null); 19 | } 20 | 21 | // 22 | // Function to create an optimized svg url 23 | // 24 | @function svg-url($svg){ 25 | // 26 | // Add missing namespace 27 | // 28 | @if not str-index($svg,xmlns) { 29 | $svg: str-replace($svg, '', '%3E'); 52 | 53 | 54 | $encoded: #{$encoded}#{$chunk}; 55 | $index: $index + $slice; 56 | } 57 | @return url("data:image/svg+xml,#{$encoded}"); 58 | } 59 | 60 | 61 | 62 | // Background svg mixin 63 | @mixin background-svg($svg){ 64 | background-image: svg-url($svg); 65 | } 66 | 67 | // Helper function to replace characters in a string 68 | @function str-replace($string, $search, $replace: '') { 69 | $index: str-index($string, $search); 70 | @return if($index, 71 | str-slice($string, 1, $index - 1) + $replace + 72 | str-replace(str-slice($string, $index + 73 | str-length($search)), $search, $replace), 74 | $string); 75 | } 76 | 77 | 78 | 79 | $svg-cartman:''; 80 | 81 | .cartman { 82 | @include aspect-ratio(); 83 | width: 40%; 84 | margin: 40px 0; 85 | padding: 0; 86 | position: relative; 87 | @include background-svg($svg-cartman); // <= here :-) 88 | background-size: cover; 89 | background-repeat:no-repeat; 90 | background-position:50% 50%; 91 | } 92 | 93 | figcaption { 94 | position:absolute; 95 | display:block; 96 | left: 100%; 97 | &:before,&:after { 98 | content:''; 99 | position:absolute; 100 | display:block; 101 | } 102 | &:before { 103 | font:15px 'Comic Sans MS'; 104 | content:'SVG in CSS freaking sucks ...Wait What!'; 105 | text-transform:uppercase; 106 | width:230px; 107 | text-align:center; 108 | border:1px solid #f1f1f1; 109 | background:white; 110 | border-radius:5px; 111 | padding:20px; 112 | } 113 | &:after{ 114 | top:75px; 115 | left: 10px; 116 | transform:rotate(30deg); 117 | border-top:30px solid white; 118 | border-left:10px solid transparent; 119 | border-right:10px solid transparent; 120 | } 121 | } 122 | 123 | $logo-color : #00b8c4; 124 | $body-color : whitesmoke; 125 | $h1-color : #00b8c4; 126 | $h2-color : #00b8c4; 127 | $h3-color : #00b8c4; 128 | $text-color : #282828; 129 | $link-color : #00b8c4; 130 | 131 | 132 | html { box-sizing: box-model; } 133 | *, *:before, *:after { box-sizing: inherit; } 134 | header,main,nav,article,section,figure,figcaption,code{ display:block;position: relative; } 135 | 136 | 137 | @include google-font{ 138 | @include google-font(Lato, 300 400 700); 139 | @include google-font(Lato, 300 400 700, italic); 140 | @include google-font('Playfair Display', $text: '“”‘’"\''); 141 | @include google-font('Lateef'); 142 | } 143 | 144 | p,label { font: 400 16px/1.3 'Lato', sans-serif; color: $text-color; } 145 | h1 { font: 300 36px/1.3 'Lato', sans-serif; color: $h1-color; } 146 | h2 { font: 300 24px/1.3 'Lato', sans-serif; color: $h2-color; } 147 | [class*="example"] {font: 400 14px/1.3 'Lato', sans-serif; color: white; } 148 | a {color: $link-color; text-decoration: none; &:hover,&:focus { 149 | text-decoration: underline; 150 | }} 151 | 152 | strong { font: inherit; font-weight: 700; } 153 | em { font: inherit; font-style: italic; } 154 | p { max-width: 700px; } 155 | blockquote { 156 | padding:0; margin:20px 0; 157 | &:before { content: '“'; font-family: 'Playfair Display'; font-size:16px; } 158 | &:after { content: '”'; font-family: 'Playfair Display'; font-size:16px; } 159 | } 160 | [data-related-pens] { background: $logo-color; } 161 | 162 | 163 | body { 164 | background: $body-color; 165 | } 166 | article { 167 | margin:-20px auto 40px; 168 | max-width: 900px; 169 | border-radius: 7px; 170 | padding: 20px 40px 0; 171 | // background: white; 172 | // box-shadow: 0 5px 5px rgba(0, 0, 0, 0.2); 173 | } 174 | section { margin: 40px 0; } 175 | 176 | textarea { 177 | outline: 0; 178 | margin-top: 8px; 179 | width:100%; 180 | height:200px; 181 | background:whitesmoke; 182 | border:1px solid #dddd; 183 | } 184 | input { margin-top: 8px; outline: 0; background:whitesmoke; font-size:20px; padding:10px; border:1px solid #dddd; display:block; 185 | width:calc(100% - 20px); } 186 | [for="pastezone"], 187 | [for="peninclude"]{font-weight: 700; } 188 | 189 | .class { 190 | width: min(91vw, var(--max-width)); 191 | } 192 | -------------------------------------------------------------------------------- /test-workspace/test.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "fixtures" 5 | } 6 | ], 7 | "settings": { 8 | "editor.detectIndentation": false, 9 | "editor.tabSize": 2, 10 | "[css]": { 11 | "editor.defaultFormatter": "sibiraj-s.vscode-scss-formatter" 12 | }, 13 | "[scss]": { 14 | "editor.defaultFormatter": "sibiraj-s.vscode-scss-formatter" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig-test-web.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src/test/runTest-web.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "outDir": "dist", 6 | "lib": [ 7 | "ES2020", 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true, 12 | "noUnusedLocals": true, 13 | "noImplicitReturns": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "noUnusedParameters": true 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".vscode-test", 20 | ".vscode-test-web" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | /** @typedef {import('webpack').Configuration} WebpackConfig */ 3 | 4 | const path = require('path'); 5 | const webpack = require('webpack'); 6 | 7 | /** @type WebpackConfig */ 8 | const extensionConfig = { 9 | target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ 10 | mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') 11 | entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ 12 | output: { 13 | // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ 14 | path: path.resolve(__dirname, 'dist'), 15 | filename: 'extension.js', 16 | libraryTarget: 'commonjs2', 17 | clean: true, 18 | }, 19 | externals: { 20 | vscode: 'commonjs vscode', // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ 21 | // modules added here also need to be added in the .vscodeignore file 22 | prettier: 'commonjs prettier', 23 | }, 24 | resolve: { 25 | // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader 26 | extensions: ['.ts', '.js'], 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.ts$/, 32 | exclude: /node_modules/, 33 | use: [ 34 | { 35 | loader: 'ts-loader', 36 | }, 37 | ], 38 | }, 39 | ], 40 | }, 41 | devtool: 'nosources-source-map', 42 | infrastructureLogging: { 43 | level: 'log', // enables logging required for problem matchers 44 | }, 45 | }; 46 | 47 | /** @type WebpackConfig */ 48 | const webExtensionConfig = { 49 | mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') 50 | target: 'webworker', // extensions run in a webworker context 51 | entry: { 52 | 'extension': './src/extension.ts', 53 | 'test/suite/index-web': './src/test/suite/index-web.ts', 54 | }, 55 | output: { 56 | filename: '[name].js', 57 | path: path.join(__dirname, './dist/web'), 58 | libraryTarget: 'commonjs', 59 | devtoolModuleFilenameTemplate: '../../[resource-path]', 60 | clean: true, 61 | }, 62 | resolve: { 63 | mainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules 64 | extensions: ['.ts', '.js'], // support ts-files and js-files 65 | alias: { 66 | // provides alternate implementation for node module and source files 67 | }, 68 | fallback: { 69 | // Webpack 5 no longer polyfills Node.js core modules automatically. 70 | // see https://webpack.js.org/configuration/resolve/#resolvefallback 71 | // for the list of Node.js core module polyfills. 72 | assert: require.resolve('assert'), 73 | }, 74 | }, 75 | module: { 76 | rules: [{ 77 | test: /\.ts$/, 78 | exclude: /node_modules/, 79 | use: [{ 80 | loader: 'ts-loader', 81 | }], 82 | }], 83 | }, 84 | plugins: [ 85 | new webpack.ProvidePlugin({ 86 | process: 'process/browser', // provide a shim for the global `process` variable 87 | }), 88 | ], 89 | externals: { 90 | vscode: 'commonjs vscode', // ignored because it doesn't exist 91 | }, 92 | performance: { 93 | hints: false, 94 | }, 95 | devtool: 'nosources-source-map', // create a source map that points to the original source file 96 | infrastructureLogging: { 97 | level: 'log', // enables logging required for problem matchers 98 | }, 99 | }; 100 | 101 | module.exports = [extensionConfig, webExtensionConfig]; 102 | --------------------------------------------------------------------------------