├── .github
└── workflows
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── DEVELOPMENT.md
├── LICENSE
├── README.md
├── icon.png
├── package-lock.json
├── package.json
├── src
└── extension.ts
├── tsconfig.json
└── tslint.json
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v1
14 |
15 | - name: Use Node.js 12.x
16 | uses: actions/setup-node@v1
17 | with:
18 | node-version: 12.x
19 |
20 | - name: install
21 | run: |
22 | npm ci
23 | env:
24 | CI: 1
25 |
26 | - name: build
27 | run: |
28 | npm run compile
29 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v*"
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v1
13 |
14 | - name: Use Node.js 12.x
15 | uses: actions/setup-node@v1
16 | with:
17 | node-version: 12.x
18 |
19 | - name: install
20 | run: |
21 | npm ci
22 | npm i -g vsce
23 | env:
24 | CI: 1
25 |
26 | - name: Build & Package
27 | run: |
28 | npm run compile
29 | vsce package
30 |
31 | - name: Publish
32 | run: |
33 | vsce publish -p $VSCE_TOKEN
34 | cp format-code-action-*.vsix format-code-action.vsix
35 | env:
36 | VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }}
37 |
38 | - name: Create Release
39 | id: create_release
40 | uses: softprops/action-gh-release@v1
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | with:
44 | files: format-code-action.vsix
45 | draft: false
46 | prerelease: false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | # build
64 | /build
65 | /out
66 |
67 | # misc
68 | .DS_Store
69 | .idea
70 | .env.local
71 | .env.development.local
72 | .env.test.local
73 | .env.production.local
74 |
75 | # Test report
76 | junit.xml
77 | reports
78 |
79 | *.vsix
80 |
--------------------------------------------------------------------------------
/.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 | "--extensionDevelopmentPath=${workspaceFolder}"
15 | ],
16 | "outFiles": [
17 | "${workspaceFolder}/out/**/*.js"
18 | ],
19 | "preLaunchTask": "npm: watch"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.insertSpaces": false
3 | }
--------------------------------------------------------------------------------
/.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": "watch",
9 | "problemMatcher": "$tsc-watch",
10 | "isBackground": true,
11 | "presentation": {
12 | "reveal": "never"
13 | },
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | # Development
2 |
3 | ## Requirements
4 |
5 | - NodeJS
6 | - VS Code
7 |
8 | ## Setup
9 |
10 | 1. Install dependencies
11 |
12 | ```sh
13 | npm i
14 | ```
15 |
16 | 1. Open in VS Code
17 |
18 | ```sh
19 | code .
20 | ```
21 |
22 | 1. Use the `Run Extension` command in Debugger panel to start a new instance of VS Code with extension added
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Rohit Gohri
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 | # Format Code Action
2 |
3 | [](https://marketplace.visualstudio.com/items?itemName=rohit-gohri.format-code-action) [](https://marketplace.visualstudio.com/items?itemName=rohit-gohri.format-code-action) [](https://marketplace.visualstudio.com/items?itemName=rohit-gohri.format-code-action)
4 |
5 | Run eslint extension after the prettier extension in VS Code. Or the other way around, whatever way you want.
6 |
7 | ## Installation
8 |
9 | > Requires VS Code 1.44+
10 |
11 | Install through VS Code extensions: [Visual Studio Code Market Place: Format Code Action](https://marketplace.visualstudio.com/items?itemName=rohit-gohri.format-code-action)
12 |
13 | Or install from within VS Code: Launch VS Code Quick Open (Ctrl+P or cmd+P), paste the following command, and press enter.
14 |
15 | ext install rohit-gohri.format-code-action
16 |
17 | Or on the command line:
18 |
19 | code --install-extension rohit-gohri.format-code-action
20 |
21 | ## Usage
22 |
23 | Disable `formatOnSave` and use the `source.formatDocument` codeAction in whatever order you want with VS Code settings:
24 |
25 | ```json
26 | "editor.formatOnSave": false,
27 | "editor.defaultFormatter": "esbenp.prettier-vscode",
28 | "editor.codeActionsOnSave": [
29 | "source.formatDocument",
30 | "source.fixAll.eslint"
31 | ]
32 | ```
33 |
34 | > NOTE: This was first released with `source.fixAll.format` as the codeAction, that still works for legacy purposes.
35 |
36 | This runs 'Format Document' with the default formatter (in this case prettier).
37 |
38 | Or for specific lanuage only:
39 |
40 | ```json
41 | "editor.formatOnSave": true,
42 | "editor.defaultFormatter": "esbenp.prettier-vscode",
43 | "[javascript]": {
44 | "editor.formatOnSave": false,
45 | "editor.codeActionsOnSave": ["source.formatDocument", "source.fixAll.eslint"]
46 | },
47 | ```
48 |
49 | This would run prettier by default, but for javascript files would run prettier and then eslint. If you want to reverse the order then just reverse the array.
50 |
51 | ### Format Modified (EXPERIMENTAL)
52 |
53 | Alternatively you may want to format only the modified part of the file, in that case use `source.formatModified`:
54 |
55 | ```json
56 | "editor.formatOnSave": false,
57 | "editor.defaultFormatter": "esbenp.prettier-vscode",
58 | "editor.codeActionsOnSave": [
59 | "source.formatModified",
60 | "source.fixAll.eslint"
61 | ]
62 | ```
63 |
64 | This is experimentally supported right now, if you face any problems please report them at:
65 |
66 | ## Motivation
67 |
68 | I created this so I could use prettier and eslint together in the editor, in a specific order (eslint after prettier). Earlier prettier was setup to run on save and eslint as a codeAction with:
69 |
70 | ```json
71 | "editor.formatOnSave": true,
72 | "editor.defaultFormatter": "esbenp.prettier-vscode",
73 | "editor.codeActionsOnSave": {
74 | "source.fixAll.eslint": true
75 | }
76 | ```
77 |
78 | This would often lead to prettier being run after eslint and eslint errors still being present.
79 |
80 | Since the [March 2020 (v1.44)](https://code.visualstudio.com/updates/v1_44#_explicit-ordering-for-code-actions-on-save) update, VS Code allows setting `codeActionsOnSave` as an array. This allows setting the order of the codeActions.
81 |
82 | The extension uses the [`CodeActionProvider`](https://code.visualstudio.com/api/references/vscode-api#CodeActionProvider) api to implement a simple code action that runs 'Format Document' on the current file. This allows us to disable `formatOnSave` and use it as a codeAction instead in a specific order with other extensions.
83 |
84 | Read More on my blog: [How to get ESlint and Prettier to play nicely in VS Code?](https://rohit.page/blog/posts/how-to-get-prettier-eslint-play-nicely-with-vscode/?utm_source=github&utm_medium=repo&utm_campaign=hf)
85 |
86 | ## VS Code API
87 |
88 | ### `vscode` module
89 |
90 | - [`languages.registerCodeActionsProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerCodeActionsProvider)
91 |
92 | ## Credits
93 |
94 | Based on [Microsoft's code-actions-sample](https://github.com/microsoft/vscode-extension-samples/tree/master/code-actions-sample)
95 |
96 | ### Icon
97 |
98 | [formatting by Danil Polshin from the Noun Project](https://thenounproject.com/search/?q=format&i=627383).
99 |
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohit-gohri/vscode-format-code-action/4356df8a166125a5fff2162c2213620579a157c2/icon.png
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "format-code-action",
3 | "version": "0.1.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@babel/code-frame": {
8 | "version": "7.8.3",
9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
10 | "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
11 | "dev": true,
12 | "requires": {
13 | "@babel/highlight": "^7.8.3"
14 | }
15 | },
16 | "@babel/helper-validator-identifier": {
17 | "version": "7.9.5",
18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
19 | "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
20 | "dev": true
21 | },
22 | "@babel/highlight": {
23 | "version": "7.9.0",
24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
25 | "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
26 | "dev": true,
27 | "requires": {
28 | "@babel/helper-validator-identifier": "^7.9.0",
29 | "chalk": "^2.0.0",
30 | "js-tokens": "^4.0.0"
31 | }
32 | },
33 | "@types/node": {
34 | "version": "12.12.35",
35 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.35.tgz",
36 | "integrity": "sha512-ASYsaKecA7TUsDrqIGPNk3JeEox0z/0XR/WsJJ8BIX/9+SkMSImQXKWfU/yBrSyc7ZSE/NPqLu36Nur0miCFfQ==",
37 | "dev": true
38 | },
39 | "@types/vscode": {
40 | "version": "1.33.0",
41 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.33.0.tgz",
42 | "integrity": "sha512-JSmGiValbrcG5g20jjCfKakLiuWyrcjVezj+SEAEZ4klXQktE5EtowuGlkLVqbkiBK4iY5wy/4yW8OjecuHnjQ==",
43 | "dev": true
44 | },
45 | "ansi-styles": {
46 | "version": "3.2.1",
47 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
48 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
49 | "dev": true,
50 | "requires": {
51 | "color-convert": "^1.9.0"
52 | }
53 | },
54 | "argparse": {
55 | "version": "1.0.10",
56 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
57 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
58 | "dev": true,
59 | "requires": {
60 | "sprintf-js": "~1.0.2"
61 | }
62 | },
63 | "balanced-match": {
64 | "version": "1.0.0",
65 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
66 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
67 | "dev": true
68 | },
69 | "brace-expansion": {
70 | "version": "1.1.11",
71 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
72 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
73 | "dev": true,
74 | "requires": {
75 | "balanced-match": "^1.0.0",
76 | "concat-map": "0.0.1"
77 | }
78 | },
79 | "builtin-modules": {
80 | "version": "1.1.1",
81 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
82 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
83 | "dev": true
84 | },
85 | "chalk": {
86 | "version": "2.4.2",
87 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
88 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
89 | "dev": true,
90 | "requires": {
91 | "ansi-styles": "^3.2.1",
92 | "escape-string-regexp": "^1.0.5",
93 | "supports-color": "^5.3.0"
94 | }
95 | },
96 | "color-convert": {
97 | "version": "1.9.3",
98 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
99 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
100 | "dev": true,
101 | "requires": {
102 | "color-name": "1.1.3"
103 | }
104 | },
105 | "color-name": {
106 | "version": "1.1.3",
107 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
108 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
109 | "dev": true
110 | },
111 | "commander": {
112 | "version": "2.20.3",
113 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
114 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
115 | "dev": true
116 | },
117 | "concat-map": {
118 | "version": "0.0.1",
119 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
120 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
121 | "dev": true
122 | },
123 | "diff": {
124 | "version": "4.0.2",
125 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
126 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
127 | "dev": true
128 | },
129 | "escape-string-regexp": {
130 | "version": "1.0.5",
131 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
132 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
133 | "dev": true
134 | },
135 | "esprima": {
136 | "version": "4.0.1",
137 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
138 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
139 | "dev": true
140 | },
141 | "fs.realpath": {
142 | "version": "1.0.0",
143 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
144 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
145 | "dev": true
146 | },
147 | "glob": {
148 | "version": "7.1.6",
149 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
150 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
151 | "dev": true,
152 | "requires": {
153 | "fs.realpath": "^1.0.0",
154 | "inflight": "^1.0.4",
155 | "inherits": "2",
156 | "minimatch": "^3.0.4",
157 | "once": "^1.3.0",
158 | "path-is-absolute": "^1.0.0"
159 | }
160 | },
161 | "has-flag": {
162 | "version": "3.0.0",
163 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
164 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
165 | "dev": true
166 | },
167 | "inflight": {
168 | "version": "1.0.6",
169 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
170 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
171 | "dev": true,
172 | "requires": {
173 | "once": "^1.3.0",
174 | "wrappy": "1"
175 | }
176 | },
177 | "inherits": {
178 | "version": "2.0.4",
179 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
180 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
181 | "dev": true
182 | },
183 | "js-tokens": {
184 | "version": "4.0.0",
185 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
186 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
187 | "dev": true
188 | },
189 | "js-yaml": {
190 | "version": "3.13.1",
191 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
192 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
193 | "dev": true,
194 | "requires": {
195 | "argparse": "^1.0.7",
196 | "esprima": "^4.0.0"
197 | }
198 | },
199 | "minimatch": {
200 | "version": "3.0.4",
201 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
202 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
203 | "dev": true,
204 | "requires": {
205 | "brace-expansion": "^1.1.7"
206 | }
207 | },
208 | "minimist": {
209 | "version": "1.2.5",
210 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
211 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
212 | "dev": true
213 | },
214 | "mkdirp": {
215 | "version": "0.5.5",
216 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
217 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
218 | "dev": true,
219 | "requires": {
220 | "minimist": "^1.2.5"
221 | }
222 | },
223 | "once": {
224 | "version": "1.4.0",
225 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
226 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
227 | "dev": true,
228 | "requires": {
229 | "wrappy": "1"
230 | }
231 | },
232 | "path-is-absolute": {
233 | "version": "1.0.1",
234 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
235 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
236 | "dev": true
237 | },
238 | "path-parse": {
239 | "version": "1.0.6",
240 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
241 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
242 | "dev": true
243 | },
244 | "resolve": {
245 | "version": "1.15.1",
246 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
247 | "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
248 | "dev": true,
249 | "requires": {
250 | "path-parse": "^1.0.6"
251 | }
252 | },
253 | "semver": {
254 | "version": "5.7.1",
255 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
256 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
257 | "dev": true
258 | },
259 | "sprintf-js": {
260 | "version": "1.0.3",
261 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
262 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
263 | "dev": true
264 | },
265 | "supports-color": {
266 | "version": "5.5.0",
267 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
268 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
269 | "dev": true,
270 | "requires": {
271 | "has-flag": "^3.0.0"
272 | }
273 | },
274 | "tslib": {
275 | "version": "1.11.1",
276 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
277 | "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
278 | "dev": true
279 | },
280 | "tslint": {
281 | "version": "5.20.1",
282 | "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz",
283 | "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==",
284 | "dev": true,
285 | "requires": {
286 | "@babel/code-frame": "^7.0.0",
287 | "builtin-modules": "^1.1.1",
288 | "chalk": "^2.3.0",
289 | "commander": "^2.12.1",
290 | "diff": "^4.0.1",
291 | "glob": "^7.1.1",
292 | "js-yaml": "^3.13.1",
293 | "minimatch": "^3.0.4",
294 | "mkdirp": "^0.5.1",
295 | "resolve": "^1.3.2",
296 | "semver": "^5.3.0",
297 | "tslib": "^1.8.0",
298 | "tsutils": "^2.29.0"
299 | }
300 | },
301 | "tsutils": {
302 | "version": "2.29.0",
303 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
304 | "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
305 | "dev": true,
306 | "requires": {
307 | "tslib": "^1.8.1"
308 | }
309 | },
310 | "typescript": {
311 | "version": "3.8.3",
312 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
313 | "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
314 | "dev": true
315 | },
316 | "wrappy": {
317 | "version": "1.0.2",
318 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
319 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
320 | "dev": true
321 | }
322 | }
323 | }
324 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "format-code-action",
3 | "private": true,
4 | "displayName": "Format Code Action",
5 | "version": "0.1.0",
6 | "publisher": "rohit-gohri",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/rohit-gohri/vscode-format-code-action"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/rohit-gohri/vscode-format-code-action/issues"
13 | },
14 | "engines": {
15 | "vscode": "^1.44.0"
16 | },
17 | "icon": "icon.png",
18 | "categories": [
19 | "Other",
20 | "Formatters"
21 | ],
22 | "activationEvents": [
23 | "*"
24 | ],
25 | "main": "./out/extension.js",
26 | "scripts": {
27 | "vscode:prepublish": "npm run compile",
28 | "compile": "tsc -p ./",
29 | "lint": "tslint -p ./",
30 | "watch": "tsc -watch -p ./"
31 | },
32 | "devDependencies": {
33 | "@types/node": "^12.12.0",
34 | "tslint": "^5.19.0",
35 | "typescript": "^3.8.3",
36 | "@types/vscode": "^1.32.0"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------
2 | * Copyright (C) Rohit Gohri (https://rohit.page). All rights reserved.
3 | *--------------------------------------------------------*/
4 |
5 | import * as vscode from "vscode";
6 |
7 | const FORMAT_DOCUMENT = "editor.action.formatDocument";
8 | const FORMAT_MODIFIED = "editor.action.formatChanges";
9 |
10 | /**
11 | * @deprecated
12 | */
13 | const DOCUMENT_CODE_ACTION_KIND_LEGACY = vscode.CodeActionKind.SourceFixAll.append(
14 | "format"
15 | );
16 |
17 | const DOCUMENT_CODE_ACTION_KIND = vscode.CodeActionKind.Source.append(
18 | "formatDocument"
19 | );
20 | const MODIFIED_CODE_ACTION_KIND = vscode.CodeActionKind.Source.append(
21 | "formatModified"
22 | );
23 |
24 | export function activate(context: vscode.ExtensionContext) {
25 | context.subscriptions.push(
26 | vscode.languages.registerCodeActionsProvider("*", new FormatActions(), {
27 | providedCodeActionKinds: FormatActions.providedCodeActionKinds,
28 | })
29 | );
30 | }
31 |
32 | let cache: vscode.CodeAction[] | undefined;
33 |
34 | /**
35 | * Provides code actions for calling format document and format modified
36 | */
37 | export class FormatActions implements vscode.CodeActionProvider {
38 | public static readonly providedCodeActionKinds = [
39 | DOCUMENT_CODE_ACTION_KIND_LEGACY,
40 | DOCUMENT_CODE_ACTION_KIND,
41 | MODIFIED_CODE_ACTION_KIND,
42 | ];
43 |
44 | public provideCodeActions(
45 | document: vscode.TextDocument,
46 | range: vscode.Range
47 | ): vscode.CodeAction[] | undefined {
48 | if (cache) return cache;
49 | const formatDocumentActionLegacy = this.getFormatDocumentAction(
50 | DOCUMENT_CODE_ACTION_KIND_LEGACY
51 | );
52 | const formatDocumentAction = this.getFormatDocumentAction();
53 | const formatModifiedAction = this.getFormatModifiedAction();
54 |
55 | cache = [
56 | formatDocumentActionLegacy,
57 | formatDocumentAction,
58 | formatModifiedAction,
59 | ];
60 | return cache;
61 | }
62 |
63 | private getFormatDocumentAction(
64 | actionKind: vscode.CodeActionKind = DOCUMENT_CODE_ACTION_KIND
65 | ): vscode.CodeAction {
66 | const action = new vscode.CodeAction("Format Document", actionKind);
67 | action.command = {
68 | command: FORMAT_DOCUMENT,
69 | title: "Format Document",
70 | tooltip: "This will format the document with the default formatter.",
71 | };
72 | return action;
73 | }
74 |
75 | private getFormatModifiedAction(): vscode.CodeAction {
76 | const action = new vscode.CodeAction(
77 | "Format Modified",
78 | MODIFIED_CODE_ACTION_KIND
79 | );
80 | action.command = {
81 | command: FORMAT_MODIFIED,
82 | title: "Format Modified",
83 | tooltip:
84 | "This will format the document's modified content (requires version control) with the default formatter.",
85 | };
86 | return action;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es6",
5 | "outDir": "out",
6 | "sourceMap": true,
7 | "strict": true,
8 | "rootDir": "src"
9 | },
10 | "exclude": [
11 | "node_modules",
12 | ".vscode-test"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "indent": [true, "tabs"],
4 | "semicolon": [true, "always"]
5 | }
6 | }
--------------------------------------------------------------------------------