├── .eslintignore ├── .gitignore ├── assets ├── json.gif ├── zain.png ├── json-z.png ├── function1.png ├── function2.png └── function3.png ├── docs ├── DEVELOPMENT.md └── CHANGELOG.md ├── resources ├── json-128.png ├── json-500.png ├── light │ ├── document.svg │ ├── edit.svg │ ├── folder.svg │ ├── boolean.svg │ ├── dependency.svg │ ├── refresh.svg │ ├── number.svg │ └── string.svg └── dark │ ├── edit.svg │ ├── document.svg │ ├── folder.svg │ ├── boolean.svg │ ├── dependency.svg │ ├── refresh.svg │ ├── number.svg │ └── string.svg ├── .vscodeignore ├── tsconfig.json ├── .vscode ├── extensions.json ├── tasks.json ├── settings.json └── launch.json ├── .eslintrc.js ├── src ├── extension.ts └── json │ └── jsonTree.ts ├── LICENSE.md ├── .github └── workflows │ └── production.yml ├── README.md └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | vscode.proposed.d.ts -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | 4 | *.vsix 5 | -------------------------------------------------------------------------------- /assets/json.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/assets/json.gif -------------------------------------------------------------------------------- /assets/zain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/assets/zain.png -------------------------------------------------------------------------------- /docs/DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | https://marketplace.visualstudio.com/manage/publishers/zainchen 2 | -------------------------------------------------------------------------------- /assets/json-z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/assets/json-z.png -------------------------------------------------------------------------------- /assets/function1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/assets/function1.png -------------------------------------------------------------------------------- /assets/function2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/assets/function2.png -------------------------------------------------------------------------------- /assets/function3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/assets/function3.png -------------------------------------------------------------------------------- /resources/json-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/resources/json-128.png -------------------------------------------------------------------------------- /resources/json-500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZainChen/vscode-json/main/resources/json-500.png -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | assets 10 | docs 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2020", 5 | "lib": ["es2020"], 6 | "outDir": "out", 7 | "sourceMap": true, 8 | "rootDir": "src", 9 | "strict": true 10 | }, 11 | "exclude": [ 12 | "node_modules", 13 | ".vscode-test" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": [ 7 | "dbaeumer.vscode-eslint" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /resources/light/document.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/dark/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.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 | } -------------------------------------------------------------------------------- /.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 | "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version 10 | "typescript.tsc.autoDetect": "off", 11 | "editor.insertSpaces": false, 12 | "cSpell.words": [ 13 | "autorefresh" 14 | ], 15 | } 16 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /**@type {import('eslint').Linter.Config} */ 2 | // eslint-disable-next-line no-undef 3 | module.exports = { 4 | root: true, 5 | parser: '@typescript-eslint/parser', 6 | plugins: [ 7 | '@typescript-eslint', 8 | ], 9 | extends: [ 10 | 'eslint:recommended', 11 | 'plugin:@typescript-eslint/recommended', 12 | ], 13 | rules: { 14 | 'semi': [2, "always"], 15 | '@typescript-eslint/no-unused-vars': 0, 16 | '@typescript-eslint/no-explicit-any': 0, 17 | '@typescript-eslint/explicit-module-boundary-types': 0, 18 | '@typescript-eslint/no-non-null-assertion': 0, 19 | '@typescript-eslint/no-namespace': 0, 20 | 'no-inner-declarations': 0, 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /resources/dark/document.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/dark/folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | import { JsonTreeProvider } from './json/jsonTree'; 5 | 6 | export function activate(context: vscode.ExtensionContext) { 7 | const jsonTreeProvider = new JsonTreeProvider(context); 8 | vscode.window.createTreeView('jsonTree', { treeDataProvider: jsonTreeProvider, showCollapseAll: true }); 9 | vscode.commands.registerCommand('jsonTree.refresh', () => jsonTreeProvider.refresh()); 10 | vscode.commands.registerCommand('jsonTree.refreshNode', offset => jsonTreeProvider.refresh(offset)); 11 | vscode.commands.registerCommand('jsonTree.renameNode', offset => jsonTreeProvider.rename(offset)); 12 | vscode.commands.registerCommand('extension.openJsonSelection', range => jsonTreeProvider.select(range)); 13 | } 14 | -------------------------------------------------------------------------------- /resources/dark/boolean.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/dark/dependency.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/boolean.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/dependency.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/dark/refresh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/refresh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": [ 11 | "--extensionDevelopmentPath=${workspaceRoot}", 12 | "--enable-proposed-api", 13 | "vscode-samples.custom-view-samples" 14 | ], 15 | "sourceMaps": true, 16 | "outFiles": [ 17 | "${workspaceRoot}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "npm: watch" 20 | }, 21 | { 22 | "type": "node", 23 | "request": "attach", 24 | "name": "Attach to Extension Host", 25 | "port": 5870, 26 | "restart": true, 27 | "outFiles": [ 28 | "${workspaceRoot}/out" 29 | ] 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Json for Visual Studio Code 2 | 3 | ## Version 2.0.2 November 08, 2020 4 | 5 | ### New Features 6 | 7 | - / 8 | 9 | ### Bug Fixes 10 | 11 | - Fix repository url and readme. 12 | 13 | --- 14 | 15 | ## Version 2.0.1 September 05, 2020 16 | 17 | ### New Features 18 | 19 | - / 20 | 21 | ### Bug Fixes 22 | 23 | - Fix node.children is not iterable. 24 | 25 | --- 26 | 27 | ## Version 2.0.0 September 04, 2020 28 | 29 | ### New Features 30 | 31 | - Add content count. 32 | - Use TypeScript. 33 | 34 | ### Bug Fixes 35 | 36 | - / 37 | 38 | --- 39 | 40 | ## Version 1.0.4 January 20, 2020 41 | 42 | ### New Features 43 | 44 | - / 45 | 46 | ### Bug Fixes 47 | 48 | - Fix sidebar icons. 49 | 50 | --- 51 | 52 | ## Version 1.0.1 February 28, 2019 53 | 54 | ### New Features 55 | 56 | - Add menu node one-click folding function. 57 | 58 | ### Bug Fixes 59 | 60 | - Solve the problem that vscode-json can't display. 61 | 62 | --- 63 | 64 | ## Version 1.0.0 February 28, 2019 65 | 66 | ### New Features 67 | 68 | - Add json view 69 | 70 | ### Bug Fixes 71 | 72 | - null 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ZainChen 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 | -------------------------------------------------------------------------------- /.github/workflows/production.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub - Prod Stage 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | push: 8 | branches: 9 | - production 10 | 11 | jobs: 12 | build: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | matrix: 17 | os: [macos-latest] 18 | 19 | steps: 20 | - name: Checkout git repo 21 | uses: actions/checkout@v4 22 | 23 | - name: Setup Node.js 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: '20' 27 | 28 | - name: Install dependencies 29 | run: npm install 30 | 31 | - name: Build 32 | run: npm run build 33 | 34 | - name: Package 35 | run: npm run package 36 | 37 | - name: Get version from package.json 38 | id: package 39 | run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT 40 | 41 | - name: Release 42 | uses: softprops/action-gh-release@v2 43 | with: 44 | tag_name: vscode-json-v${{ steps.package.outputs.version }} 45 | files: json-${{ steps.package.outputs.version }}.vsix 46 | -------------------------------------------------------------------------------- /resources/dark/number.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/number.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/dark/string.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/light/string.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Json for Visual Studio Code 2 | [![VisualStudioMarketplace](https://img.shields.io/badge/VisualStudioMarketplace-v2.0.2-orange.svg)](https://marketplace.visualstudio.com/items?itemName=ZainChen.json) 3 | [![Downloads](https://img.shields.io/badge/Downloads-305k%2B-brightgreen.svg)](https://marketplace.visualstudio.com/items?itemName=ZainChen.json) 4 | [![UpdateTime](https://img.shields.io/badge/UpdateTime-2020%2F11%2F08%2013%3A04%3A30-blue.svg)](https://marketplace.visualstudio.com/items?itemName=ZainChen.json) 5 | 6 | This extension adds json support for Visual Studio Code. 7 | 8 | # About 9 | 10 | GitHub: https://github.com/ZainChen/vscode-json 11 | 12 |

