├── .esbuild.config.js ├── .eslintrc ├── .gitignore ├── .prettierrc.json ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── exampleFiles ├── .babelrc ├── .eslintrc ├── .nycrc.json ├── .prettierrc ├── cypress.json ├── lerna.json ├── npm │ ├── .npmrc │ └── package.json └── tsconfig.json ├── icon.png ├── l10n └── bundle.l10n.zh-cn.json ├── media └── editor │ ├── index.ts │ ├── npm.ts │ ├── prettier.ts │ ├── schema.ts │ ├── schema │ ├── babelrc.json │ ├── cypress.json │ ├── eslintrc.json │ ├── lerna.json │ ├── nycrc.json │ └── tsconfig.json │ ├── search.ts │ ├── setting.ts │ ├── style.scss │ ├── toc.ts │ └── util.ts ├── package.json ├── src ├── extension.ts ├── settingsEditorProvider.ts └── util.ts └── tsconfig.json /.esbuild.config.js: -------------------------------------------------------------------------------- 1 | const esbuild = require('esbuild') 2 | const sassPlugin = require('esbuild-sass-plugin').sassPlugin 3 | 4 | const watch = process.argv.includes('--watch') 5 | const minify = !watch 6 | 7 | const replaceNodeBuiltIns = () => { 8 | const replace = { 9 | path: require.resolve('path-browserify'), 10 | } 11 | const filter = RegExp(`^(${Object.keys(replace).join('|')})$`) 12 | return { 13 | name: 'replaceNodeBuiltIns', 14 | setup(build) { 15 | build.onResolve({ filter }, (arg) => ({ 16 | path: replace[arg.path], 17 | })) 18 | }, 19 | } 20 | } 21 | 22 | esbuild 23 | .build({ 24 | entryPoints: ['src/extension.ts'], 25 | tsconfig: './tsconfig.json', 26 | bundle: true, 27 | external: ['vscode'], 28 | sourcemap: watch, 29 | minify, 30 | watch, 31 | platform: 'node', 32 | outfile: 'dist/extension.js', 33 | }) 34 | .catch(() => process.exit(1)) 35 | 36 | esbuild 37 | .build({ 38 | entryPoints: ['media/editor/index.ts'], 39 | tsconfig: './tsconfig.json', 40 | bundle: true, 41 | external: ['vscode'], 42 | sourcemap: watch ? 'inline' : false, 43 | minify, 44 | watch, 45 | plugins: [replaceNodeBuiltIns()], 46 | mainFields: ['browser', 'module', 'main'], 47 | platform: 'browser', 48 | outfile: 'dist/editor.js', 49 | }) 50 | .catch(() => process.exit(1)) 51 | 52 | esbuild 53 | .build({ 54 | entryPoints: ['media/editor/style.scss'], 55 | bundle: true, 56 | minify, 57 | plugins: [sassPlugin()], 58 | watch, 59 | outfile: 'dist/editor.css', 60 | }) 61 | .catch(() => process.exit(1)) 62 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "extends": ["prettier"], 9 | "plugins": ["@typescript-eslint"], 10 | "rules": { 11 | "@typescript-eslint/naming-convention": "warn", 12 | "curly": "warn", 13 | "eqeqeq": "warn", 14 | "no-throw-literal": "warn", 15 | "semi": "off" 16 | }, 17 | "ignorePatterns": ["out", "dist", "**/*.d.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | out/ 4 | *.vsix 5 | package-lock.json -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "tabWidth": 2, 4 | "semi": false, 5 | "printWidth": 80 6 | } 7 | -------------------------------------------------------------------------------- /.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 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.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 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/out/**/*.js" 17 | ] 18 | }, 19 | { 20 | "name": "Extension Tests", 21 | "type": "extensionHost", 22 | "request": "launch", 23 | "args": [ 24 | "--extensionDevelopmentPath=${workspaceFolder}", 25 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 26 | ], 27 | "outFiles": [ 28 | "${workspaceFolder}/out/test/**/*.js" 29 | ], 30 | "preLaunchTask": "${defaultBuildTask}" 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /.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 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | src/** 4 | media/** 5 | exampleFiles/** 6 | .gitignore 7 | .yarnrc 8 | vsc-extension-quickstart.md 9 | **/tsconfig.json 10 | **/.eslintrc.json 11 | **/*.map 12 | **/*.ts 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.2 (27 Feb 2023) 2 | 3 | * feat: tsconfig.json extends path support 4 | 5 | ## 1.0.1 (23 Feb 2023) 6 | 7 | * fix: windows select path not normalized -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022-present liriliri 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 Settings Editor 2 | 3 | VS Code visual editor for settings like prettierrc, tsconfig etc. 4 | 5 | ![settings-editor](https://res.liriliri.io/other/vscode-settings-editor.gif) 6 | 7 | ## Install 8 | 9 | 1. Open Extensions sideBar panel in Visual Studio Code and choose the menu options for View → Extensions 10 | 1. Search for `vscode-settings-editor` 11 | 1. Click Install 12 | 1. Click Reload, if required 13 | 14 | ## Features 15 | 16 | Supported configuration type: 17 | 18 | * npm 19 | - package.json 20 | - .npmrc 21 | * prettier 22 | - .prettierrc 23 | * typescript 24 | - tsconfig.json 25 | * cypress 26 | - cypress.json 27 | * lerna 28 | - lerna.json 29 | * istanbul 30 | - .nycrc 31 | * babel 32 | - .babelrc 33 | * eslint 34 | - .eslintrc 35 | 36 | ## How to Use 37 | 38 | Click button on editor title to open settings visual editor. 39 | -------------------------------------------------------------------------------- /exampleFiles/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { 4 | "useBuiltIns": "usage", 5 | "corejs": 3.28 6 | }], 7 | "minify" 8 | ], 9 | "comments": false 10 | } -------------------------------------------------------------------------------- /exampleFiles/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "extends": ["prettier"], 9 | "plugins": ["@typescript-eslint"], 10 | "rules": { 11 | "@typescript-eslint/naming-convention": "warn", 12 | "curly": "warn", 13 | "eqeqeq": "warn", 14 | "no-throw-literal": "warn", 15 | "semi": "off" 16 | }, 17 | "ignorePatterns": ["out", "dist", "**/*.d.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /exampleFiles/.nycrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@istanbuljs/nyc-config-typescript", 3 | "reporter": [ 4 | "lcov", 5 | "text", 6 | "text-summary" 7 | ], 8 | "exclude": [ 9 | "js/**/*.d.ts", 10 | "typings/*.d.ts", 11 | "docs/**", 12 | "jsdocs/**", 13 | "coverage/**", 14 | "test/**", 15 | "bin/**", 16 | "lib/lbt/**", 17 | "util/**", 18 | "src/cli.ts", 19 | "index.js", 20 | "js/src/cli.js", 21 | ".prettierrc.js" 22 | ], 23 | "check-coverage": true, 24 | "lines": 50, 25 | "statements": 50, 26 | "functions": 50, 27 | "branches": 40, 28 | "watermarks": { 29 | "lines": [ 30 | 60, 31 | 90 32 | ], 33 | "functions": [ 34 | 60, 35 | 90 36 | ], 37 | "branches": [ 38 | 50, 39 | 70 40 | ], 41 | "statements": [ 42 | 60, 43 | 90 44 | ] 45 | }, 46 | "cache": true, 47 | "all": true, 48 | "report-dir": "./coverage" 49 | } 50 | -------------------------------------------------------------------------------- /exampleFiles/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "tabWidth": 2, 4 | "semi": false, 5 | "printWidth": 80, 6 | "useTabs": false, 7 | "quoteProps": "as-needed", 8 | "bracketSameLine": false 9 | } 10 | -------------------------------------------------------------------------------- /exampleFiles/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectId": "8crkwu", 3 | "baseUrl": "http://localhost:3000", 4 | "numTestsKeptInMemory": 1, 5 | "defaultCommandTimeout": 10000, 6 | "experimentalStudio": true, 7 | "retries": { 8 | "runMode": 2 9 | }, 10 | "env": { 11 | "USE_LIVE_API": false, 12 | "UPDATE_FIXTURES": false 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /exampleFiles/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.0.0" 6 | } 7 | -------------------------------------------------------------------------------- /exampleFiles/npm/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /exampleFiles/npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-settings-editor", 3 | "displayName": "Settings Editor", 4 | "description": "VS Code visual editor for settings like npm package.json", 5 | "version": "0.1.0", 6 | "engines": { 7 | "vscode": "^1.74.0" 8 | }, 9 | "categories": [ 10 | "Other" 11 | ], 12 | "main": "./dist/extension.js", 13 | "scripts": { 14 | "vscode:prepublish": "npm run compile", 15 | "compile": "node .esbuild.config.js", 16 | "format": "prettier \"*.{js,json}\" \"src/**/*.ts\" \"media/**/*.ts\" \"exampleFiles/*.json\" --write", 17 | "watch": "node .esbuild.config.js --watch", 18 | "pretest": "npm run compile && npm run lint", 19 | "lint": "eslint src --ext ts" 20 | }, 21 | "devDependencies": { 22 | "@types/glob": "^8.0.0", 23 | "@types/mocha": "^10.0.1", 24 | "@types/node": "16.x", 25 | "@types/vscode": "^1.74.0", 26 | "@typescript-eslint/eslint-plugin": "^5.45.0", 27 | "@typescript-eslint/parser": "^5.45.0", 28 | "@vscode/test-electron": "^2.2.0", 29 | "esbuild": "^0.16.17", 30 | "esbuild-sass-plugin": "^2.4.5", 31 | "eslint": "^8.28.0", 32 | "glob": "^8.0.3", 33 | "licia": "^1.37.1", 34 | "luna-setting": "^0.3.0", 35 | "mocha": "^10.1.0", 36 | "prettier": "^2.8.3", 37 | "typescript": "^4.9.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /exampleFiles/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "outDir": "out", 6 | "lib": ["ES2020", "DOM"], 7 | "sourceMap": true, 8 | "esModuleInterop": true, 9 | "rootDirs": ["src", "media"], 10 | "strict": true /* enable all strict type-checking options */ 11 | /* Additional Checks */ 12 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 13 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 14 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liriliri/vscode-settings-editor/f3cb655e3255eff7f3095d5ef3c3a79c4e0aee89/icon.png -------------------------------------------------------------------------------- /l10n/bundle.l10n.zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "Running command {command} in terminal settings editor": "正在终端 settings editor 中运行命令 {command}" 3 | } -------------------------------------------------------------------------------- /media/editor/index.ts: -------------------------------------------------------------------------------- 1 | import npm from './npm' 2 | import prettier from './prettier' 3 | import schema from './schema' 4 | import { store, i18n } from './util' 5 | import * as search from './search' 6 | import * as setting from './setting' 7 | 8 | window.process = require('process') 9 | 10 | const handlers: any = { 11 | prettier, 12 | npm, 13 | schema, 14 | } 15 | 16 | window.addEventListener('message', (event) => { 17 | const message = event.data // The json data that the extension sent 18 | switch (message.type) { 19 | case 'update': 20 | const { fileName, text, handler } = message 21 | if (store.get('fileName') === fileName && store.get('text') === text) { 22 | return 23 | } 24 | store.set('fileName', fileName) 25 | store.set('text', text) 26 | store.set('handler', handler) 27 | updateContent() 28 | break 29 | case 'init': 30 | const { language, space } = message 31 | store.set('language', language) 32 | store.set('space', space) 33 | updateLanguage() 34 | break 35 | } 36 | }) 37 | 38 | function updateLanguage() { 39 | const language = store.get('language') 40 | if (language) { 41 | i18n.locale(language) 42 | search.setPlaceHolder(i18n.t('searchSettings')) 43 | } 44 | } 45 | 46 | function updateContent() { 47 | const fileName = store.get('fileName') 48 | const text = store.get('text') 49 | const handler = store.get('handler') 50 | 51 | if (!fileName || !text || !handler) { 52 | return 53 | } 54 | 55 | search.reset() 56 | setting.reset() 57 | 58 | handlers[handler](fileName, text) 59 | } 60 | 61 | updateLanguage() 62 | updateContent() 63 | -------------------------------------------------------------------------------- /media/editor/npm.ts: -------------------------------------------------------------------------------- 1 | import isEmpty from 'licia/isEmpty' 2 | import map from 'licia/map' 3 | import truncate from 'licia/truncate' 4 | import safeSet from 'licia/safeSet' 5 | import splitPath from 'licia/splitPath' 6 | import ini from 'licia/ini' 7 | import { def } from './setting' 8 | import * as setting from './setting' 9 | import { vscode, updateText, i18n, getSpace } from './util' 10 | 11 | export default function handler(fileName: string, text: string) { 12 | const { name } = splitPath(fileName) 13 | 14 | switch (name) { 15 | case 'package.json': 16 | pack(fileName, text) 17 | break 18 | case '.npmrc': 19 | config(text) 20 | break 21 | } 22 | } 23 | 24 | function pack(fileName: string, text: string) { 25 | const json = JSON.parse(text) 26 | setting.onChange((key, val) => { 27 | safeSet(json, key, val) 28 | 29 | if (key === 'license' && val === '') { 30 | delete json.license 31 | } 32 | 33 | updateText(JSON.stringify(json, null, getSpace()) + '\n') 34 | }) 35 | 36 | setting.build([ 37 | ['title', 'Npm Package'], 38 | [ 39 | 'markdown', 40 | i18n.t('seeDoc', { 41 | url: 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json', 42 | }), 43 | ], 44 | [ 45 | 'text', 46 | 'name', 47 | json.name, 48 | 'Name', 49 | 'The name is what your thing is called.', 50 | ], 51 | [ 52 | 'text', 53 | 'version', 54 | json.version, 55 | 'Version', 56 | 'Version must be parseable by node-semver, which is bundled with npm as a dependency. (npm install semver to use it yourself.)', 57 | ], 58 | [ 59 | 'text', 60 | 'description', 61 | json.description, 62 | 'Description', 63 | "This helps people discover your package, as it's listed in npm search.", 64 | ], 65 | [ 66 | 'complex', 67 | 'keywords', 68 | 'Keywords', 69 | "This helps people discover your package as it's listed in npm search.", 70 | ], 71 | [ 72 | 'text', 73 | 'homepage', 74 | def(json.homepage, ''), 75 | 'Homepage', 76 | 'The url to the project homepage.', 77 | ], 78 | ]) 79 | const licenseOptions: any = { 80 | MIT: 'MIT', 81 | ISC: 'ISC', 82 | 'BSD-2-Clause': 'BSD-2-Clause', 83 | none: '', 84 | } 85 | if (json.license) { 86 | licenseOptions[json.license] = json.license 87 | } 88 | setting.build([ 89 | [ 90 | 'select', 91 | 'license', 92 | json.license || '', 93 | 'License', 94 | "You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you're placing on it.", 95 | licenseOptions, 96 | ], 97 | [ 98 | 'path', 99 | 'main', 100 | json.main, 101 | 'Main', 102 | 'The main field is a module ID that is the primary entry point to your program.', 103 | { 104 | extensions: ['js'], 105 | }, 106 | ], 107 | ]) 108 | 109 | if (json.scripts && !isEmpty(json.scripts)) { 110 | const { dir } = splitPath(fileName) 111 | setting.build([ 112 | ['title', 'Scripts'], 113 | ...map(json.scripts, (script: string, name: string) => { 114 | return [ 115 | 'button', 116 | name, 117 | truncate(script, 30), 118 | () => { 119 | vscode.postMessage({ 120 | type: 'run', 121 | command: `cd ${dir} && npm run ${name}`, 122 | }) 123 | }, 124 | ] 125 | }), 126 | ]) 127 | } 128 | } 129 | 130 | function config(text: string) { 131 | const obj = ini.parse(text) 132 | 133 | setting.onChange((key, val) => { 134 | safeSet(obj, key, val) 135 | 136 | updateText(ini.stringify(obj)) 137 | }) 138 | 139 | setting.build([ 140 | ['title', 'Npm Config'], 141 | [ 142 | 'markdown', 143 | i18n.t('seeDoc', { 144 | url: 'https://docs.npmjs.com/cli/v9/using-npm/config', 145 | }), 146 | ], 147 | [ 148 | 'text', 149 | 'registry', 150 | def(obj.registry, 'https://registry.npmjs.org/'), 151 | 'Registry', 152 | 'The base URL of the npm registry.', 153 | ], 154 | [ 155 | 'path', 156 | 'cache', 157 | def(obj.cache, ''), 158 | 'Cache', 159 | "The location of npm's cache directory.", 160 | { 161 | folder: true, 162 | file: false, 163 | absolute: true, 164 | }, 165 | ], 166 | [ 167 | 'text', 168 | 'prefix', 169 | def(obj.prefix, ''), 170 | 'Prefix', 171 | 'In global mode, the folder where the node executable is installed. In local mode, the nearest parent folder containing either a package.json file or a node_modules folder.', 172 | ], 173 | [ 174 | 'text', 175 | 'proxy', 176 | def(obj.proxy, ''), 177 | 'Proxy', 178 | 'A proxy to use for outgoing http requests. If the `HTTP_PROXY` or `http_proxy` environment variables are set, proxy settings will be honored by the underlying `request` library.', 179 | ], 180 | ]) 181 | } 182 | -------------------------------------------------------------------------------- /media/editor/prettier.ts: -------------------------------------------------------------------------------- 1 | import LunaSetting from 'luna-setting' 2 | import safeSet from 'licia/safeSet' 3 | import { def } from './setting' 4 | import * as setting from './setting' 5 | import { i18n, updateText, getSpace, setI18n } from './util' 6 | 7 | setI18n({ 8 | 'prettier.tabWidthDesc': [ 9 | 'Specify the number of spaces per indentation-level.', 10 | '指定缩进空格数。', 11 | ], 12 | }) 13 | 14 | export default function handler(fileName: string, text: string) { 15 | const json = JSON.parse(text) 16 | 17 | setting.onChange((key, val) => { 18 | safeSet(json, key, val) 19 | 20 | updateText(JSON.stringify(json, null, getSpace()) + '\n') 21 | }) 22 | 23 | setting.build([ 24 | ['title', 'Prettier Options'], 25 | [ 26 | 'markdown', 27 | i18n.t('seeDoc', { url: 'https://prettier.io/docs/en/options.html' }), 28 | ], 29 | [ 30 | 'number', 31 | 'printWidth', 32 | def(json.printWidth, 80), 33 | 'Print Width', 34 | 'Specify the line length that the printer will wrap on.', 35 | { min: 0, step: 1, max: Infinity }, 36 | ], 37 | [ 38 | 'number', 39 | 'tabWidth', 40 | def(json.tabWidth, 2), 41 | 'Tab Width', 42 | i18n.t('prettier.tabWidthDesc'), 43 | { 44 | min: 0, 45 | step: 1, 46 | max: 16, 47 | }, 48 | ], 49 | [ 50 | 'checkbox', 51 | 'useTabs', 52 | def(json.useTabs, false), 53 | 'Tabs', 54 | 'Indent lines with tabs instead of spaces.', 55 | ], 56 | [ 57 | 'checkbox', 58 | 'semi', 59 | def(json.semi, true), 60 | 'Semicolons', 61 | 'Print semicolons at the ends of statements.', 62 | ], 63 | [ 64 | 'checkbox', 65 | 'singleQuote', 66 | def(json.singleQuote, false), 67 | 'Quotes', 68 | 'Use single quotes instead of double quotes.', 69 | ], 70 | [ 71 | 'select', 72 | 'quoteProps', 73 | def(json.quoteProps, 'as-needed'), 74 | 'Quote Props', 75 | 'Change when properties in objects are quoted.', 76 | { 77 | 'Only add quotes around object properties where required': 'as-needed', 78 | 'If at least one property in an object requires quotes, quote all properties': 79 | 'consistent', 80 | 'Respect the input use of quotes in object properties': 'preserve', 81 | }, 82 | ], 83 | [ 84 | 'checkbox', 85 | 'jsxSingleQuote', 86 | def(json.jsxSingleQuote, 'false'), 87 | 'JSX Quotes', 88 | 'Use single quotes instead of double quotes in JSX.', 89 | ], 90 | [ 91 | 'select', 92 | 'trailingComma', 93 | def(json.trailingComma, 'es5'), 94 | 'Trailing Commas', 95 | 'Print trailing commas wherever possible in multi-line comma-separated syntactic structures. (A single-line array, for example, never gets trailing commas.)', 96 | { 97 | 'Trailing commas where valid in ES5 (objects, arrays, etc.)': 'es5', 98 | 'No trailing commas': 'none', 99 | 'Trailing commas wherever possible (including function parameters and calls)': 100 | 'all', 101 | }, 102 | ], 103 | [ 104 | 'checkbox', 105 | 'bracketSpacing', 106 | def(json.bracketSpacing, true), 107 | 'Bracket Spacing', 108 | 'Print spaces between brackets in object literals.', 109 | ], 110 | [ 111 | 'checkbox', 112 | 'bracketSameLine', 113 | def(json.bracketSameLine, false), 114 | 'Bracket Line', 115 | 'Put the `>` of a multi-line HTML (HTML, JSX, Vue, Angular) element at the end of the last line instead of being alone on the next line (does not apply to self closing elements).', 116 | ], 117 | [ 118 | 'select', 119 | 'arrowParens', 120 | def(json.arrowParens, 'always'), 121 | 'Arrow Function Parentheses', 122 | 'Include parentheses around a sole arrow function parameter.', 123 | { 124 | 'Always include parens': 'always', 125 | 'Omit parens when possible': 'avoid', 126 | }, 127 | ], 128 | [ 129 | 'select', 130 | 'proseWrap', 131 | def(json.proseWrap, 'preserve'), 132 | 'Prose Wrap', 133 | 'To have Prettier wrap prose to the print width, change this option to "always". If you want Prettier to force all prose blocks to be on a single line and rely on editor/viewer soft wrapping instead, you can use "never".', 134 | { 135 | 'Wrap prose if it exceeds the print width': 'always', 136 | 'Un-wrap each block of prose into one line': 'never', 137 | 'Do nothing, leave prose as-is': 'preserve', 138 | }, 139 | ], 140 | [ 141 | 'select', 142 | 'htmlWhitespaceSensitivity', 143 | def(json.htmlWhitespaceSensitivity, 'css'), 144 | 'HTML Whitespace Sensitivity', 145 | 'Specify the global whitespace sensitivity for HTML, Vue, Angular, and Handlebars. See [whitespace-sensitive formatting](https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting) for more info.', 146 | { 147 | 'Respect the default value of CSS display property': 'css', 148 | 'Whitespace (or the lack of it) around all tags is considered significant': 149 | 'strict', 150 | 'Whitespace (or the lack of it) around all tags is considered insignificant': 151 | 'ignore', 152 | }, 153 | ], 154 | [ 155 | 'checkbox', 156 | 'vueIndentScriptAndStyle', 157 | def(json.vueIndentScriptAndStyle, false), 158 | 'Vue files script and style tags indentation', 159 | 'Whether or not to indent the code inside ` 190 | 191 | 192 | ` 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import splitPath from 'licia/splitPath' 2 | import * as vscode from 'vscode' 3 | import endWith from 'licia/endWith' 4 | import path from 'path' 5 | 6 | export function setContext(name: string, value: any) { 7 | vscode.commands.executeCommand('setContext', name, value) 8 | } 9 | 10 | let document: vscode.TextDocument | undefined 11 | export function setDocument(doc: vscode.TextDocument) { 12 | document = doc 13 | } 14 | 15 | export function getDocument() { 16 | return document 17 | } 18 | 19 | let textEditor: vscode.TextEditor | undefined 20 | export function setTextEditor(editor: vscode.TextEditor) { 21 | textEditor = editor 22 | } 23 | 24 | export function getTextEditor() { 25 | return textEditor 26 | } 27 | 28 | export function reopenWith(editor: string) { 29 | let uri: vscode.Uri | undefined 30 | try { 31 | const activeTabInput = vscode.window.tabGroups.activeTabGroup.activeTab 32 | ?.input as { [key: string]: any; uri: vscode.Uri | undefined } 33 | uri = activeTabInput.uri 34 | } catch (e) { 35 | const document = getDocument() 36 | if (document) { 37 | uri = document.uri 38 | } 39 | } 40 | if (uri) { 41 | vscode.commands.executeCommand('vscode.openWith', uri, editor) 42 | } 43 | } 44 | 45 | export async function getFileHandler(document: vscode.TextDocument) { 46 | const fileName = document.fileName 47 | const { name, dir } = splitPath(fileName) 48 | 49 | switch (name) { 50 | case 'package.json': 51 | case '.npmrc': 52 | return 'npm' 53 | case '.prettierrc': 54 | case '.prettierrc.json': 55 | return 'prettier' 56 | case 'tsconfig.json': 57 | case 'cypress.json': 58 | case '.eslintrc': 59 | case '.eslintrc.json': 60 | case 'lerna.json': 61 | case '.nycrc': 62 | case '.nycrc.json': 63 | case '.babelrc': 64 | case '.babelrc.json': 65 | return 'schema' 66 | } 67 | 68 | return '' 69 | } 70 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "outDir": "out", 6 | "lib": ["ES2020", "DOM"], 7 | "sourceMap": true, 8 | "esModuleInterop": true, 9 | "rootDirs": ["src", "media"], 10 | "strict": true /* enable all strict type-checking options */ 11 | /* Additional Checks */ 12 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 13 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 14 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 15 | } 16 | } 17 | --------------------------------------------------------------------------------