vscode-json v2.0.2

13 |

omi

14 |

vscode-json

15 | 16 | # Function 17 | 18 | - Json analysis 19 | - Content count 20 | 21 |

Json

22 | 23 | ## Json tree 24 | 25 | Jump to any position. 26 | 27 |

Json

28 | 29 | ## Settings 30 | 31 | Set auto refresh. 32 | 33 |

Json

34 | 35 | ## Modify 36 | 37 | Right click, modify name. 38 | 39 |

Json

40 | 41 | # Resources 42 | 43 | vscode-extension-samples: https://github.com/microsoft/vscode-extension-samples 44 | 45 | # Gratitude 46 | 47 | VS Code Team 48 | 49 | # Extension Developer 50 | 51 | 52 | 53 | 54 | 59 | 64 | 69 | 70 | 71 | 76 | 81 | 86 | 87 | 88 |
55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 |
72 | 73 | 74 | 75 | 77 | 78 | 79 | 80 | 82 | 83 | 84 | 85 |
89 | 90 | ## License 91 | 92 | Copyright (c) Microsoft Corporation and ZainChen. All rights reserved. 93 | 94 | Licensed under the [MIT](https://github.com/ZainChen/vscode-json/blob/master/LICENSE.md) License. 95 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json", 3 | "displayName": "json", 4 | "description": "Json for Visual Studio Code", 5 | "version": "2.1.0", 6 | "publisher": "ZainChen", 7 | "author": "ZainChen ", 8 | "homepage": "https://github.com/ZainChen/vscode-json#readme", 9 | "bugs": { 10 | "url": "https://github.com/ZainChen/vscode-json/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/ZainChen/vscode-json" 15 | }, 16 | "license": "MIT", 17 | "icon": "resources/json-128.png", 18 | "main": "./out/extension.js", 19 | "scripts": { 20 | "watch": "tsc -watch -p ./", 21 | "build": "tsc -p ./", 22 | "package": "vsce package", 23 | "lint": "eslint \"src/**/*.ts\"" 24 | }, 25 | "dependencies": { 26 | "jsonc-parser": "^0.4.2" 27 | }, 28 | "devDependencies": { 29 | "@types/node": "^16.18.34", 30 | "@types/vscode": "^1.73.0", 31 | "@typescript-eslint/eslint-plugin": "^6.7.0", 32 | "@typescript-eslint/parser": "^6.7.0", 33 | "@vscode/vsce": "^2.26.0", 34 | "eslint": "^8.26.0", 35 | "typescript": "^5.3.2" 36 | }, 37 | "categories": [ 38 | "Extension Packs", 39 | "Other" 40 | ], 41 | "keywords": [ 42 | "zain", 43 | "ZainChen", 44 | "银", 45 | "志银", 46 | "陈志银", 47 | "陈志振", 48 | "json", 49 | "html", 50 | "css", 51 | "javascript", 52 | "nodejs", 53 | "github", 54 | "gitlab", 55 | "git", 56 | "c", 57 | "C++", 58 | "web", 59 | "js", 60 | "npm", 61 | "python", 62 | "java", 63 | "Ruby", 64 | "webpack", 65 | "php", 66 | "mysql", 67 | "sql", 68 | "apache", 69 | "nginx", 70 | "iis", 71 | "wordpress", 72 | "hexo", 73 | "tencent", 74 | "linux", 75 | "window", 76 | "mac", 77 | "vs", 78 | "google", 79 | "markdown", 80 | "xml", 81 | "run", 82 | "commands", 83 | "view", 84 | "diff", 85 | "tree", 86 | "compare" 87 | ], 88 | "engines": { 89 | "vscode": "^1.74.0" 90 | }, 91 | "activationEvents": [ 92 | "onLanguage:json", 93 | "onLanguage:jsonc" 94 | ], 95 | "contributes": { 96 | "viewsContainers": { 97 | "activitybar": [ 98 | { 99 | "id": "json-views", 100 | "title": "json", 101 | "icon": "./resources/json-500.png" 102 | } 103 | ] 104 | }, 105 | "views": { 106 | "json-views": [ 107 | { 108 | "id": "jsonTree", 109 | "name": "Please open the json file.(ZainChen)" 110 | } 111 | ] 112 | }, 113 | "menus": { 114 | "view/title": [ 115 | { 116 | "command": "jsonTree.refresh", 117 | "when": "view == jsonTree", 118 | "group": "navigation" 119 | } 120 | ], 121 | "view/item/context": [ 122 | { 123 | "command": "jsonTree.renameNode", 124 | "when": "view == jsonTree" 125 | }, 126 | { 127 | "command": "jsonTree.refreshNode", 128 | "when": "view == jsonTree", 129 | "group": "inline" 130 | } 131 | ] 132 | }, 133 | "commands": [ 134 | { 135 | "command": "jsonTree.refresh", 136 | "title": "Refresh", 137 | "icon": { 138 | "light": "./resources/light/refresh.svg", 139 | "dark": "./resources/dark/refresh.svg" 140 | } 141 | }, 142 | { 143 | "command": "jsonTree.refreshNode", 144 | "title": "Refresh", 145 | "icon": { 146 | "light": "./resources/light/refresh.svg", 147 | "dark": "./resources/dark/refresh.svg" 148 | } 149 | }, 150 | { 151 | "command": "jsonTree.renameNode", 152 | "title": "Rename" 153 | } 154 | ], 155 | "languages": [ 156 | { 157 | "id": "json", 158 | "extensions": [ 159 | ".json" 160 | ], 161 | "aliases": [ 162 | "Json" 163 | ] 164 | } 165 | ], 166 | "configuration": [ 167 | { 168 | "type": "object", 169 | "title": "JSON-zain", 170 | "properties": { 171 | "JSON-zain.author.ZainChen": { 172 | "type": "string", 173 | "default": "Welcome to vscode-json.", 174 | "description": "Json for Visual Studio Code" 175 | }, 176 | "JSON-zain.json.autorefresh": { 177 | "type": "boolean", 178 | "default": false, 179 | "description": "Whether to update the menu in real time based on the contents of the json file!" 180 | } 181 | } 182 | } 183 | ] 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/json/jsonTree.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as json from 'jsonc-parser'; 3 | import * as path from 'path'; 4 | 5 | export class JsonTreeProvider implements vscode.TreeDataProvider { 6 | 7 | private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); 8 | readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; 9 | 10 | private tree: json.Node | undefined; 11 | private text = ''; 12 | private editor: vscode.TextEditor | undefined; 13 | private autoRefresh = true; 14 | 15 | constructor(private context: vscode.ExtensionContext) { 16 | vscode.window.onDidChangeActiveTextEditor(() => this.onActiveEditorChanged()); 17 | vscode.workspace.onDidChangeTextDocument(e => this.onDocumentChanged(e)); 18 | this.parseTree(); 19 | this.autoRefresh = vscode.workspace.getConfiguration('JSON-zain.json').get('autorefresh', false); 20 | vscode.workspace.onDidChangeConfiguration(() => { 21 | this.autoRefresh = vscode.workspace.getConfiguration('JSON-zain.json').get('autorefresh', false); 22 | }); 23 | this.onActiveEditorChanged(); 24 | } 25 | 26 | refresh(offset?: number): void { 27 | this.parseTree(); 28 | if (offset) { 29 | this._onDidChangeTreeData.fire(offset); 30 | } else { 31 | this._onDidChangeTreeData.fire(undefined); 32 | } 33 | } 34 | 35 | rename(offset: number): void { 36 | vscode.window.showInputBox({ placeHolder: 'Enter the new label' }) 37 | .then(value => { 38 | const editor = this.editor; 39 | const tree = this.tree; 40 | if (value !== null && value !== undefined && editor && tree) { 41 | editor.edit(editBuilder => { 42 | const path = json.getLocation(this.text, offset).path; 43 | let propertyNode: json.Node | undefined = json.findNodeAtLocation(tree, path); 44 | if (propertyNode.parent?.type !== 'array') { 45 | propertyNode = propertyNode.parent?.children ? propertyNode.parent.children[0] : undefined; 46 | } 47 | if (propertyNode) { 48 | const range = new vscode.Range(editor.document.positionAt(propertyNode.offset), editor.document.positionAt(propertyNode.offset + propertyNode.length)); 49 | editBuilder.replace(range, `"${value}"`); 50 | setTimeout(() => { 51 | this.parseTree(); 52 | this.refresh(offset); 53 | }, 100); 54 | } 55 | }); 56 | } 57 | }); 58 | } 59 | 60 | private onActiveEditorChanged(): void { 61 | if (vscode.window.activeTextEditor) { 62 | if (vscode.window.activeTextEditor.document.uri.scheme === 'file') { 63 | const enabled = vscode.window.activeTextEditor.document.languageId === 'json' || vscode.window.activeTextEditor.document.languageId === 'jsonc'; 64 | vscode.commands.executeCommand('setContext', 'jsonTreeEnabled', enabled); 65 | // if (enabled) { 66 | // this.refresh(); 67 | // } 68 | } 69 | } else { 70 | vscode.commands.executeCommand('setContext', 'jsonTreeEnabled', false); 71 | } 72 | // 切换文件,刷新 73 | this.refresh(); 74 | } 75 | 76 | private onDocumentChanged(changeEvent: vscode.TextDocumentChangeEvent): void { 77 | if (this.tree && this.autoRefresh && changeEvent.document.uri.toString() === this.editor?.document.uri.toString()) { 78 | for (const change of changeEvent.contentChanges) { 79 | const path = json.getLocation(this.text, this.editor.document.offsetAt(change.range.start)).path; 80 | path.pop(); 81 | const node = path.length ? json.findNodeAtLocation(this.tree, path) : void 0; 82 | this.parseTree(); 83 | this._onDidChangeTreeData.fire(node ? node.offset : void 0); 84 | } 85 | } 86 | } 87 | 88 | private parseTree(): void { 89 | this.text = ''; 90 | this.tree = undefined; 91 | this.editor = vscode.window.activeTextEditor; 92 | if (this.editor && this.editor.document) { 93 | this.text = this.editor.document.getText(); 94 | this.tree = json.parseTree(this.text); 95 | } 96 | } 97 | 98 | getChildren(offset?: number): Thenable { 99 | if (offset && this.tree) { 100 | const path = json.getLocation(this.text, offset).path; 101 | const node = json.findNodeAtLocation(this.tree, path); 102 | return Promise.resolve(this.getChildrenOffsets(node)); 103 | } else { 104 | return Promise.resolve(this.tree ? this.getChildrenOffsets(this.tree) : []); 105 | } 106 | } 107 | 108 | private getChildrenOffsets(node: json.Node): number[] { 109 | const offsets: number[] = []; 110 | if (node.children && this.tree) { 111 | for (const child of node.children) { 112 | const childPath = json.getLocation(this.text, child.offset).path; 113 | const childNode = json.findNodeAtLocation(this.tree, childPath); 114 | if (childNode) { 115 | offsets.push(childNode.offset); 116 | } 117 | } 118 | } 119 | return offsets; 120 | } 121 | 122 | getTreeItem(offset: number): vscode.TreeItem { 123 | if (!this.tree) { 124 | throw new Error('Invalid tree'); 125 | } 126 | if (!this.editor) { 127 | throw new Error('Invalid editor'); 128 | } 129 | 130 | const path = json.getLocation(this.text, offset).path; 131 | const valueNode = json.findNodeAtLocation(this.tree, path); 132 | if (valueNode) { 133 | const hasChildren = valueNode.type === 'object' || valueNode.type === 'array'; 134 | const treeItem: vscode.TreeItem = new vscode.TreeItem(this.getLabel(valueNode), hasChildren ? valueNode.type === 'object' ? vscode.TreeItemCollapsibleState.Expanded : vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None); 135 | treeItem.command = { 136 | command: 'extension.openJsonSelection', 137 | title: '', 138 | arguments: [new vscode.Range(this.editor.document.positionAt(valueNode.offset), this.editor.document.positionAt(valueNode.offset + valueNode.length))] 139 | }; 140 | treeItem.iconPath = this.getIcon(valueNode); 141 | treeItem.contextValue = valueNode.type; 142 | return treeItem; 143 | } 144 | throw (new Error(`Could not find json node at ${path}`)); 145 | } 146 | 147 | select(range: vscode.Range) { 148 | if (this.editor) { 149 | this.editor.selection = new vscode.Selection(range.start, range.end); 150 | // 编辑窗跳转到指定范围 151 | this.editor.revealRange(range, vscode.TextEditorRevealType.InCenter); 152 | } 153 | } 154 | 155 | private getIcon(node: json.Node): any { 156 | const nodeType = node.type; 157 | if (nodeType === 'boolean') { 158 | return { 159 | light: this.context.asAbsolutePath(path.join('resources', 'light', 'boolean.svg')), 160 | dark: this.context.asAbsolutePath(path.join('resources', 'dark', 'boolean.svg')) 161 | }; 162 | } 163 | if (nodeType === 'string') { 164 | return { 165 | light: this.context.asAbsolutePath(path.join('resources', 'light', 'string.svg')), 166 | dark: this.context.asAbsolutePath(path.join('resources', 'dark', 'string.svg')) 167 | }; 168 | } 169 | if (nodeType === 'number') { 170 | return { 171 | light: this.context.asAbsolutePath(path.join('resources', 'light', 'number.svg')), 172 | dark: this.context.asAbsolutePath(path.join('resources', 'dark', 'number.svg')) 173 | }; 174 | } 175 | return null; 176 | } 177 | 178 | private getLabel(node: json.Node): string { 179 | if (node.parent?.type === 'array') { 180 | const prefix = node.parent.children?.indexOf(node).toString(); 181 | if (node.type === 'object') { 182 | return prefix + ': { '+ this.getNodeChildrenCount(node) +' }'; 183 | } 184 | if (node.type === 'array') { 185 | return prefix + ': [ '+ this.getNodeChildrenCount(node) +' ]'; 186 | } 187 | return prefix + ':' + node.value.toString(); 188 | } 189 | else { 190 | const property = node.parent?.children ? node.parent.children[0].value.toString() : ''; 191 | if (node.type === 'array' || node.type === 'object') { 192 | if (node.type === 'object') { 193 | return '{ '+ this.getNodeChildrenCount(node) +' } ' + property; 194 | } 195 | if (node.type === 'array') { 196 | return '[ '+ this.getNodeChildrenCount(node) +' ] ' + property; 197 | } 198 | } 199 | const value = this.editor?.document.getText(new vscode.Range(this.editor.document.positionAt(node.offset), this.editor.document.positionAt(node.offset + node.length))); 200 | return `${property}: ${value}`; 201 | } 202 | } 203 | 204 | private getNodeChildrenCount(node: json.Node): string { 205 | let count = ''; 206 | if (node && node.children) { 207 | count = node.children.length + ''; 208 | } 209 | return count; 210 | } 211 | } --------------------------------------------------------------------------------