├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .prettierrc ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .yarnrc ├── CHANGELOG.MD ├── CONTRIBUTING.md ├── Jenkinsfile ├── LICENSE ├── README.md ├── SECURITY.md ├── documentation └── vscode-diagram.mp4 ├── example └── workflow │ ├── extension │ ├── .eslintrc.js │ ├── .vscodeignore │ ├── LICENSE │ ├── package.json │ ├── src │ │ ├── workflow-editor-provider.ts │ │ └── workflow-extension.ts │ ├── tsconfig.json │ ├── webpack.config.js │ └── webpack.prod.js │ ├── web-extension │ ├── .eslintrc.js │ ├── .vscodeignore │ ├── LICENSE │ ├── package.json │ ├── src │ │ ├── workflow-editor-provider.ts │ │ ├── workflow-extension.ts │ │ └── workflow-server.ts │ ├── tsconfig.json │ ├── webpack.config.js │ └── webpack.prod.js │ ├── webview │ ├── LICENSE │ ├── package.json │ ├── src │ │ ├── app.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── webpack.config.js │ └── webpack.prod.js │ └── workspace │ ├── example1.md │ └── example1.wf ├── lerna.json ├── logs └── .gitkeep ├── package.json ├── packages ├── vscode-integration-webview │ ├── LICENSE │ ├── README.md │ ├── css │ │ ├── command-palette.css │ │ ├── decoration.css │ │ ├── diagram.css │ │ ├── features.css │ │ ├── glsp-vscode.css │ │ └── tool-palette.css │ ├── package.json │ ├── src │ │ ├── default-modules.ts │ │ ├── diagram-identifier.ts │ │ ├── features │ │ │ ├── copyPaste │ │ │ │ ├── copy-paste-module.ts │ │ │ │ └── copy-paste-startup.ts │ │ │ ├── default │ │ │ │ ├── default-module.ts │ │ │ │ ├── extension-action-handler.ts │ │ │ │ └── vscode-glsp-modelsource.ts │ │ │ ├── export │ │ │ │ └── export-module.ts │ │ │ ├── navigation │ │ │ │ └── navigation-module.ts │ │ │ └── notification │ │ │ │ └── notification-module.ts │ │ ├── glsp-diagram-widget.ts │ │ ├── glsp-starter.ts │ │ ├── index.ts │ │ └── webview-glsp-client.ts │ └── tsconfig.json └── vscode-integration │ ├── .eslintrc.js │ ├── LICENSE │ ├── README.md │ ├── browser.d.ts │ ├── browser.js │ ├── node.d.ts │ ├── node.js │ ├── package.json │ ├── src │ ├── browser │ │ ├── index.ts │ │ ├── quickstart-components │ │ │ ├── browser-glsp-vscode-server.ts │ │ │ └── websocket-glsp-vscode-server.ts │ │ └── re-export.ts │ ├── common │ │ ├── client-actions.ts │ │ ├── glsp-vscode-connector.ts │ │ ├── index.ts │ │ ├── quickstart-components │ │ │ ├── base-glsp-vscode-server.ts │ │ │ ├── configuration-util.ts │ │ │ ├── glsp-editor-provider.ts │ │ │ ├── index.ts │ │ │ └── webview-endpoint.ts │ │ ├── re-export.ts │ │ └── types.ts │ └── node │ │ ├── index.ts │ │ ├── quickstart-components │ │ ├── glsp-socket-server-launcher.ts │ │ ├── node-glsp-vscode-server.ts │ │ └── socket-glsp-vscode-server.ts │ │ └── re-export.ts │ └── tsconfig.json ├── tsconfig.eslint.json ├── tsconfig.json └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | root: true, 4 | extends: '@eclipse-glsp', 5 | ignorePatterns: ['**/{node_modules,lib}', '**/.eslintrc.js', '**/webpack.config.js'], 6 | 7 | parserOptions: { 8 | tsconfigRootDir: __dirname, 9 | project: 'tsconfig.eslint.json' 10 | }, 11 | rules: { 12 | 'no-restricted-imports': [ 13 | 'warn', 14 | { 15 | name: 'sprotty', 16 | message: "The sprotty default exports are customized and reexported by GLSP. Please use '@eclipse-glsp/client' instead" 17 | }, 18 | { 19 | name: 'sprotty-protocol', 20 | message: 21 | "The sprotty-protocol default exports are customized and reexported by GLSP. Please use '@eclipse-glsp/protocol' or '@eclipse-glsp/client' instead" 22 | } 23 | ] 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Question 4 | url: https://github.com/eclipse-glsp/glsp/discussions 5 | about: Please ask questions on the Eclipse GLSP discussions page. 6 | - name: Create issue in GLSP umbrella project 7 | url: https://github.com/eclipse-glsp/glsp/issues/new/choose 8 | about: Please create new issues in the GLSP umbrella project, as we are tracking the issues for all components of GLSP there. 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | #### What it does 13 | 14 | 15 | 16 | #### How to test 17 | 18 | 19 | 20 | #### Follow-ups 21 | 22 | 23 | 24 | #### Changelog 25 | 26 | 27 | 28 | - [ ] This PR should be mentioned in the changelog 29 | - [ ] This PR introduces a breaking change (if yes, provide more details below for the changelog and the migration guide) 30 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: 'CodeQL' 13 | 14 | on: 15 | push: 16 | branches: [master] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [master] 20 | schedule: 21 | - cron: '27 3 * * 0' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ['javascript'] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v2 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v2 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v2 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .browser_modules 3 | lib 4 | *.log 5 | *.jar 6 | dist 7 | tsconfig.tsbuildinfo 8 | eslint.xml 9 | *.vsix 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | "@eclipse-glsp/prettier-config" 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | // List of extensions which should be recommended for users of this workspace. 5 | "recommendations": [ 6 | "dbaeumer.vscode-eslint", 7 | "esbenp.prettier-vscode", 8 | "DavidAnson.vscode-markdownlint" 9 | ], 10 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 11 | "unwantedRecommendations": [] 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Workflow GLSP Example Extension", 9 | "type": "extensionHost", 10 | "request": "launch", 11 | "runtimeExecutable": "${execPath}", 12 | "args": [ 13 | "${workspaceFolder}/example/workflow/workspace", 14 | "--extensionDevelopmentPath=${workspaceFolder}/example/workflow/extension" 15 | ], 16 | "outFiles": [ 17 | "${workspaceRoot}/example/workflow/extension/dist/workflow-extension.js", 18 | "${workspaceRoot}/example/workflow/extension/lib/**/*.js", 19 | "${workspaceRoot}/packages/vscode-integration/lib/**/*.js", 20 | "${workspaceRoot}/node_modules/@eclipse-glsp/*/lib/**/*.js", 21 | "${workspaceRoot}/node_modules/vscode-messenger/*/lib/**/*.js", 22 | "${workspaceRoot}/node_modules/vscode-messenger-common/*/lib/**/*.js" 23 | ], 24 | "sourceMaps": true, 25 | "sourceMapPathOverrides": { 26 | "webpack://workflow-vscode-example/(.+)": "${workspaceFolder}/example/workflow/extension/$1" 27 | }, 28 | "env": { 29 | "GLSP_LOG_DIR": "${workspaceFolder}/logs" 30 | } 31 | }, 32 | { 33 | "name": "Workflow GLSP Example Extension (External GLSP Server)", 34 | "type": "extensionHost", 35 | "request": "launch", 36 | "runtimeExecutable": "${execPath}", 37 | "args": [ 38 | "${workspaceFolder}/example/workflow/workspace", 39 | "--extensionDevelopmentPath=${workspaceFolder}/example/workflow/extension" 40 | ], 41 | "outFiles": [ 42 | "${workspaceRoot}/example/workflow/extension/dist/workflow-extension.js", 43 | "${workspaceRoot}/example/workflow/extension/lib/**/*.js", 44 | "${workspaceRoot}/packages/vscode-integration/lib/**/*.js", 45 | "${workspaceRoot}/node_modules/@eclipse-glsp/*/lib/**/*.js" 46 | ], 47 | "sourceMaps": true, 48 | "sourceMapPathOverrides": { 49 | "webpack://workflow-vscode-example/(.+)": "${workspaceFolder}/example/workflow/extension/$1" 50 | }, 51 | "env": { 52 | "GLSP_SERVER_DEBUG": "true", 53 | "GLSP_SERVER_PORT": "5007" 54 | } 55 | }, 56 | { 57 | "name": "Workflow GLSP Example Extension (Integrated Node GLSP Server)", 58 | "type": "extensionHost", 59 | "request": "launch", 60 | "runtimeExecutable": "${execPath}", 61 | "args": [ 62 | "${workspaceFolder}/example/workflow/workspace", 63 | "--extensionDevelopmentPath=${workspaceFolder}/example/workflow/extension" 64 | ], 65 | "outFiles": [ 66 | "${workspaceRoot}/example/workflow/extension/dist/workflow-extension.js", 67 | "${workspaceRoot}/example/workflow/extension/lib/**/*.js", 68 | "${workspaceRoot}/packages/vscode-integration/lib/**/*.js", 69 | "${workspaceRoot}/node_modules/@eclipse-glsp/*/lib/**/*.js" 70 | ], 71 | "sourceMaps": true, 72 | "sourceMapPathOverrides": { 73 | "webpack://workflow-vscode-example/(.+)": "${workspaceFolder}/example/workflow/extension/$1" 74 | }, 75 | "env": { 76 | "GLSP_INTEGRATED_SERVER": "true" 77 | } 78 | }, 79 | { 80 | "name": "Workflow GLSP Example Extension (WebSocket)", 81 | "type": "extensionHost", 82 | "request": "launch", 83 | "runtimeExecutable": "${execPath}", 84 | "args": [ 85 | "${workspaceFolder}/example/workflow/workspace", 86 | "--extensionDevelopmentPath=${workspaceFolder}/example/workflow/extension" 87 | ], 88 | "outFiles": [ 89 | "${workspaceRoot}/example/workflow/extension/dist/workflow-extension.js", 90 | "${workspaceRoot}/example/workflow/extension/lib/**/*.js", 91 | "${workspaceRoot}/packages/vscode-integration/lib/**/*.js", 92 | "${workspaceRoot}/node_modules/@eclipse-glsp/*/lib/**/*.js" 93 | ], 94 | "sourceMaps": true, 95 | "sourceMapPathOverrides": { 96 | "webpack://workflow-vscode-example/(.+)": "${workspaceFolder}/example/workflow/extension/$1" 97 | }, 98 | "env": { 99 | "GLSP_LOG_DIR": "${workspaceFolder}/logs", 100 | "GLSP_WEBSOCKET_PATH": "workflow" 101 | } 102 | }, 103 | { 104 | "name": "Workflow GLSP Example Extension (External WebSocket GLSP Server)", 105 | "type": "extensionHost", 106 | "request": "launch", 107 | "runtimeExecutable": "${execPath}", 108 | "args": [ 109 | "${workspaceFolder}/example/workflow/workspace", 110 | "--extensionDevelopmentPath=${workspaceFolder}/example/workflow/extension" 111 | ], 112 | "outFiles": [ 113 | "${workspaceRoot}/example/workflow/extension/dist/workflow-extension.js", 114 | "${workspaceRoot}/example/workflow/extension/lib/**/*.js", 115 | "${workspaceRoot}/packages/vscode-integration/lib/**/*.js", 116 | "${workspaceRoot}/node_modules/@eclipse-glsp/*/lib/**/*.js" 117 | ], 118 | "sourceMaps": true, 119 | "sourceMapPathOverrides": { 120 | "webpack://workflow-vscode-example/(.+)": "${workspaceFolder}/example/workflow/extension/$1" 121 | }, 122 | "env": { 123 | "GLSP_LOG_DIR": "${workspaceFolder}/logs", 124 | "GLSP_SERVER_DEBUG": "true", 125 | "GLSP_SERVER_PORT": "8081", 126 | "GLSP_WEBSOCKET_PATH": "workflow" 127 | } 128 | }, 129 | { 130 | "name": "Workflow GLSP Example Web Extension", 131 | "type": "extensionHost", 132 | "request": "launch", 133 | "runtimeExecutable": "${execPath}", 134 | "args": [ 135 | "${workspaceFolder}/example/workflow/workspace", 136 | "--extensionDevelopmentPath=${workspaceFolder}/example/workflow/web-extension" 137 | ], 138 | "outFiles": [ 139 | "${workspaceFolder}/example/workflow/web-extension/dist/extension.js", 140 | "${workspaceFolder}/example/workflow/web-extension/lib/**/*.js", 141 | "${workspaceFolder}/packages/vscode-integration/lib/**/*.js", 142 | "${workspaceRoot}/node_modules/@eclipse-glsp/*/lib/**/*.js" 143 | ], 144 | "sourceMaps": true 145 | } 146 | ] 147 | } 148 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // If one would like to add/remove/modify user preferences without modifying the content of the 2 | // workspace settings file, then one would need to modify the `settings.json` under here: 3 | // - Windows: %APPDATA%\Code\User\settings.json 4 | // - Linux: $HOME/.config/Code/User/settings.json 5 | // - Mac: $HOME/Library/Application Support/Code/User/settings.json 6 | { 7 | "editor.formatOnSave": true, 8 | "editor.codeActionsOnSave": { 9 | "source.organizeImports": "explicit", 10 | "source.fixAll.eslint": "explicit" 11 | }, 12 | "eslint.validate": ["javascript", "typescript"], 13 | "search.exclude": { 14 | "**/node_modules": true, 15 | "**/lib": true 16 | }, 17 | "task.autoDetect": "off", 18 | "typescript.tsdk": "node_modules/typescript/lib", 19 | "[css]": { 20 | "editor.defaultFormatter": "esbenp.prettier-vscode" 21 | }, 22 | "[javascript]": { 23 | "editor.defaultFormatter": "esbenp.prettier-vscode" 24 | }, 25 | "[javascriptreact]": { 26 | "editor.defaultFormatter": "esbenp.prettier-vscode" 27 | }, 28 | "[json]": { 29 | "editor.defaultFormatter": "esbenp.prettier-vscode" 30 | }, 31 | "[markdown]": { 32 | "editor.defaultFormatter": "esbenp.prettier-vscode" 33 | }, 34 | "[typescript]": { 35 | "editor.defaultFormatter": "esbenp.prettier-vscode" 36 | }, 37 | "[typescriptreact]": { 38 | "editor.defaultFormatter": "esbenp.prettier-vscode" 39 | }, 40 | "[yaml]": { 41 | "editor.defaultFormatter": "esbenp.prettier-vscode" 42 | }, 43 | "markdownlint.config": { 44 | "MD007": { 45 | "indent": 4 46 | }, 47 | "MD030": { 48 | "ul_single": 3, 49 | "ul_multi": 3 50 | }, 51 | "no-inline-html": { 52 | "allowed_elements": ["details", "summary"] 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build all packages", 8 | "type": "shell", 9 | "group": { 10 | "kind": "build", 11 | "isDefault": true 12 | }, 13 | "command": "yarn", 14 | "presentation": { 15 | "reveal": "always", 16 | "panel": "new" 17 | }, 18 | "problemMatcher": [] 19 | }, 20 | { 21 | "label": "Watch all packages", 22 | "type": "shell", 23 | "group": "build", 24 | "command": "yarn watch", 25 | "presentation": { 26 | "reveal": "always", 27 | "panel": "new" 28 | }, 29 | "problemMatcher": [] 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | --ignore-engines true -------------------------------------------------------------------------------- /CHANGELOG.MD: -------------------------------------------------------------------------------- 1 | # Eclipse GLSP VSCode Integration Changelog 2 | 3 | ## 2.5.0 - active 4 | 5 | ### Changes 6 | 7 | ### Potentially Breaking Changes 8 | 9 | ## [2.4.0 - 04/04/2025](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v2.4.0) 10 | 11 | ### Changes 12 | 13 | - [diagram] Dispose pending progress reporters on diagram close [#72](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/72) 14 | - [diagram] Fix wrong CSS for `--glsp-warning-foreground` [#73](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/73) 15 | 16 | ### Potentially Breaking Changes 17 | 18 | ## [2.3.0 - 19/12/2024](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v2.3.0) 19 | 20 | ### Changes 21 | 22 | - [diagram] Update default styling to consistently use vscode theme variables [#68](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/68) 23 | - [deps] Drop support for node `16`. New minimum version is `18.x` [#69](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/69) 24 | 25 | ## [2.2.1 - 22/07/2024](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v2.2.1) 26 | 27 | ### Changes 28 | 29 | - [diagram] Fix minor styling and behavioral issues when using `GLSPProjectionView` [#62](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/62) 30 | - [diagram] Removed the context menu module from the default integration as it is currently not supported in VS Code [#63](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/63) 31 | 32 | ### Potentially Breaking Changes 33 | 34 | - [protocol] Fix a bug in the client-server action forwarding that prevented proper marking and handling of server received actions [#58](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/58)
Following classes and methods are now deprecated: 35 | - `VsCodeGLSPModelSource`: Rebinding to a custom model source is no longer necessary. Use the default `GLSPModelSource` instead. 36 | - `ExtensionAction`: The concept of marking actions as locally dispatched `ExtensionActions` is no longer necessary and usage is discouraged. 37 | - `GlspVscodeConnector.sendToActiveClient`: Use `GlspVscodeConnector.dispatchAction` instead. 38 | - `GlspVscodeConnector.setActionToClient`: Use `GlspVscodeConnector.dispatchAction` instead. 39 | 40 | ## [2.1.0 - 24/01/2024](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v2.1.0) 41 | 42 | ## [2.0.0 - 14/10/2023](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v2.0.0) 43 | 44 | ### Changes 45 | 46 | - [launch] Socket-based launch quickstart components now support auto-assigned ports [#33](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/33) 47 | - [diagram] Fix a bug where the context key for selected elements was not updated properly [#28](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/28) 48 | - [diagram] Implement support for `MessageAction` notifications [#35](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/35) 49 | - [diagram] Improve dirty state handling to also enable dirty state change evens that have not been triggered by an operation [#37](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/37) 50 | - [launch] Provide `NodeGlspVscodeServer` to enable direct server integration in the extension context without a dedicated server process [#38](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/37) 51 | - [diagram] Fixed a bug that prevented proper server-side disposal of diagram sessions [#40](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/40) 52 | - [API] Restructured packages to also provide a node-dependency free entry point for web-extensions ('@eclipse-glsp/vscode-integration/browser`) [#39](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/39) 53 | - [diagram] Add support for server progress reporting [#47](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/47) 54 | - [example] Add keybinding for triggering `ExportSvgAction`s [#41](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/41) 55 | 56 | ### Breaking Changes 57 | 58 | - [deps] Update to vscode-jsonrpc 8.0.2 & update minimum requirements for Node to >=16.11.0 [#31](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/31) 59 | - [launch] Refactor socket-based quickstart components to also support WebSocket connections [#37](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/37) 60 | - Renamed `JavaSocketServerLaunchOptions` -> `SocketServerLaunchOptions` and removed `serverType` property 61 | - Renamed `GlspServerLauncher` -> `GLSPSocketServerLauncher` 62 | - Replaced `serverPort` property of `SocketGlspVscodeServerOptions` with `connectionOptions` 63 | - Added `start()` and `onReady` to `GlspVscodeServer` interface 64 | - [API] Refactored `GlspVscodeConnector.onSelectionUpdate` event [#40](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/40) 65 | - `Event` -> `Event<{selectedElementIDs:string[], deselectedElementIDs:[]}>` 66 | - [API] Drop dependency to `sprotty-vscode-webview` [#36](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/36) 67 | - Classes,Types and symbols provide by `sprotty-vscode-webview` are no longer exported via main index 68 | - `SprottyDiagramIdentifier`->`GLSPDiagramIdentifier` 69 | - `SprottyStarter`-> `GLSPStarter` 70 | - `GLSPVscodeDiagramWidget`-> `GLSPDiagramWidget` 71 | - [API] Refactor webview communication into a `WebviewEndpoint` service and use `vscode-messenger` protocol for webview communication [#51](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/51) [#52](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/52) 72 | - Extract vscode specific diagram bindings into custom feature modules 73 | - Replace `GLSPVscodeExtensionHandler` with `HostExtensionHandler` 74 | 75 | ## [v1.0.0 - 30/06/2022](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v1.0.0) 76 | 77 | ### Changes 78 | 79 | - [example] Improved and modernized styling of the GLSP workflow example [#22](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/22) 80 | - [build] Updated Typescript to version 4.5.5 and enforced `noImplicitOverride` [#26](https://github.com/eclipse-glsp/glsp-vscode-integration/pull/26) 81 | 82 | ## [v0.9.0- 09/12/2021](https://github.com/eclipse-glsp/glsp-vscode-integration/releases/tag/v0.9.0) 83 | 84 | Inception of the Eclipse VScode integration. 85 | This project provides the glue code to integrate a GLSP diagram editor into VSCode. 86 | This is achieved by using the VSCode extension API for creating custom editors. 87 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Eclipse GLSP 2 | 3 | Thank you for your interest in the GLSP project! 4 | The following is a set of guidelines for contributing to GLSP. 5 | 6 | ## Code of Conduct 7 | 8 | This project is governed by the [Eclipse Community Code of Conduct](https://github.com/eclipse/.github/blob/master/CODE_OF_CONDUCT.md). 9 | By participating, you are expected to uphold this code. 10 | 11 | ## Communication 12 | 13 | The following communication channels are available: 14 | 15 | - [GitHub issues](https://github.com/eclipse-glsp/glsp/issues) - for bug reports, feature requests, etc. 16 | - [GitHub Discussions](https://github.com/eclipse-glsp/glsp/discussions) - for questions 17 | - [Developer mailing list](https://accounts.eclipse.org/mailing-list/glsp-dev) - for organizational issues (e.g. elections of new committers) 18 | 19 | In case you have a question, please look into the [GitHub Discussions](https://github.com/eclipse-glsp/glsp/discussions) first. 20 | If you don't find any answer there, feel free to start a new discussion or create a new [issue](https://github.com/eclipse-glsp/glsp/issues) to get help. 21 | 22 | Please create new issues only in the [GLSP umbrella project](https://github.com/eclipse-glsp/glsp), as we are tracking the issues for all components of GLSP there. 23 | 24 | ## How to Contribute 25 | 26 | In order to contribute, please first open an issue in this project, irrespectively whether this bug or feature concerns the glsp-client, glsp-server, or one of the platform integrations. 27 | This issue should describe the bug you intend to fix or the feature you would like to add. 28 | Once you have your code ready for review, please open a pull request in the respective repository. 29 | A [committer of the GLSP project](https://projects.eclipse.org/projects/ecd.glsp/who) will then review your contribution and help to get it merged. 30 | 31 | Please note that before your pull request can be accepted, you must electronically sign the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php). 32 | For more information, see the [Eclipse Foundation Project Handbook](https://www.eclipse.org/projects/handbook/#resources-commit). 33 | 34 | ### Branch names and commit messages 35 | 36 | If you are an [elected committer of the GLSP project](https://projects.eclipse.org/projects/ecd.glsp/who) please create a branch in the respective repository. 37 | Otherwise please fork and create a branch in your fork for the pull request. 38 | 39 | The branch name should be in the form `issues/{issue_number}`, e.g. `issues/123`. So please create an issue before creating a pull request. 40 | All branches with this naming schema will be deleted after they are merged. 41 | 42 | In the commit message you should also reference the corresponding issue, e.g. using `closes https://github.com/eclipse-glsp/glsp/issues/241`, thus allowing [auto close of issues](https://help.github.com/en/github/managing-your-work-on-github/closing-issues-using-keywords). 43 | Please use the absolute URL of the issue instead of just `#241`, as all issues are kept in , whereas the pull requests are opened against the respective repositories, such as . 44 | Using the absolute URL will still allow to correctly reference issues irrespectively where you open the pull request. 45 | 46 | Please make sure you read the [guide for a good commit message](https://chris.beams.io/posts/git-commit/). 47 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | def kubernetes_config = """ 2 | apiVersion: v1 3 | kind: Pod 4 | spec: 5 | containers: 6 | - name: node 7 | image: node:18 8 | tty: true 9 | resources: 10 | limits: 11 | memory: "2Gi" 12 | cpu: "1" 13 | requests: 14 | memory: "2Gi" 15 | cpu: "1" 16 | command: 17 | - cat 18 | volumeMounts: 19 | - mountPath: "/home/jenkins" 20 | name: "jenkins-home" 21 | readOnly: false 22 | - mountPath: "/.yarn" 23 | name: "yarn-global" 24 | readOnly: false 25 | volumes: 26 | - name: "jenkins-home" 27 | emptyDir: {} 28 | - name: "yarn-global" 29 | emptyDir: {} 30 | """ 31 | 32 | pipeline { 33 | agent { 34 | kubernetes { 35 | label 'glsp-agent-pod' 36 | yaml kubernetes_config 37 | } 38 | } 39 | options { 40 | buildDiscarder logRotator(numToKeepStr: '15') 41 | } 42 | 43 | environment { 44 | YARN_CACHE_FOLDER = "${env.WORKSPACE}/yarn-cache" 45 | SPAWN_WRAP_SHIM_ROOT = "${env.WORKSPACE}" 46 | EMAIL_TO= "glsp-build@eclipse.org" 47 | } 48 | 49 | stages { 50 | stage('Build') { 51 | steps { 52 | container('node') { 53 | timeout(30){ 54 | sh "yarn install" 55 | script { 56 | // Fail the step if there are uncommited changes to the yarn.lock file 57 | if (sh(returnStatus: true, script: 'git diff --name-only | grep -q "^yarn.lock"') == 0) { 58 | echo 'The yarn.lock file has uncommited changes!' 59 | error 'The yarn.lock file has uncommited changes!' 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | 67 | stage('Codechecks (ESLint)'){ 68 | steps { 69 | container('node') { 70 | timeout(30){ 71 | sh "yarn lint:ci" 72 | } 73 | } 74 | } 75 | } 76 | 77 | stage('Deploy (master only)') { 78 | when { 79 | allOf { 80 | branch 'master' 81 | expression { 82 | /* Only trigger the deployment job if the changeset contains changes in 83 | the `packages` or `example` directory */ 84 | sh(returnStatus: true, script: 'git diff --name-only HEAD^ | grep -q "^packages\\|example"') == 0 85 | } 86 | } 87 | } 88 | steps { 89 | container('node') { 90 | timeout(30) { 91 | withCredentials([string(credentialsId: 'npmjs-token', variable: 'NPM_AUTH_TOKEN')]) { 92 | sh 'printf "//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n" >> $WORKSPACE/.npmrc' 93 | } 94 | sh 'git config user.email "eclipse-glsp-bot@eclipse.org"' 95 | sh 'git config user.name "eclipse-glsp-bot"' 96 | sh 'yarn publish:next' 97 | } 98 | } 99 | } 100 | } 101 | } 102 | 103 | post { 104 | success { 105 | // Record & publish ESLint issues 106 | recordIssues enabledForFailure: true, publishAllIssues: true, aggregatingResults: true, 107 | tools: [esLint(pattern: './eslint.xml')], 108 | qualityGates: [[threshold: 1, type: 'TOTAL', unstable: true]] 109 | } 110 | failure { 111 | script { 112 | if (env.BRANCH_NAME == 'master') { 113 | echo "Build result FAILURE: Send email notification to ${EMAIL_TO}" 114 | emailext attachLog: true, 115 | from: 'glsp-bot@eclipse.org', 116 | body: 'Job: ${JOB_NAME}
Build Number: ${BUILD_NUMBER}
Build URL: ${BUILD_URL}', 117 | mimeType: 'text/html', subject: 'Build ${JOB_NAME} (#${BUILD_NUMBER}) FAILURE', to: "${EMAIL_TO}" 118 | } 119 | } 120 | } 121 | unstable { 122 | script { 123 | if (env.BRANCH_NAME == 'master') { 124 | echo "Build result UNSTABLE: Send email notification to ${EMAIL_TO}" 125 | emailext attachLog: true, 126 | from: 'glsp-bot@eclipse.org', 127 | body: 'Job: ${JOB_NAME}
Build Number: ${BUILD_NUMBER}
Build URL: ${BUILD_URL}', 128 | mimeType: 'text/html', subject: 'Build ${JOB_NAME} (#${BUILD_NUMBER}) UNSTABLE', to: "${EMAIL_TO}" 129 | } 130 | } 131 | } 132 | fixed { 133 | script { 134 | if (env.BRANCH_NAME == 'master') { 135 | echo "Build back to normal: Send email notification to ${EMAIL_TO}" 136 | emailext attachLog: false, 137 | from: 'glsp-bot@eclipse.org', 138 | body: 'Job: ${JOB_NAME}
Build Number: ${BUILD_NUMBER}
Build URL: ${BUILD_URL}', 139 | mimeType: 'text/html', subject: 'Build ${JOB_NAME} back to normal (#${BUILD_NUMBER})', to: "${EMAIL_TO}" 140 | } 141 | } 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eclipse GLSP VS Code Integration [![Build Status](https://ci.eclipse.org/glsp/job/eclipse-glsp/job/glsp-vscode-integration/job/master/badge/icon)](https://ci.eclipse.org/glsp/job/eclipse-glsp/job/glsp-vscode-integration/job/master/) 2 | 3 | This project contains the glue code necessary to diagram editors built with the [graphical language server platform (GLSP)](https://github.com/eclipse-glsp/glsp) with VS Code, as well as an example VS Code extension for the workflow diagram example for testing purposes. 4 | 5 | ## Workflow Diagram Example 6 | 7 | The workflow diagram is a consistent example provided by all GLSP components. 8 | The example implements a simple flow chart diagram editor with different types of nodes and edges (see screenshot below). 9 | The example can be used to try out different GLSP features, as well as several available integrations with IDE platforms (Theia, VS Code, Eclipse, Standalone). 10 | As the example is fully open source, you can also use it as a blueprint for a custom implementation of a GLSP diagram editor. 11 | See [our project website](https://www.eclipse.org/glsp/documentation/#workflowoverview) for an overview of the workflow example and all components implementing it. 12 | 13 | > _**Remark:**_ The workflow example is a fully dev example, as it combines a variety of integration and connectivity options to easily test the different use cases. 14 | > However, it should not be used as a blueprint for your custom implementation, for this we recommend the [GLSP project templates](https://github.com/eclipse-glsp/glsp-examples/tree/master/project-templates) in the GLSP example repository. 15 | 16 | 17 | 18 | ### How to start the Workflow Diagram example? 19 | 20 | Clone this repository and build the VS Code integration packages: 21 | 22 | ```bash 23 | yarn install 24 | ``` 25 | 26 | Now you can start the VS Code extension by opening this repository in VS Code and executing the `Workflow GLSP Example Extension` launch configuration, provided with this project. 27 | 28 | > A precompiled version of the Workflow Diagram Server will be launched automatically by the extension. 29 | > To debug or modify the server and run it separately: see the instructions below. 30 | 31 | ### How to start the Workflow Diagram example server from the sources 32 | 33 | If you want to explore or change the Workflow Diagram Server too, you can clone, build and start the Java or Node variant of the `workflow example glsp-server` from your IDE instead of using the pre-built version of the Workflow Diagram Server. 34 | Checkout the [`glsp-server`](https://github.com/eclipse-glsp/glsp-server#workflow-diagram-example) or [`glsp-server-node`](https://github.com/eclipse-glsp/glsp-server-node#workflow-diagram-example) repo for instructions on building and running the Workflow Diagram Server example. 35 | 36 | To test the VS Code extension with an external server (e.g started from your IDE) the launch configuration `Workflow GLSP Example Extension (External GLSP Server)` can be used. 37 | 38 | ### Start Workflow Diagram example in WebSocket mode 39 | 40 | The default example use case uses a socket communication from the extension to the GLSP server. 41 | To communicate with the server via WebSockets, the `Workflow GLSP Example Extension (Websocket)` launch configuration can be used. 42 | This launch config establishes a connection to the server via the endpoint `ws://localhost:8081/workflow`. 43 | To test the websocket connection with an external server the `Workflow GLSP Example Extension (External WebSocket GLSP Server)` launch config can be used 44 | 45 | ### Start Workflow Diagram example without a dedicated server process 46 | 47 | The default example use case uses a socket communication from the extension to a GLSP server process. 48 | To directly start the server in the extension context without an extra process, the `Workflow GLSP Example Extension (Integrated Node GLSP Server)` launch configuration can be used. 49 | 50 | ### Start Workflow Diagram example as a Web extension 51 | 52 | In addition to a classic node-based VS Code extension, it is also possible to start the Workflow Diagram example as a VS Code web extension. 53 | For this, the `Workflow GLSP Example Web Extension` launch configuration can be used. 54 | Per default, this extension starts the GLSP server within the extension context and uses direct communication without json-rpc. 55 | In addition, it is also possible to use an external GLSP server via WebSocket. To use this approach simply start a Workflow GLSP server that is listening on `ws://localhost:8081/workflow` (default websocket config for the Workflow example server) and then start the web extension via `Workflow GLSP Example Web Extension` launch configuration. 56 | When available (i.e. the websocket address is reachable) the extension will automatically use the external server instead of the default in-context server. 57 | 58 | > _**Remark:**_ In production, one would decide for one way of connectivity, and would not implement all the different options as we do in the workflow diagram example. 59 | > This was setup to easily show and switch between the different possibilities. 60 | 61 | ### How to package the Workflow Diagram example extension 62 | 63 | The `vsce` CLI tool can be used to package/publish a vscode extension. 64 | 65 | Before packaging it's recommended to execute a `production build` with 66 | 67 | ```bash 68 | yarn bundle:prod 69 | ``` 70 | 71 | This ensures that the extension sources are bundled efficiently without development overhead like source maps. 72 | Both example extension (normal & web) have a `package` utility script that will automatically create the corresponding `*.vsix` file with `vsce`. 73 | To package the normal extension use 74 | 75 | ```bash 76 | yarn workflow package 77 | ``` 78 | 79 | and for the web extension use 80 | 81 | ```bash 82 | yarn workflow:web package 83 | ``` 84 | 85 | ### Where to find the sources? 86 | 87 | In addition to this repository, the related source code can be found here: 88 | 89 | - 90 | - 91 | - 92 | 93 | ## More information 94 | 95 | For more information, please visit the [Eclipse GLSP Umbrella repository](https://github.com/eclipse-glsp/glsp) and the [Eclipse GLSP Website](https://www.eclipse.org/glsp/). 96 | If you have questions, please raise them in the [discussions](https://github.com/eclipse-glsp/glsp/discussions) and have a look at our [communication and support options](https://www.eclipse.org/glsp/contact/). 97 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Eclipse GLSP Vulnerability Reporting Policy 2 | 3 | If you think or suspect that you have discovered a new security vulnerability in this project, please do not disclose it on GitHub, e.g. in an issue, a PR, or a discussion. Any such disclosure will be removed/deleted on sight, to promote orderly disclosure, as per the Eclipse Foundation Security Policy (1). 4 | 5 | Instead, please report any potential vulnerability to the Eclipse Foundation Security Team. Make sure to provide a concise description of the issue, a CWE, and other supporting information. 6 | 7 | (1) Eclipse Foundation Vulnerability Reporting Policy: 8 | -------------------------------------------------------------------------------- /documentation/vscode-diagram.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipse-glsp/glsp-vscode-integration/edec0c24c7521c8d7e2e18f81dcc6138af6a4c99/documentation/vscode-diagram.mp4 -------------------------------------------------------------------------------- /example/workflow/extension/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: '../../../.eslintrc.js', 4 | rules: { 5 | 'import/no-unresolved': 'off' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /example/workflow/extension/.vscodeignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | src 4 | tsconfig.json 5 | tsconfig.tsbuildinfo 6 | -------------------------------------------------------------------------------- /example/workflow/extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workflow-vscode-example", 3 | "displayName": "Workflow GLSP Example", 4 | "version": "2.5.0", 5 | "private": "true", 6 | "description": "An example graphical language used for modeling workflows", 7 | "categories": [ 8 | "Programming Languages" 9 | ], 10 | "homepage": "https://www.eclipse.org/glsp/", 11 | "bugs": "https://github.com/eclipse-glsp/glsp/issues", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/eclipse-glsp/glsp-vscode-integration.git" 15 | }, 16 | "author": { 17 | "name": "EclipseGLSP" 18 | }, 19 | "contributors": [ 20 | { 21 | "name": "Eclipse GLSP Project", 22 | "email": "glsp-dev@eclipse.org", 23 | "url": "https://projects.eclipse.org/projects/ecd.glsp" 24 | } 25 | ], 26 | "publisher": "Eclipse-GLSP", 27 | "main": "./dist/workflow-extension", 28 | "files": [ 29 | "dist" 30 | ], 31 | "scripts": { 32 | "build": "yarn compile && yarn bundle", 33 | "bundle": "webpack", 34 | "bundle:prod": "webpack --config ./webpack.prod.js", 35 | "clean": "rimraf lib tsconfig.tsbuildinfo dist", 36 | "compile": "tsc -b", 37 | "lint": "eslint --ext .ts,.tsx ./src", 38 | "package": "vsce package --yarn", 39 | "watch": "tsc -w", 40 | "watch:bundle": "webpack --watch" 41 | }, 42 | "contributes": { 43 | "commands": [ 44 | { 45 | "command": "workflow.fit", 46 | "title": "Fit to Screen", 47 | "category": "Workflow Diagram", 48 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 49 | }, 50 | { 51 | "command": "workflow.center", 52 | "title": "Center selection", 53 | "category": "Workflow Diagram", 54 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 55 | }, 56 | { 57 | "command": "workflow.layout", 58 | "title": "Layout diagram", 59 | "category": "Workflow Diagram", 60 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 61 | }, 62 | { 63 | "command": "workflow.goToPreviousNode", 64 | "title": "Go to previous Node", 65 | "icon": "$(arrow-circle-left)", 66 | "category": "Workflow Navigation", 67 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 68 | }, 69 | { 70 | "command": "workflow.goToNextNode", 71 | "title": "Go to next Node", 72 | "icon": "$(arrow-circle-right)", 73 | "category": "Workflow Navigation", 74 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 75 | }, 76 | { 77 | "command": "workflow.showDocumentation", 78 | "title": "Show documentation...", 79 | "category": "Workflow Navigation", 80 | "icon": "$(code-oss)", 81 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 82 | }, 83 | { 84 | "command": "workflow.exportAsSVG", 85 | "title": "Export as SVG", 86 | "category": "Workflow Diagram", 87 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 88 | } 89 | ], 90 | "customEditors": [ 91 | { 92 | "viewType": "workflow.glspDiagram", 93 | "displayName": "Workflow Diagram Editor", 94 | "selector": [ 95 | { 96 | "filenamePattern": "*.wf" 97 | } 98 | ] 99 | } 100 | ], 101 | "keybindings": [ 102 | { 103 | "key": "alt+f", 104 | "mac": "alt+f", 105 | "command": "workflow.fit", 106 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 107 | }, 108 | { 109 | "key": "alt+c", 110 | "mac": "alt+c", 111 | "command": "workflow.center", 112 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 113 | }, 114 | { 115 | "key": "ctrl+a", 116 | "mac": "ctrl+a", 117 | "command": "workflow.selectAll", 118 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 119 | }, 120 | { 121 | "key": "alt+l", 122 | "mac": "alt+l", 123 | "command": "workflow.layout", 124 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 125 | }, 126 | { 127 | "key": "alt+e", 128 | "mac": "alt+e", 129 | "command": "workflow.exportAsSVG", 130 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 131 | }, 132 | { 133 | "key": "Ctrl+4", 134 | "mac": "cmd+4", 135 | "command": "workflow.goToNextNode", 136 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 137 | }, 138 | { 139 | "key": "Ctrl+3", 140 | "mac": "cmd+3", 141 | "command": "workflow.goToPreviousNode", 142 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 143 | } 144 | ], 145 | "menus": { 146 | "editor/title": [ 147 | { 148 | "submenu": "workflow.editor.title", 149 | "group": "bookmarks" 150 | }, 151 | { 152 | "command": "workflow.goToPreviousNode", 153 | "group": "navigation", 154 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 155 | }, 156 | { 157 | "command": "workflow.goToNextNode", 158 | "group": "navigation", 159 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 160 | }, 161 | { 162 | "command": "workflow.showDocumentation", 163 | "group": "navigation", 164 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 165 | } 166 | ], 167 | "workflow.editor.title": [ 168 | { 169 | "command": "workflow.fit", 170 | "group": "navigation", 171 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 172 | }, 173 | { 174 | "command": "workflow.center", 175 | "group": "navigation", 176 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 177 | }, 178 | { 179 | "command": "workflow.layout", 180 | "group": "navigation", 181 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 182 | }, 183 | { 184 | "command": "workflow.exportAsSVG", 185 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 186 | } 187 | ] 188 | }, 189 | "submenus": [ 190 | { 191 | "id": "workflow.editor.title", 192 | "label": "Diagram" 193 | } 194 | ] 195 | }, 196 | "activationEvents": [ 197 | "onStartupFinished" 198 | ], 199 | "devDependencies": { 200 | "@eclipse-glsp-examples/workflow-server": "next", 201 | "@eclipse-glsp-examples/workflow-server-bundled": "next", 202 | "@eclipse-glsp/vscode-integration": "2.5.0", 203 | "@vscode/vsce": "^2.19.0", 204 | "copy-webpack-plugin": "^11.0.0", 205 | "ts-loader": "^9.4.4", 206 | "webpack": "^5.88.2", 207 | "webpack-cli": "^5.1.4", 208 | "webpack-merge": "^5.9.0", 209 | "workflow-glsp-webview": "2.5.0" 210 | }, 211 | "engines": { 212 | "vscode": "^1.54.0" 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /example/workflow/extension/src/workflow-editor-provider.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.01 15 | ********************************************************************************/ 16 | import { GlspEditorProvider, GlspVscodeConnector } from '@eclipse-glsp/vscode-integration'; 17 | import * as vscode from 'vscode'; 18 | 19 | export default class WorkflowEditorProvider extends GlspEditorProvider { 20 | diagramType = 'workflow-diagram'; 21 | 22 | constructor( 23 | protected readonly extensionContext: vscode.ExtensionContext, 24 | protected override readonly glspVscodeConnector: GlspVscodeConnector 25 | ) { 26 | super(glspVscodeConnector); 27 | } 28 | 29 | setUpWebview( 30 | _document: vscode.CustomDocument, 31 | webviewPanel: vscode.WebviewPanel, 32 | _token: vscode.CancellationToken, 33 | clientId: string 34 | ): void { 35 | const webview = webviewPanel.webview; 36 | const extensionUri = this.extensionContext.extensionUri; 37 | const webviewScriptSourceUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'dist', 'webview.js')); 38 | 39 | webviewPanel.webview.options = { 40 | enableScripts: true 41 | }; 42 | 43 | webviewPanel.webview.html = ` 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 |
56 | 57 | 58 | `; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /example/workflow/extension/src/workflow-extension.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import 'reflect-metadata'; 17 | 18 | import { WorkflowDiagramModule, WorkflowLayoutConfigurator, WorkflowServerModule } from '@eclipse-glsp-examples/workflow-server/node'; 19 | import { configureELKLayoutModule } from '@eclipse-glsp/layout-elk'; 20 | import { GModelStorage, LogLevel, createAppModule } from '@eclipse-glsp/server/node'; 21 | import { 22 | GlspSocketServerLauncher, 23 | GlspVscodeConnector, 24 | NavigateAction, 25 | NodeGlspVscodeServer, 26 | SocketGlspVscodeServer, 27 | configureDefaultCommands 28 | } from '@eclipse-glsp/vscode-integration/node'; 29 | import { ContainerModule } from 'inversify'; 30 | import * as path from 'path'; 31 | import * as process from 'process'; 32 | import * as vscode from 'vscode'; 33 | import WorkflowEditorProvider from './workflow-editor-provider'; 34 | 35 | const DEFAULT_SERVER_PORT = '0'; 36 | const NODE_EXECUTABLE = path.join(__dirname, '..', 'dist', 'wf-glsp-server-node.js'); 37 | const LOG_DIR = process.env.GLSP_LOG_DIR; 38 | 39 | export async function activate(context: vscode.ExtensionContext): Promise { 40 | // Start server process using quickstart component 41 | let serverProcess: GlspSocketServerLauncher | undefined; 42 | const useIntegratedServer = JSON.parse(process.env.GLSP_INTEGRATED_SERVER ?? 'false'); 43 | if (!useIntegratedServer && process.env.GLSP_SERVER_DEBUG !== 'true') { 44 | const additionalArgs = []; 45 | if (LOG_DIR) { 46 | additionalArgs.push('--fileLog', 'true', '--logDir', LOG_DIR); 47 | } 48 | if (process.env.GLSP_WEBSOCKET_PATH) { 49 | additionalArgs.push('--webSocket'); 50 | } 51 | serverProcess = new GlspSocketServerLauncher({ 52 | executable: NODE_EXECUTABLE, 53 | socketConnectionOptions: { port: JSON.parse(process.env.GLSP_SERVER_PORT || DEFAULT_SERVER_PORT) }, 54 | additionalArgs, 55 | logging: true 56 | }); 57 | 58 | context.subscriptions.push(serverProcess); 59 | await serverProcess.start(); 60 | } 61 | // Wrap server with quickstart component 62 | const workflowServer = useIntegratedServer 63 | ? new NodeGlspVscodeServer({ 64 | clientId: 'glsp.workflow', 65 | clientName: 'workflow', 66 | serverModules: createServerModules() 67 | }) 68 | : new SocketGlspVscodeServer({ 69 | clientId: 'glsp.workflow', 70 | clientName: 'workflow', 71 | connectionOptions: { 72 | port: serverProcess?.getPort() || JSON.parse(process.env.GLSP_SERVER_PORT || DEFAULT_SERVER_PORT), 73 | path: process.env.GLSP_WEBSOCKET_PATH 74 | } 75 | }); 76 | // Initialize GLSP-VSCode connector with server wrapper 77 | const glspVscodeConnector = new GlspVscodeConnector({ 78 | server: workflowServer, 79 | logging: true 80 | }); 81 | 82 | const customEditorProvider = vscode.window.registerCustomEditorProvider( 83 | 'workflow.glspDiagram', 84 | new WorkflowEditorProvider(context, glspVscodeConnector), 85 | { 86 | webviewOptions: { retainContextWhenHidden: true }, 87 | supportsMultipleEditorsPerDocument: false 88 | } 89 | ); 90 | 91 | context.subscriptions.push(workflowServer, glspVscodeConnector, customEditorProvider); 92 | workflowServer.start(); 93 | 94 | configureDefaultCommands({ extensionContext: context, connector: glspVscodeConnector, diagramPrefix: 'workflow' }); 95 | 96 | context.subscriptions.push( 97 | vscode.commands.registerCommand('workflow.goToNextNode', () => { 98 | glspVscodeConnector.dispatchAction(NavigateAction.create('next')); 99 | }), 100 | vscode.commands.registerCommand('workflow.goToPreviousNode', () => { 101 | glspVscodeConnector.dispatchAction(NavigateAction.create('previous')); 102 | }), 103 | vscode.commands.registerCommand('workflow.showDocumentation', () => { 104 | glspVscodeConnector.dispatchAction(NavigateAction.create('documentation')); 105 | }) 106 | ); 107 | } 108 | 109 | function createServerModules(): ContainerModule[] { 110 | const appModule = createAppModule({ logLevel: LogLevel.info, logDir: LOG_DIR, fileLog: true, consoleLog: false }); 111 | const elkLayoutModule = configureELKLayoutModule({ algorithms: ['layered'], layoutConfigurator: WorkflowLayoutConfigurator }); 112 | const mainModule = new WorkflowServerModule().configureDiagramModule(new WorkflowDiagramModule(() => GModelStorage), elkLayoutModule); 113 | return [appModule, mainModule]; 114 | } 115 | -------------------------------------------------------------------------------- /example/workflow/extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config", 3 | "compilerOptions": { 4 | "composite": true, 5 | "rootDir": "src", 6 | "outDir": "lib" 7 | }, 8 | "include": ["src", "dist"], 9 | "references": [ 10 | { 11 | "path": "../../../packages/vscode-integration" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /example/workflow/extension/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | const CopyPlugin = require('copy-webpack-plugin'); 6 | const nodeModules = path.resolve(__dirname, '../../../node_modules'); 7 | 8 | /**@type {import('webpack').Configuration}*/ 9 | const config = { 10 | target: 'node', 11 | 12 | entry: path.resolve(__dirname, 'src/workflow-extension.ts'), 13 | output: { 14 | path: path.resolve(__dirname, 'dist'), 15 | filename: 'workflow-extension.js', 16 | libraryTarget: 'commonjs2' 17 | }, 18 | devtool: 'source-map', 19 | externals: { 20 | vscode: 'commonjs vscode' 21 | }, 22 | mode: 'development', 23 | resolve: { 24 | extensions: ['.ts', '.js'] 25 | }, 26 | module: { 27 | rules: [ 28 | { 29 | test: /\.ts$/, 30 | exclude: /node_modules/, 31 | use: [ 32 | { 33 | loader: 'ts-loader' 34 | } 35 | ] 36 | } 37 | ] 38 | }, 39 | plugins: [ 40 | new CopyPlugin({ 41 | patterns: [ 42 | { 43 | from: path.resolve(nodeModules, '@eclipse-glsp-examples', 'workflow-server-bundled', 'wf-glsp-server-node.js') 44 | }, 45 | { 46 | from: path.resolve(__dirname, '..', 'webview', 'dist') 47 | } 48 | ] 49 | }) 50 | ], 51 | ignoreWarnings: [/Can't resolve .* in '.*ws\/lib'/], 52 | performance: { 53 | hints: false 54 | } 55 | }; 56 | 57 | module.exports = config; 58 | -------------------------------------------------------------------------------- /example/workflow/extension/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.config.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production', 6 | devtool: false 7 | }); 8 | -------------------------------------------------------------------------------- /example/workflow/web-extension/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: '../../../.eslintrc.js', 4 | rules: { 5 | 'import/no-unresolved': 'off' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /example/workflow/web-extension/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | node_modules 3 | lib/ 4 | src/ 5 | tsconfig.json 6 | webpack.config.js 7 | tsconfig.tsbuildinfo 8 | .eslintrc.js 9 | -------------------------------------------------------------------------------- /example/workflow/web-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workflow-vscode-example-web", 3 | "displayName": "Workflow GLSP Example (Web)", 4 | "version": "2.5.0", 5 | "private": "true", 6 | "description": "An example graphical language used for modeling workflows", 7 | "categories": [ 8 | "Programming Languages" 9 | ], 10 | "homepage": "https://www.eclipse.org/glsp/", 11 | "bugs": "https://github.com/eclipse-glsp/glsp/issues", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/eclipse-glsp/glsp-vscode-integration.git" 15 | }, 16 | "author": { 17 | "name": "EclipseGLSP" 18 | }, 19 | "contributors": [ 20 | { 21 | "name": "Eclipse GLSP Project", 22 | "email": "glsp-dev@eclipse.org", 23 | "url": "https://projects.eclipse.org/projects/ecd.glsp" 24 | } 25 | ], 26 | "publisher": "Eclipse-GLSP", 27 | "browser": "./dist/extension", 28 | "files": [ 29 | "lib", 30 | "dist" 31 | ], 32 | "scripts": { 33 | "build": "yarn compile && yarn bundle", 34 | "bundle": "webpack", 35 | "bundle:prod": "webpack --config ./webpack.prod.js", 36 | "clean": "rimraf lib tsconfig.tsbuildinfo ", 37 | "compile": "tsc-b", 38 | "lint": "eslint --ext .ts,.tsx ./src", 39 | "package": "vsce package --yarn", 40 | "watch": "tsc -w", 41 | "watch:bundle": "webpack --watch" 42 | }, 43 | "contributes": { 44 | "commands": [ 45 | { 46 | "command": "workflow.fit", 47 | "title": "Fit to Screen", 48 | "category": "Workflow Diagram", 49 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 50 | }, 51 | { 52 | "command": "workflow.center", 53 | "title": "Center selection", 54 | "category": "Workflow Diagram", 55 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 56 | }, 57 | { 58 | "command": "workflow.layout", 59 | "title": "Layout diagram", 60 | "category": "Workflow Diagram", 61 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 62 | }, 63 | { 64 | "command": "workflow.goToPreviousNode", 65 | "title": "Go to previous Node", 66 | "icon": "$(arrow-circle-left)", 67 | "category": "Workflow Navigation", 68 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 69 | }, 70 | { 71 | "command": "workflow.goToNextNode", 72 | "title": "Go to next Node", 73 | "icon": "$(arrow-circle-right)", 74 | "category": "Workflow Navigation", 75 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 76 | }, 77 | { 78 | "command": "workflow.showDocumentation", 79 | "title": "Show documentation...", 80 | "category": "Workflow Navigation", 81 | "icon": "$(code-oss)", 82 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 83 | }, 84 | { 85 | "command": "workflow.exportAsSVG", 86 | "title": "Export as SVG", 87 | "category": "Workflow Diagram", 88 | "enablement": "activeCustomEditorId == 'workflow.glspDiagram'" 89 | } 90 | ], 91 | "customEditors": [ 92 | { 93 | "viewType": "workflow.glspDiagram", 94 | "displayName": "Workflow Diagram Editor", 95 | "selector": [ 96 | { 97 | "filenamePattern": "*.wf" 98 | } 99 | ] 100 | } 101 | ], 102 | "keybindings": [ 103 | { 104 | "key": "alt+f", 105 | "mac": "alt+f", 106 | "command": "workflow.fit", 107 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 108 | }, 109 | { 110 | "key": "alt+c", 111 | "mac": "alt+c", 112 | "command": "workflow.center", 113 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 114 | }, 115 | { 116 | "key": "ctrl+a", 117 | "mac": "ctrl+a", 118 | "command": "workflow.selectAll", 119 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 120 | }, 121 | { 122 | "key": "alt+l", 123 | "mac": "alt+l", 124 | "command": "workflow.layout", 125 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 126 | }, 127 | { 128 | "key": "alt+e", 129 | "mac": "alt+e", 130 | "command": "workflow.exportAsSVG", 131 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 132 | }, 133 | { 134 | "key": "Ctrl+4", 135 | "mac": "cmd+4", 136 | "command": "workflow.goToNextNode", 137 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 138 | }, 139 | { 140 | "key": "Ctrl+3", 141 | "mac": "cmd+3", 142 | "command": "workflow.goToPreviousNode", 143 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 144 | } 145 | ], 146 | "menus": { 147 | "editor/title": [ 148 | { 149 | "submenu": "workflow.editor.title", 150 | "group": "bookmarks" 151 | }, 152 | { 153 | "command": "workflow.goToPreviousNode", 154 | "group": "navigation", 155 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 156 | }, 157 | { 158 | "command": "workflow.goToNextNode", 159 | "group": "navigation", 160 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 161 | }, 162 | { 163 | "command": "workflow.showDocumentation", 164 | "group": "navigation", 165 | "when": "activeCustomEditorId == 'workflow.glspDiagram' && workflow.editorSelectedElementsAmount == 1" 166 | } 167 | ], 168 | "workflow.editor.title": [ 169 | { 170 | "command": "workflow.fit", 171 | "group": "navigation", 172 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 173 | }, 174 | { 175 | "command": "workflow.center", 176 | "group": "navigation", 177 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 178 | }, 179 | { 180 | "command": "workflow.layout", 181 | "group": "navigation", 182 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 183 | }, 184 | { 185 | "command": "workflow.exportAsSVG", 186 | "when": "activeCustomEditorId == 'workflow.glspDiagram'" 187 | } 188 | ] 189 | }, 190 | "submenus": [ 191 | { 192 | "id": "workflow.editor.title", 193 | "label": "Diagram" 194 | } 195 | ] 196 | }, 197 | "activationEvents": [ 198 | "onStartupFinished" 199 | ], 200 | "devDependencies": { 201 | "@eclipse-glsp-examples/workflow-server": "next", 202 | "@eclipse-glsp/vscode-integration": "2.5.0", 203 | "@types/node": "16.x", 204 | "@vscode/vsce": "^2.19.0", 205 | "copy-webpack-plugin": "^11.0.0", 206 | "webpack": "^5.75.0", 207 | "webpack-cli": "^5.0.1", 208 | "webpack-merge": "^5.9.0", 209 | "workflow-glsp-webview": "2.5.0" 210 | }, 211 | "engines": { 212 | "vscode": "^1.54.0" 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /example/workflow/web-extension/src/workflow-editor-provider.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { GlspEditorProvider, GlspVscodeConnector } from '@eclipse-glsp/vscode-integration/browser'; 17 | import * as vscode from 'vscode'; 18 | 19 | export default class WorkflowEditorProvider extends GlspEditorProvider { 20 | diagramType = 'workflow-diagram'; 21 | 22 | constructor( 23 | protected readonly extensionContext: vscode.ExtensionContext, 24 | protected override readonly glspVscodeConnector: GlspVscodeConnector 25 | ) { 26 | super(glspVscodeConnector); 27 | } 28 | 29 | setUpWebview( 30 | _document: vscode.CustomDocument, 31 | webviewPanel: vscode.WebviewPanel, 32 | _token: vscode.CancellationToken, 33 | clientId: string 34 | ): void { 35 | const webview = webviewPanel.webview; 36 | const extensionUri = this.extensionContext.extensionUri; 37 | const webviewScriptSourceUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'dist', 'webview.js')); 38 | 39 | webviewPanel.webview.options = { 40 | enableScripts: true 41 | }; 42 | 43 | webviewPanel.webview.html = ` 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 |
56 | 57 | 58 | `; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /example/workflow/web-extension/src/workflow-extension.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import 'reflect-metadata'; 17 | 18 | import { 19 | BrowserGlspVscodeServer, 20 | GlspVscodeConnector, 21 | NavigateAction, 22 | WebSocketGlspVscodeServer, 23 | configureDefaultCommands 24 | } from '@eclipse-glsp/vscode-integration/browser'; 25 | import * as vscode from 'vscode'; 26 | import WorkflowEditorProvider from './workflow-editor-provider'; 27 | import { createServerModules } from './workflow-server'; 28 | 29 | export async function activate(context: vscode.ExtensionContext): Promise { 30 | // Env variables are no available in the web extension context. So we have to check wether 31 | // the websocket address for the external usecase is reachable to decide which server variant should be used 32 | 33 | const webSocketAddress = 'ws://localhost:8081/workflow'; 34 | const useWebSocket = await isAvailable(webSocketAddress); 35 | 36 | const workflowServer = useWebSocket 37 | ? new WebSocketGlspVscodeServer({ 38 | clientId: 'glsp.workflow', 39 | clientName: 'workflow', 40 | connectionOptions: { webSocketAddress } 41 | }) 42 | : new BrowserGlspVscodeServer({ 43 | clientId: 'glsp.workflow', 44 | clientName: 'workflow', 45 | serverModules: createServerModules() 46 | }); 47 | 48 | // Initialize GLSP-VSCode connector with server wrapper 49 | const glspVscodeConnector = new GlspVscodeConnector({ 50 | server: workflowServer, 51 | logging: true 52 | }); 53 | 54 | const customEditorProvider = vscode.window.registerCustomEditorProvider( 55 | 'workflow.glspDiagram', 56 | new WorkflowEditorProvider(context, glspVscodeConnector), 57 | { 58 | webviewOptions: { retainContextWhenHidden: true }, 59 | supportsMultipleEditorsPerDocument: false 60 | } 61 | ); 62 | 63 | context.subscriptions.push(workflowServer, glspVscodeConnector, customEditorProvider); 64 | workflowServer.start(); 65 | 66 | configureDefaultCommands({ extensionContext: context, connector: glspVscodeConnector, diagramPrefix: 'workflow' }); 67 | 68 | context.subscriptions.push( 69 | vscode.commands.registerCommand('workflow.goToNextNode', () => { 70 | glspVscodeConnector.dispatchAction(NavigateAction.create('next')); 71 | }), 72 | vscode.commands.registerCommand('workflow.goToPreviousNode', () => { 73 | glspVscodeConnector.dispatchAction(NavigateAction.create('previous')); 74 | }), 75 | vscode.commands.registerCommand('workflow.showDocumentation', () => { 76 | glspVscodeConnector.dispatchAction(NavigateAction.create('documentation')); 77 | }) 78 | ); 79 | } 80 | 81 | function isAvailable(webSocketAddress: string): Promise { 82 | return new Promise((resolve, reject) => { 83 | const webSocket = new WebSocket(webSocketAddress); 84 | webSocket.onopen = () => { 85 | webSocket.close(); 86 | resolve(true); 87 | }; 88 | webSocket.onerror = () => resolve(false); 89 | }); 90 | } 91 | -------------------------------------------------------------------------------- /example/workflow/web-extension/src/workflow-server.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { WorkflowDiagramModule, WorkflowServerModule } from '@eclipse-glsp-examples/workflow-server/browser'; 17 | import { 18 | GLSPServerError, 19 | GModelSerializer, 20 | LogLevel, 21 | Logger, 22 | ModelState, 23 | SOURCE_URI_ARG, 24 | SourceModelStorage, 25 | createAppModule 26 | } from '@eclipse-glsp/server/browser'; 27 | import { 28 | MaybePromise, 29 | RequestModelAction, 30 | SaveModelAction, 31 | TypeGuard, 32 | isGModelElementSchema 33 | } from '@eclipse-glsp/vscode-integration/browser'; 34 | import { ContainerModule, inject, injectable } from 'inversify'; 35 | import * as vscode from 'vscode'; 36 | 37 | export function createServerModules(): ContainerModule[] { 38 | const appModule = createAppModule({ logLevel: LogLevel.info, consoleLog: true }); 39 | const mainModule = new WorkflowServerModule().configureDiagramModule(new WorkflowDiagramModule(() => GModelVSCodeStorage)); 40 | return [appModule, mainModule]; 41 | } 42 | 43 | @injectable() 44 | export class GModelVSCodeStorage implements SourceModelStorage { 45 | @inject(Logger) 46 | protected logger: Logger; 47 | 48 | @inject(GModelSerializer) 49 | protected modelSerializer: GModelSerializer; 50 | 51 | @inject(ModelState) 52 | protected modelState: ModelState; 53 | 54 | async loadSourceModel(action: RequestModelAction): Promise { 55 | const sourceUri = this.getSourceUri(action); 56 | const rootSchema = await this.loadFromFile(sourceUri, isGModelElementSchema); 57 | const root = this.modelSerializer.createRoot(rootSchema); 58 | this.modelState.updateRoot(root); 59 | } 60 | 61 | saveSourceModel(action: SaveModelAction): MaybePromise { 62 | const fileUri = this.getFileUri(action); 63 | const schema = this.modelSerializer.createSchema(this.modelState.root); 64 | this.writeFile(fileUri, schema); 65 | } 66 | 67 | protected getSourceUri(action: RequestModelAction): vscode.Uri { 68 | const sourceUri = action.options?.[SOURCE_URI_ARG]; 69 | if (typeof sourceUri !== 'string') { 70 | throw new GLSPServerError(`Invalid RequestModelAction! Missing argument with key '${SOURCE_URI_ARG}'`); 71 | } 72 | return vscode.Uri.parse(sourceUri); 73 | } 74 | 75 | protected loadFromFile(sourceUri: vscode.Uri): Promise; 76 | protected loadFromFile(sourceUri: vscode.Uri, guard: TypeGuard): Promise; 77 | protected async loadFromFile(sourceUri: vscode.Uri, guard?: TypeGuard): Promise { 78 | try { 79 | const fileContent = await this.readFile(sourceUri); 80 | if (!fileContent) { 81 | throw new GLSPServerError(`Could not load the source model. The file '${sourceUri}' is empty!.`); 82 | } 83 | 84 | if (guard && !guard(fileContent)) { 85 | throw new Error('The loaded root object is not of the expected type!'); 86 | } 87 | return fileContent; 88 | } catch (error) { 89 | throw new GLSPServerError(`Could not load model from file: ${sourceUri}`, error); 90 | } 91 | } 92 | 93 | protected async readFile(uri: vscode.Uri): Promise { 94 | try { 95 | const data = await vscode.workspace.fs.readFile(uri); 96 | return this.toJson(data); 97 | } catch (error) { 98 | throw new GLSPServerError(`Could not read & parse file contents of '${uri}' as json`, error); 99 | } 100 | } 101 | 102 | protected toJson(fileContent: Uint8Array): unknown { 103 | const jsonString = new TextDecoder().decode(fileContent); 104 | return JSON.parse(jsonString); 105 | } 106 | 107 | protected getFileUri(action: SaveModelAction): vscode.Uri { 108 | const uri = action.fileUri ?? this.modelState.get(SOURCE_URI_ARG); 109 | if (!uri) { 110 | throw new GLSPServerError('Could not derive fileUri for saving the current source model'); 111 | } 112 | return vscode.Uri.parse(uri); 113 | } 114 | 115 | protected fromJson(jsonObject: unknown): Uint8Array { 116 | const jsonString = JSON.stringify(jsonObject); 117 | return new TextEncoder().encode(jsonString); 118 | } 119 | 120 | protected async writeFile(fileUri: vscode.Uri, model: unknown): Promise { 121 | const content = this.fromJson(model); 122 | await vscode.workspace.fs.writeFile(fileUri, content); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /example/workflow/web-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config", 3 | "compilerOptions": { 4 | "composite": true, 5 | "rootDir": "src", 6 | "outDir": "lib" 7 | }, 8 | "include": ["src", "dist"], 9 | "references": [ 10 | { 11 | "path": "../../../packages/vscode-integration" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /example/workflow/web-extension/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | const CopyPlugin = require('copy-webpack-plugin'); 6 | 7 | /**@type {import('webpack').Configuration}*/ 8 | const config = { 9 | target: 'webworker', // vscode extensions run in webworker context for VS Code web 📖 -> https://webpack.js.org/configuration/target/#target 10 | 11 | entry: './src/workflow-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 | }, 18 | mode: 'development', 19 | devtool: 'eval-source-map', 20 | externals: { 21 | 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/ 22 | }, 23 | resolve: { 24 | // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader 25 | mainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules 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 | plugins: [ 42 | new webpack.ProvidePlugin({ 43 | process: 'process/browser' // provide a shim for the global `process` variable 44 | }), 45 | new CopyPlugin({ 46 | patterns: [ 47 | { 48 | from: path.resolve(__dirname, '..', 'webview', 'dist') 49 | } 50 | ] 51 | }) 52 | ], 53 | ignoreWarnings: [/Can't resolve .* in '.*ws\/lib'/], 54 | performance: { 55 | hints: false 56 | } 57 | }; 58 | module.exports = config; 59 | -------------------------------------------------------------------------------- /example/workflow/web-extension/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.config.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production', 6 | devtool: false 7 | }); 8 | -------------------------------------------------------------------------------- /example/workflow/webview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workflow-glsp-webview", 3 | "version": "2.5.0", 4 | "private": "true", 5 | "description": "Example of the Workflow GLSP diagram in a VS Code extensions (WebView part)", 6 | "keywords": [ 7 | "vscode", 8 | "graph", 9 | "diagram", 10 | "layout", 11 | "glsp" 12 | ], 13 | "homepage": "https://www.eclipse.org/glsp/", 14 | "bugs": "https://github.com/eclipse-glsp/glsp/issues", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/eclipse-glsp/glsp-vscode-integration.git" 18 | }, 19 | "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", 20 | "author": { 21 | "name": "Eclipse GLSP" 22 | }, 23 | "contributors": [ 24 | { 25 | "name": "Eclipse GLSP Project", 26 | "email": "glsp-dev@eclipse.org", 27 | "url": "https://projects.eclipse.org/projects/ecd.glsp" 28 | } 29 | ], 30 | "scripts": { 31 | "build": "yarn compile && yarn bundle", 32 | "bundle": "webpack", 33 | "bundle:prod": "webpack --config ./webpack.prod.js", 34 | "clean": "rimraf lib tsconfig.tsbuildinfo dist", 35 | "compile": "tsc -b", 36 | "lint": "eslint --ext .ts,.tsx ./src", 37 | "watch": "tsc -w" 38 | }, 39 | "devDependencies": { 40 | "@eclipse-glsp-examples/workflow-glsp": "next", 41 | "@eclipse-glsp/vscode-integration-webview": "2.5.0", 42 | "@vscode/codicons": "^0.0.25", 43 | "circular-dependency-plugin": "^5.2.2", 44 | "css-loader": "^6.7.1", 45 | "ignore-loader": "^0.1.2", 46 | "process": "0.11.10", 47 | "reflect-metadata": "^0.1.13", 48 | "source-map-loader": "^4.0.1", 49 | "style-loader": "^3.3.1", 50 | "ts-loader": "^9.4.2", 51 | "webpack": "^5.75.0", 52 | "webpack-cli": "^5.0.1", 53 | "webpack-merge": "^5.9.0" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /example/workflow/webview/src/app.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2020-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { createWorkflowDiagramContainer } from '@eclipse-glsp-examples/workflow-glsp'; 17 | import { ContainerConfiguration } from '@eclipse-glsp/client'; 18 | import { GLSPStarter } from '@eclipse-glsp/vscode-integration-webview'; 19 | import '@eclipse-glsp/vscode-integration-webview/css/glsp-vscode.css'; 20 | import '@vscode/codicons/dist/codicon.css'; 21 | import { Container } from 'inversify'; 22 | 23 | class WorkflowGLSPStarter extends GLSPStarter { 24 | createContainer(...containerConfiguration: ContainerConfiguration): Container { 25 | return createWorkflowDiagramContainer(...containerConfiguration); 26 | } 27 | } 28 | 29 | export function launch(): void { 30 | new WorkflowGLSPStarter(); 31 | } 32 | -------------------------------------------------------------------------------- /example/workflow/webview/src/index.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import 'reflect-metadata'; 17 | import { launch } from './app'; 18 | 19 | launch(); 20 | -------------------------------------------------------------------------------- /example/workflow/webview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config/tsconfig.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "rootDir": "src", 6 | "outDir": "lib" 7 | }, 8 | "include": ["src"], 9 | "references": [ 10 | { 11 | "path": "../../../packages/vscode-integration-webview" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /example/workflow/webview/webpack.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const path = require('path'); 3 | 4 | const outputPath = path.resolve(__dirname, './dist/'); 5 | 6 | /**@type {import('webpack').Configuration}*/ 7 | const config = { 8 | target: 'web', 9 | 10 | entry: path.resolve(__dirname, 'src/index.ts'), 11 | output: { 12 | filename: 'webview.js', 13 | path: outputPath 14 | }, 15 | devtool: 'eval-source-map', 16 | mode: 'development', 17 | 18 | resolve: { 19 | fallback: { 20 | fs: false, 21 | net: false 22 | }, 23 | alias: { 24 | process: 'process/browser' 25 | }, 26 | extensions: ['.ts', '.tsx', '.js'] 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.tsx?$/, 32 | use: ['ts-loader'] 33 | }, 34 | { 35 | test: /\.js$/, 36 | use: ['source-map-loader'], 37 | enforce: 'pre' 38 | }, 39 | { 40 | test: /\.css$/, 41 | exclude: /\.useable\.css$/, 42 | use: ['style-loader', 'css-loader'] 43 | } 44 | ] 45 | }, 46 | ignoreWarnings: [/Failed to parse source map/, /Can't resolve .* in '.*ws\/lib'/], 47 | performance: { 48 | hints: false 49 | } 50 | }; 51 | 52 | module.exports = config; 53 | -------------------------------------------------------------------------------- /example/workflow/webview/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.config.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production', 6 | devtool: false 7 | }); 8 | -------------------------------------------------------------------------------- /example/workflow/workspace/example1.md: -------------------------------------------------------------------------------- 1 | = Documentation = 2 | 3 | == Push == 4 | 5 | The push task is performed by the user. He or she pushes the button. 6 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.5.0", 3 | "npmClient": "yarn", 4 | "command": { 5 | "run": { 6 | "stream": true 7 | }, 8 | "publish": { 9 | "forcePublish": true, 10 | "skipGit": true, 11 | "registry": "https://registry.npmjs.org/" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipse-glsp/glsp-vscode-integration/edec0c24c7521c8d7e2e18f81dcc6138af6a4c99/logs/.gitkeep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.5.0-next", 3 | "private": true, 4 | "workspaces": [ 5 | "packages/*", 6 | "example/workflow/*" 7 | ], 8 | "scripts": { 9 | "all": "yarn install && yarn lint", 10 | "build": "yarn compile && yarn bundle", 11 | "bundle": " lerna run bundle", 12 | "bundle:prod": "lerna run bundle:prod", 13 | "check:headers": "glsp checkHeaders . -t lastCommit", 14 | "check:pr": "yarn all && yarn check:headers", 15 | "clean": "lerna run clean && rimraf logs/*.log", 16 | "compile": "tsc -b", 17 | "generate:index": "lerna run generate:index && yarn lint:fix", 18 | "lint": "eslint --ext .ts,.tsx .", 19 | "lint:ci": "yarn lint -o eslint.xml -f checkstyle", 20 | "lint:fix": "yarn lint --fix", 21 | "prepare": "yarn build", 22 | "publish:latest": "lerna publish from-git --no-git-reset --no-git-tag-version --no-push", 23 | "publish:next": "lerna publish preminor --exact --canary --preid next --dist-tag next --no-git-reset --no-git-tag-version --no-push --ignore-scripts --yes", 24 | "publish:prepare": "lerna version --ignore-scripts --yes --no-push", 25 | "upgrade:next": "glsp updateNext", 26 | "watch": "concurrently --kill-others -n tsc,extension,web-extension -c red,yellow.green \"tsc -b -w --preserveWatchOutput\" \"yarn -s workflow watch:bundle\" \"yarn -s workflow:web watch:bundle\"", 27 | "workflow": "yarn --cwd example/workflow/extension", 28 | "workflow:web": "yarn --cwd example/workflow/web-extension" 29 | }, 30 | "devDependencies": { 31 | "@eclipse-glsp/dev": "next", 32 | "@types/node": "18.x", 33 | "@types/vscode": "^1.54.0", 34 | "concurrently": "^8.2.2", 35 | "lerna": "^7.0.0", 36 | "typescript": "^5.0.4" 37 | }, 38 | "engines": { 39 | "node": ">=18", 40 | "yarn": ">=1.7.0 <2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/README.md: -------------------------------------------------------------------------------- 1 | # Eclipse GLSP VSCode Integration 2 | 3 | This package helps you to implement a [VS Code Webview](https://code.visualstudio.com/api/extension-guides/webview) that renders a [GLSP](https://www.eclipse.org/glsp/) diagram. 4 | 5 | ## Where to find the sources? 6 | 7 | In addition to this repository, the related source code can be found here: 8 | 9 | - 10 | - 11 | - 12 | 13 | ## More information 14 | 15 | For more information, please visit the [Eclipse GLSP Umbrella repository](https://github.com/eclipse-glsp/glsp) and the [Eclipse GLSP Website](https://www.eclipse.org/glsp/). 16 | If you have questions, please raise them in the [discussions](https://github.com/eclipse-glsp/glsp/discussions) and have a look at our [communication and support options](https://www.eclipse.org/glsp/contact/). 17 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/css/command-palette.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2019 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | .command-palette { 18 | z-index: var(--vscode-menu-z-index); 19 | -webkit-animation: fadein 0.3s; 20 | -moz-animation: fadein 0.3s; 21 | -ms-animation: fadein 0.3s; 22 | -o-animation: fadein 0.3s; 23 | animation: fadein 0.3s; 24 | } 25 | 26 | .command-palette.validation .validation-decorator { 27 | position: absolute; 28 | padding-left: 5px; 29 | padding-top: 5px; 30 | padding-bottom: 5px; 31 | border-radius: 5px 5px 0px 0px; 32 | color: white; 33 | /* indent second line for icon */ 34 | padding-left: 25px; 35 | text-indent: -10px; 36 | /* let error decoration fade in */ 37 | -webkit-animation: fadein 0.3s; 38 | -moz-animation: fadein 0.3s; 39 | -ms-animation: fadein 0.3s; 40 | -o-animation: fadein 0.3s; 41 | animation: fadein 0.3s; 42 | } 43 | 44 | .command-palette.validation.error input, 45 | .command-palette.validation.error input:focus { 46 | color: var(--vscode-inputValidation-errorForeground); 47 | outline-color: var(--vscode-inputValidation-errorBorder); 48 | } 49 | 50 | .command-palette.validation.error .validation-decorator.error { 51 | border: 1px solid var(--vscode-inputValidation-errorBorder); 52 | background-color: var(--vscode-inputValidation-errorBorder); 53 | } 54 | 55 | .command-palette.validation.warning input, 56 | .command-palette.validation.warning input:focus { 57 | color: var(--vscode-inputValidation-warningForeground); 58 | outline-color: var(--vscode-inputValidation-warningBorder); 59 | } 60 | 61 | .command-palette.validation.warning .validation-decorator.warning { 62 | border: 1px solid var(--vscode-inputValidation-warningBorder); 63 | background-color: var(--vscode-inputValidation-warningBorder); 64 | } 65 | 66 | .command-palette { 67 | box-shadow: var(--vscode-border-width) var(--vscode-border-width) var(--vscode-widget-shadow); 68 | background-color: var(--vscode-menu-background); 69 | } 70 | 71 | .command-palette input { 72 | background: var(--vscode-input-background); 73 | color: var(--vscode-input-foreground); 74 | border: var(--vscode-border-width) solid var(--vscode-input-border); 75 | font-family: var(--vscode-ui-font-family); 76 | font-size: var(--vscode-ui-font-size1); 77 | line-height: var(--vscode-content-line-height); 78 | padding-left: 5px; 79 | } 80 | 81 | .command-palette .command-palette-suggestions { 82 | background: inherit; 83 | line-height: var(--vscode-content-line-height); 84 | } 85 | 86 | .command-palette .command-palette-suggestions > div:hover:not(.group) { 87 | background: var(--vscode-menubar-selectionBackground); 88 | } 89 | 90 | .command-palette .command-palette-suggestions > div.selected { 91 | background: var(--vscode-menu-selectionBackground); 92 | color: var(--vscode-menu-selectionForeground); 93 | } 94 | 95 | .command-palette .loading { 96 | position: absolute; 97 | font-size: inherit; 98 | top: 5px; 99 | right: 0; 100 | } 101 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/css/decoration.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2020-2021 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | :root { 18 | --glsp-error-foreground: var(--vscode-inputValidation-errorBorder); 19 | --glsp-warning-foreground: var(--vscode-inputValidation-warningBorder); 20 | --glsp-info-foreground: var(--vscode-inputValidation-infoBorder); 21 | } 22 | 23 | .sprotty-issue-background { 24 | fill: var(--vscode-editor-background); 25 | } 26 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/css/diagram.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2020-2022 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | html, 18 | body { 19 | width: 100%; 20 | height: 100%; 21 | padding: 0px; 22 | overflow: hidden; 23 | } 24 | 25 | .sprotty { 26 | display: flex; 27 | height: 100%; 28 | } 29 | 30 | .sprotty svg { 31 | width: 100%; 32 | flex: 1; 33 | border-style: solid; 34 | border-width: 0px; 35 | } 36 | 37 | .sprotty svg:focus { 38 | border-width: 0; 39 | outline: none; 40 | } 41 | 42 | .sprotty-graph { 43 | background: var(--vscode-editor-background); 44 | } 45 | 46 | .sprotty-node { 47 | stroke: var(--vscode-editor-foreground); 48 | fill: var(--vscode-editor-foreground); 49 | } 50 | 51 | .sprotty-edge { 52 | fill: none; 53 | stroke: var(--vscode-editor-foreground); 54 | } 55 | 56 | .sprotty-edge .arrow { 57 | fill: var(--vscode-editor-foreground); 58 | } 59 | 60 | .sprotty-node.selected, 61 | .sprotty-edge.selected { 62 | stroke: var(--vscode-focusBorder); 63 | } 64 | 65 | .sprotty-edge.selected .arrow { 66 | fill: var(--vscode-focusBorder); 67 | stroke: var(--vscode-focusBorder); 68 | } 69 | 70 | .inactive .sprotty-node.selected { 71 | stroke: var(--vscode-editor-inactiveSelectionBackground); 72 | } 73 | 74 | .sprotty-resize-handle.selected, 75 | .sprotty-resize-handle.active, 76 | .sprotty-edge > .sprotty-routing-handle.selected, 77 | .sprotty-edge > .sprotty-routing-handle.mouseover { 78 | fill: var(--vscode-focusBorder); 79 | } 80 | 81 | .inactive .sprotty-resize-handle, 82 | .inactive .sprotty-routing-handle { 83 | fill: var(--vscode-tab-unfocusedInactiveForeground); 84 | } 85 | 86 | .sprotty-node.mouseover:not(.selected), 87 | .sprotty-edge.mouseover:not(.selected) { 88 | stroke: var(--vscode-editor-foreground); 89 | } 90 | 91 | .sprotty-edge.mouseover:not(.selected) .arrow { 92 | fill: var(--vscode-editor-foreground); 93 | stroke: var(--vscode-editor-foreground); 94 | } 95 | 96 | .sprotty-popup { 97 | padding: 0px; 98 | border-radius: 2px; 99 | box-shadow: 0px 1px 6px var(--vscode-widget-shadow); 100 | background-color: var(--vscode-editorHoverWidget-background); 101 | color: var(--vscode-editorHoverWidget-foreground); 102 | border: 1px solid var(--vscode-editorHoverWidget-border); 103 | } 104 | 105 | .mouse-enter .sprotty-projection-bar { 106 | opacity: 1; 107 | } 108 | 109 | .mouse-leave .sprotty-projection-bar { 110 | opacity: 0; 111 | pointer-events: none; 112 | } 113 | 114 | .sprotty-projection-bar.horizontal.bordered-projection-bar { 115 | height: 15px; 116 | } 117 | 118 | .sprotty-projection-bar.vertical.bordered-projection-bar { 119 | width: 15px; 120 | } 121 | 122 | .sprotty text { 123 | fill: var(--vscode-editor-background); 124 | } 125 | 126 | .sprotty-edge text { 127 | fill: var(--vscode-foreground); 128 | } 129 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/css/features.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | /* Debug */ 18 | 19 | .debug-bounds-decoration { 20 | stroke: var(--vscode-editor-foreground); 21 | } 22 | 23 | /* Ghost element */ 24 | 25 | .sprotty-node.insert-indicator:not(.selected) { 26 | stroke: var(--vscode-editor-foreground); 27 | } 28 | 29 | /* Helper lines */ 30 | 31 | .helper-line { 32 | stroke: var(--vscode-focusBorder); 33 | } 34 | 35 | /* Grid */ 36 | body[data-vscode-theme-kind='vscode-dark'] .grid-background .sprotty-graph, 37 | body[data-vscode-theme-kind='vscode-dark'] .grid-background.sprotty-graph { 38 | --grid-color: rgba(255, 255, 255, 0.1); 39 | } 40 | 41 | body[data-vscode-theme-kind='vscode-light'] .grid-background .sprotty-graph, 42 | body[data-vscode-theme-kind='vscode-light'] .grid-background.sprotty-graph { 43 | --grid-color: rgba(0, 0, 0, 0.1); 44 | } 45 | 46 | body[data-vscode-theme-kind='vscode-high-contrast'] .grid-background .sprotty-graph, 47 | body[data-vscode-theme-kind='vscode-high-contrast'] .grid-background.sprotty-graph { 48 | --grid-color: rgba(255, 255, 255); 49 | } 50 | 51 | body[data-vscode-theme-kind='vscode-high-contrast-light'] .grid-background .sprotty-graph, 52 | body[data-vscode-theme-kind='vscode-high-contrast-light'] .grid-background.sprotty-graph { 53 | --grid-color: rgba(0, 0, 0); 54 | } 55 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/css/glsp-vscode.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2020-2021 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | @import 'command-palette.css'; 18 | @import 'diagram.css'; 19 | @import 'tool-palette.css'; 20 | @import 'decoration.css'; 21 | @import 'features.css'; 22 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/css/tool-palette.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2020-2022 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | .tool-palette { 18 | box-shadow: 0px 1px 6px var(--vscode-widget-shadow); 19 | font-size: var(--vscode-ui-font-size1); 20 | } 21 | 22 | .tool-palette :focus-visible { 23 | outline: none; 24 | } 25 | 26 | .tool-group { 27 | background: var(--vscode-settings-dropdownBackground); 28 | } 29 | 30 | .tool-palette .palette-header { 31 | background: var(--vscode-settings-dropdownBackground); 32 | color: var(--vscode-titleBar-activeForeground); 33 | border: 0; 34 | box-shadow: none; 35 | border-top: 2px solid var(--vscode-focusBorder); 36 | } 37 | 38 | .tool-palette .palette-header .header-tools i { 39 | border: none; 40 | } 41 | 42 | .tool-palette .palette-header .header-tools i:hover:not(.clicked) { 43 | background: var(--vscode-menubar-selectionBackground); 44 | } 45 | 46 | .tool-palette .palette-header .header-tools .clicked { 47 | background: var(--vscode-inputOption-activeBackground); 48 | } 49 | 50 | .tool-palette .palette-body { 51 | border: 0; 52 | box-shadow: none; 53 | background: var(--vscode-list-focusBackground); 54 | color: var(--vscode-titleBar-activeForeground); 55 | } 56 | 57 | .tool-palette .palette-body .group-header { 58 | background: var(--vscode-editorHoverWidget-statusBarBackground); 59 | color: var(--vscode-titleBar-activeForeground); 60 | border: 0; 61 | } 62 | 63 | .tool-button { 64 | background: var(--vscode-settings-dropdownBackground); 65 | color: var(--vscode-titleBar-activeForeground); 66 | } 67 | 68 | .tool-palette .palette-body .tool-button:hover:not(.clicked) { 69 | background: var(--vscode-menubar-selectionBackground); 70 | } 71 | 72 | .tool-palette .tool-button.clicked { 73 | background: var(--vscode-inputOption-activeBackground); 74 | } 75 | 76 | .search-input { 77 | background: var(--vscode-input-background); 78 | color: var(--vscode-input-foreground); 79 | border: var(--vscode-border-width) solid var(--vscode-input-border); 80 | } 81 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eclipse-glsp/vscode-integration-webview", 3 | "version": "2.5.0", 4 | "description": "Integration of a GLSP diagram in a VS Code extensions (WebView part)", 5 | "keywords": [ 6 | "vscode", 7 | "graph", 8 | "diagram", 9 | "layout", 10 | "glsp" 11 | ], 12 | "homepage": "https://www.eclipse.org/glsp/", 13 | "bugs": "https://github.com/eclipse-glsp/glsp/issues", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/eclipse-glsp/glsp-vscode-integration.git" 17 | }, 18 | "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", 19 | "author": { 20 | "name": "Eclipse GLSP" 21 | }, 22 | "contributors": [ 23 | { 24 | "name": "Eclipse GLSP Project", 25 | "email": "glsp-dev@eclipse.org", 26 | "url": "https://projects.eclipse.org/projects/ecd.glsp" 27 | } 28 | ], 29 | "main": "lib/index", 30 | "types": "lib/index", 31 | "files": [ 32 | "lib", 33 | "src", 34 | "css" 35 | ], 36 | "scripts": { 37 | "build": "tsc -b", 38 | "clean": "rimraf lib tsconfig.tsbuildinfo ", 39 | "generate:index": "glsp generateIndex src -s -f", 40 | "lint": "eslint --ext .ts,.tsx ./src", 41 | "watch": "tsc -w" 42 | }, 43 | "dependencies": { 44 | "@eclipse-glsp/client": "next", 45 | "vscode-jsonrpc": "8.2.0", 46 | "vscode-messenger-webview": "^0.4.5" 47 | }, 48 | "devDependencies": { 49 | "reflect-metadata": "^0.1.13" 50 | }, 51 | "publishConfig": { 52 | "access": "public" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/default-modules.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { ModuleConfiguration, contextMenuModule } from '@eclipse-glsp/client'; 18 | import { vscodeCopyPasteModule } from './features/copyPaste/copy-paste-module'; 19 | import { vscodeDefaultModule } from './features/default/default-module'; 20 | import { vscodeExportModule } from './features/export/export-module'; 21 | import { vscodeNavigationModule } from './features/navigation/navigation-module'; 22 | import { vscodeNotificationModule } from './features/notification/notification-module'; 23 | 24 | export const VSCODE_DEFAULT_MODULES = [ 25 | vscodeDefaultModule, 26 | vscodeCopyPasteModule, 27 | vscodeExportModule, 28 | vscodeNavigationModule, 29 | vscodeNotificationModule 30 | ] as const; 31 | 32 | export const VSCODE_DEFAULT_MODULE_CONFIG: ModuleConfiguration = { 33 | add: [...VSCODE_DEFAULT_MODULES], 34 | remove: [contextMenuModule] 35 | }; 36 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/diagram-identifier.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { AnyObject, hasStringProp } from '@eclipse-glsp/client'; 17 | 18 | export const GLSPDiagramIdentifier = Symbol('GLSPDiagramIdentifier'); 19 | 20 | export interface GLSPDiagramIdentifier { 21 | clientId: string; 22 | diagramType: string; 23 | uri: string; 24 | } 25 | 26 | export function isDiagramIdentifier(object: any): object is GLSPDiagramIdentifier { 27 | return ( 28 | AnyObject.is(object) && // 29 | hasStringProp(object, 'clientId') && 30 | hasStringProp(object, 'diagramType') && 31 | hasStringProp(object, 'uri') 32 | ); 33 | } 34 | 35 | // ---------------------------------- 36 | // Initial Handshake 37 | 38 | export interface WebviewReadyMessage { 39 | readyMessage: string; 40 | } 41 | 42 | export namespace WebviewReadyMessage { 43 | export function is(object: unknown): object is WebviewReadyMessage { 44 | return AnyObject.is(object) && hasStringProp(object, 'readyMessage'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/copyPaste/copy-paste-module.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { FeatureModule, ICopyPasteHandler, TYPES, bindAsService, copyPasteModule } from '@eclipse-glsp/client'; 18 | import { CopyPasteHandlerProvider, CopyPasteStartup } from './copy-paste-startup'; 19 | 20 | export const vscodeCopyPasteModule = new FeatureModule( 21 | bind => { 22 | bind(CopyPasteHandlerProvider).toProvider( 23 | ctx => () => new Promise(resolve => resolve(ctx.container.get(TYPES.ICopyPasteHandler))) 24 | ); 25 | bindAsService(bind, TYPES.IDiagramStartup, CopyPasteStartup); 26 | }, 27 | { requires: copyPasteModule, featureId: Symbol('vscodeCopyPaste') } 28 | ); 29 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/copyPaste/copy-paste-startup.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { ICopyPasteHandler, IDiagramStartup, MaybePromise } from '@eclipse-glsp/client'; 18 | import { inject, injectable } from 'inversify'; 19 | 20 | export const CopyPasteHandlerProvider = Symbol('CopyPasteHandlerProvider'); 21 | /** 22 | * Service identifier and type definition to bind the {@link ICopyPasteHandler} to an provider. 23 | * This enables asynchronous injections and can be used to bypass circular dependency issues. 24 | */ 25 | export type CopyPasteHandlerProvider = () => Promise; 26 | 27 | /** 28 | * Startup service to hook up the copy&paste event handler 29 | */ 30 | @injectable() 31 | export class CopyPasteStartup implements IDiagramStartup { 32 | @inject(CopyPasteHandlerProvider) 33 | protected copyPasteHandlerProvider: CopyPasteHandlerProvider; 34 | 35 | preInitialize(): MaybePromise { 36 | this.copyPasteHandlerProvider().then(copyPasteHandler => { 37 | document.addEventListener('copy', (e: ClipboardEvent) => { 38 | copyPasteHandler.handleCopy(e); 39 | }); 40 | 41 | document.addEventListener('cut', (e: ClipboardEvent) => { 42 | copyPasteHandler.handleCut(e); 43 | }); 44 | 45 | document.addEventListener('paste', (e: ClipboardEvent) => { 46 | copyPasteHandler.handlePaste(e); 47 | }); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/default/default-module.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { FeatureModule, SelectAction, TYPES, bindAsService, defaultModule } from '@eclipse-glsp/client'; 18 | import { GLSPDiagramWidget, GLSPDiagramWidgetFactory } from '../../glsp-diagram-widget'; 19 | import { ExtensionActionKind, HostExtensionActionHandler } from './extension-action-handler'; 20 | 21 | export const vscodeDefaultModule = new FeatureModule( 22 | bind => { 23 | bind(GLSPDiagramWidget).toSelf().inSingletonScope(); 24 | bind(GLSPDiagramWidgetFactory).toFactory(context => () => context.container.get(GLSPDiagramWidget)); 25 | bindAsService(bind, TYPES.IActionHandlerInitializer, HostExtensionActionHandler); 26 | bind(ExtensionActionKind).toConstantValue(SelectAction.KIND); 27 | }, 28 | { requires: defaultModule, featureId: Symbol('vscodeDefault') } 29 | ); 30 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/default/extension-action-handler.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { 17 | Action, 18 | ActionHandlerRegistry, 19 | GLSPClient, 20 | IActionHandler, 21 | IActionHandlerInitializer, 22 | ICommand, 23 | IDiagramOptions, 24 | TYPES 25 | } from '@eclipse-glsp/client'; 26 | import { inject, injectable, multiInject, optional, postConstruct } from 'inversify'; 27 | 28 | /** 29 | * Service identifier to define action kinds that should be delegated to the vscode extension (when locally dispatched) 30 | * 31 | * Usage: 32 | * ```ts 33 | * bind(ExtensionActionKind).toConstantValue(SomeAction.KIND) 34 | * ``` 35 | */ 36 | export const ExtensionActionKind = Symbol('ExtensionActionKind'); 37 | 38 | /** 39 | * Delegates actions that should be handled inside of the host extension instead 40 | * of the webview. This enables the implementation of action handlers that require access 41 | * to the vscode API. 42 | */ 43 | @injectable() 44 | export class HostExtensionActionHandler implements IActionHandler, IActionHandlerInitializer { 45 | @multiInject(ExtensionActionKind) 46 | @optional() 47 | protected actionKinds: string[] = []; 48 | 49 | @inject(TYPES.IDiagramOptions) 50 | protected diagramOptions: IDiagramOptions; 51 | 52 | protected glspClient?: GLSPClient; 53 | 54 | @postConstruct() 55 | protected postConstruct(): void { 56 | this.diagramOptions.glspClientProvider().then(glspClient => (this.glspClient = glspClient)); 57 | } 58 | 59 | initialize(registry: ActionHandlerRegistry): void { 60 | this.actionKinds.forEach(kind => registry.register(kind, this)); 61 | } 62 | 63 | handle(action: Action): void | Action | ICommand { 64 | if (this.actionKinds.includes(action.kind)) { 65 | const message = { 66 | clientId: this.diagramOptions.clientId, 67 | action 68 | }; 69 | this.glspClient?.sendActionMessage(message); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/default/vscode-glsp-modelsource.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | /* eslint-disable deprecation/deprecation */ 17 | import { Action, GLSPModelSource } from '@eclipse-glsp/client'; 18 | import { injectable } from 'inversify'; 19 | 20 | /** 21 | * A helper interface that allows the webview to mark actions that have been received directly from the vscode extension 22 | * (i.e. they are not forwarded to the GLSP Server). 23 | * 24 | * @deprecated The concept of marking actions as locally dispatched `ExtensionAction`s is no longer necessary and usage is discouraged. 25 | */ 26 | export interface ExtensionAction extends Action { 27 | __localDispatch: true; 28 | } 29 | 30 | export namespace ExtensionAction { 31 | /** 32 | * @deprecated The concept of marking actions as locally dispatched `ExtensionAction`s is no longer necessary and usage is discouraged. 33 | * */ 34 | export function is(object: unknown): object is ExtensionAction { 35 | return Action.is(object) && '__localDispatch' in object && object.__localDispatch === true; 36 | } 37 | 38 | /** 39 | * Mark the given action as {@link ServerAction} by attaching the "_receivedFromServer" property 40 | * @param action The action that should be marked as server action 41 | * 42 | * @deprecated The concept of marking actions as locally dispatched `ExtensionAction`s is no longer necessary and usage is discouraged. 43 | */ 44 | export function mark(action: Action): void { 45 | (action as ExtensionAction).__localDispatch = true; 46 | } 47 | } 48 | 49 | /** 50 | * Customization of the default {@link GLSPModelSource} for the vscode integration. 51 | * Also takes locally dispatched actions (i.e. actions that are originating from or intended for the host extension) into consideration. 52 | * 53 | * @deprecated A customized model source is no longer necessary. Use the default {@link GLSPModelSource} instead. 54 | */ 55 | @injectable() 56 | export class VsCodeGLSPModelSource extends GLSPModelSource {} 57 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/export/export-module.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { ExportSvgAction, FeatureModule, exportModule } from '@eclipse-glsp/client'; 18 | import { ExtensionActionKind } from '../default/extension-action-handler'; 19 | 20 | export const vscodeExportModule = new FeatureModule( 21 | bind => { 22 | bind(ExtensionActionKind).toConstantValue(ExportSvgAction.KIND); 23 | }, 24 | { requires: exportModule, featureId: Symbol('vscodeExport') } 25 | ); 26 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/navigation/navigation-module.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { FeatureModule, NavigateToExternalTargetAction, navigationModule } from '@eclipse-glsp/client'; 18 | import { ExtensionActionKind } from '../default/extension-action-handler'; 19 | 20 | export const vscodeNavigationModule = new FeatureModule( 21 | bind => { 22 | bind(ExtensionActionKind).toConstantValue(NavigateToExternalTargetAction.KIND); 23 | }, 24 | { requires: navigationModule, featureId: Symbol('vscodeNavigation') } 25 | ); 26 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/features/notification/notification-module.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { EndProgressAction, FeatureModule, MessageAction, StartProgressAction, UpdateProgressAction } from '@eclipse-glsp/client'; 18 | import { ExtensionActionKind } from '../default/extension-action-handler'; 19 | 20 | export const vscodeNotificationModule = new FeatureModule( 21 | bind => { 22 | bind(ExtensionActionKind).toConstantValue(MessageAction.KIND); 23 | bind(ExtensionActionKind).toConstantValue(StartProgressAction.KIND); 24 | bind(ExtensionActionKind).toConstantValue(EndProgressAction.KIND); 25 | bind(ExtensionActionKind).toConstantValue(UpdateProgressAction.KIND); 26 | }, 27 | { featureId: Symbol('vscodeNotification') } 28 | ); 29 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/glsp-diagram-widget.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2018-2024 TypeFox and others. 3 | * Modifications: (c) 2020-2023 EclipseSource and others. 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0 which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the Eclipse 11 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 12 | * with the GNU Classpath Exception which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | ********************************************************************************/ 17 | // based on https://github.com/eclipse-sprotty/sprotty-vscode/blob/v0.3.0/sprotty-vscode-webview/src/vscode-diagram-widget.ts 18 | import { 19 | DiagramLoader, 20 | DiagramLoadingOptions, 21 | FocusStateChangedAction, 22 | IActionDispatcher, 23 | IDiagramOptions, 24 | ModelSource, 25 | TYPES, 26 | ViewerOptions 27 | } from '@eclipse-glsp/client'; 28 | import { inject, injectable, postConstruct } from 'inversify'; 29 | export const GLSPDiagramWidgetFactory = Symbol('GLSPDiagramWidgetFactory'); 30 | export type GLSPDiagramWidgetFactory = () => GLSPDiagramWidget; 31 | 32 | @injectable() 33 | export abstract class GLSPDiagramWidget { 34 | @inject(TYPES.IActionDispatcher) 35 | protected actionDispatcher: IActionDispatcher; 36 | 37 | @inject(TYPES.ModelSource) 38 | protected modelSource: ModelSource; 39 | 40 | @inject(TYPES.IDiagramOptions) 41 | protected diagramOptions: IDiagramOptions; 42 | 43 | @inject(TYPES.ViewerOptions) 44 | protected viewerOptions: ViewerOptions; 45 | 46 | @inject(DiagramLoader) 47 | protected diagramLoader: DiagramLoader; 48 | 49 | get clientId(): string { 50 | return this.diagramOptions.clientId; 51 | } 52 | 53 | protected containerDiv: HTMLDivElement | undefined; 54 | 55 | @postConstruct() 56 | initialize(): void { 57 | this.initializeHtml(); 58 | this.loadDiagram(); 59 | } 60 | 61 | protected initializeHtml(): void { 62 | const containerDiv = document.getElementById(this.clientId + '_container') as HTMLDivElement; 63 | if (containerDiv) { 64 | const svgContainer = document.createElement('div'); 65 | svgContainer.id = this.viewerOptions.baseDiv; 66 | containerDiv.appendChild(svgContainer); 67 | 68 | const hiddenContainer = document.createElement('div'); 69 | hiddenContainer.id = this.viewerOptions.hiddenDiv; 70 | document.body.appendChild(hiddenContainer); 71 | this.containerDiv = containerDiv; 72 | containerDiv.addEventListener('mouseenter', e => this.handleMouseEnter(e)); 73 | containerDiv.addEventListener('mouseleave', e => this.handleMouseLeave(e)); 74 | window.addEventListener('focus', e => this.handleFocusChange(e, true)); 75 | window.addEventListener('blur', e => this.handleFocusChange(e, false)); 76 | window.addEventListener('contextmenu', e => this.handleContextMenu(e)); 77 | } 78 | } 79 | 80 | handleContextMenu(e: MouseEvent): void { 81 | // Prevent the default context menu for now 82 | // Should be removed once we provide a proper context menu integration 83 | e.preventDefault(); 84 | window.focus(); 85 | } 86 | 87 | handleMouseEnter(e: MouseEvent): void { 88 | this.containerDiv?.classList.add('mouse-enter'); 89 | this.containerDiv?.classList.remove('mouse-leave'); 90 | } 91 | 92 | handleMouseLeave(e: MouseEvent): void { 93 | this.containerDiv?.classList.add('mouse-leave'); 94 | this.containerDiv?.classList.remove('mouse-enter'); 95 | } 96 | 97 | handleFocusChange(e: FocusEvent, hasFocus: boolean): void { 98 | this.actionDispatcher.dispatch(FocusStateChangedAction.create(hasFocus)); 99 | } 100 | 101 | protected createDiagramLoadingOptions(): DiagramLoadingOptions | undefined { 102 | return undefined; 103 | } 104 | 105 | loadDiagram(): Promise { 106 | return this.diagramLoader.load(this.createDiagramLoadingOptions()); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/glsp-starter.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2018-2024 TypeFox and others. 3 | * Modifications: (c) 2020-2023 EclipseSource and others. 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0 which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the Eclipse 11 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 12 | * with the GNU Classpath Exception which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | ********************************************************************************/ 17 | // based on https://github.com/eclipse-sprotty/sprotty-vscode/blob/v0.3.0/sprotty-vscode-webview/src/sprotty-starter.ts 18 | import { ContainerConfiguration, createDiagramOptionsModule } from '@eclipse-glsp/client'; 19 | import { Container, ContainerModule } from 'inversify'; 20 | import { HOST_EXTENSION, NotificationType } from 'vscode-messenger-common'; 21 | import { Messenger, VsCodeApi } from 'vscode-messenger-webview'; 22 | import { VSCODE_DEFAULT_MODULE_CONFIG } from './default-modules'; 23 | import { GLSPDiagramIdentifier } from './diagram-identifier'; 24 | import { GLSPDiagramWidget } from './glsp-diagram-widget'; 25 | import { WebviewGlspClient } from './webview-glsp-client'; 26 | export const WebviewReadyNotification: NotificationType = { method: 'ready' }; 27 | export const InitializeNotification: NotificationType = { method: 'initialize' }; 28 | 29 | declare function acquireVsCodeApi(): VsCodeApi; 30 | 31 | export abstract class GLSPStarter { 32 | protected container?: Container; 33 | protected messenger: Messenger; 34 | 35 | constructor() { 36 | this.messenger = new Messenger(acquireVsCodeApi()); 37 | this.messenger.onNotification(InitializeNotification, identifier => 38 | this.acceptDiagramIdentifier(identifier) 39 | ); 40 | this.messenger.start(); 41 | this.sendReadyMessage(); 42 | } 43 | 44 | protected sendReadyMessage(): void { 45 | this.messenger.sendNotification(WebviewReadyNotification, HOST_EXTENSION); 46 | } 47 | 48 | protected acceptDiagramIdentifier(identifier: GLSPDiagramIdentifier): void { 49 | if (this.container) { 50 | const oldIdentifier = this.container.get(GLSPDiagramIdentifier); 51 | oldIdentifier.diagramType = identifier.diagramType; 52 | oldIdentifier.uri = identifier.uri; 53 | const diagramWidget = this.container.get(GLSPDiagramWidget); 54 | diagramWidget.loadDiagram(); 55 | } else { 56 | const diagramModule = this.createDiagramOptionsModule(identifier); 57 | this.container = this.createContainer(diagramModule, ...this.getContainerConfiguration()); 58 | this.addVscodeBindings?.(this.container, identifier); 59 | this.container.get(GLSPDiagramWidget); 60 | } 61 | } 62 | 63 | protected createDiagramOptionsModule(identifier: GLSPDiagramIdentifier): ContainerModule { 64 | const glspClient = new WebviewGlspClient({ id: identifier.diagramType, messenger: this.messenger }); 65 | return createDiagramOptionsModule({ 66 | clientId: identifier.clientId, 67 | diagramType: identifier.diagramType, 68 | glspClientProvider: async () => glspClient, 69 | sourceUri: decodeURIComponent(identifier.uri) 70 | }); 71 | } 72 | 73 | /** 74 | * Retrieves additional {@link ContainerConfiguration} for the diagram container. 75 | * Typically this composes a set of vscode specific customization modules. 76 | * @returns the container configuration 77 | */ 78 | protected getContainerConfiguration(): ContainerConfiguration { 79 | return [VSCODE_DEFAULT_MODULE_CONFIG]; 80 | } 81 | 82 | protected abstract createContainer(...containerConfiguration: ContainerConfiguration): Container; 83 | 84 | /** 85 | * Optional hook that can be implemented to customize diagram container bindings before it's used 86 | * to instantiate the diagram services 87 | * @param container The diagram container 88 | * @param diagramIdentifier The diagram identfier 89 | */ 90 | protected addVscodeBindings?(container: Container, diagramIdentifier: GLSPDiagramIdentifier): void; 91 | } 92 | 93 | export function decodeURI(uri: string): string { 94 | return decodeURIComponent(uri.replace(/\+/g, ' ')); 95 | } 96 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/index.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2020-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | export * from './default-modules'; 18 | export * from './diagram-identifier'; 19 | export * from './features/copyPaste/copy-paste-module'; 20 | export * from './features/copyPaste/copy-paste-startup'; 21 | export * from './features/default/default-module'; 22 | export * from './features/default/extension-action-handler'; 23 | export * from './features/default/vscode-glsp-modelsource'; 24 | export * from './features/export/export-module'; 25 | export * from './features/navigation/navigation-module'; 26 | export * from './features/notification/notification-module'; 27 | export * from './glsp-diagram-widget'; 28 | export * from './glsp-starter'; 29 | export * from './webview-glsp-client'; 30 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/src/webview-glsp-client.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { 18 | Action, 19 | ActionMessage, 20 | ActionMessageHandler, 21 | ClientState, 22 | Disposable, 23 | DisposableCollection, 24 | DisposeClientSessionParameters, 25 | Emitter, 26 | Event, 27 | GLSPClient, 28 | InitializeClientSessionParameters, 29 | InitializeParameters, 30 | InitializeResult 31 | } from '@eclipse-glsp/client'; 32 | import { HOST_EXTENSION, NotificationType, RequestType } from 'vscode-messenger-common'; 33 | import { Messenger } from 'vscode-messenger-webview'; 34 | 35 | export interface WebviewGlspClientOptions extends GLSPClient.Options { 36 | messenger?: Messenger; 37 | } 38 | 39 | export const ActionMessageNotification: NotificationType = { method: 'actionMessage' }; 40 | export const ClientStateChangeNotification: NotificationType = { method: 'notifyClientStateChange' }; 41 | export const StartRequest: RequestType = { method: 'start' }; 42 | export const InitializeServerRequest: RequestType = { method: 'initializeServer' }; 43 | export const InitializeClientSessionRequest: RequestType = { method: 'initializeClientSession' }; 44 | export const DisposeClientSessionRequest: RequestType = { method: 'disposeClientSession' }; 45 | export const ShutdownServerNotification: NotificationType = { method: 'shutdownServer' }; 46 | export const StopRequest: RequestType = { method: 'stop' }; 47 | /** 48 | * GLSP client implementation for the diagram webview. This is proxy implementation 49 | * that communicates with the actual GLSP client running in the host extension. 50 | * via the vscode-messenger protocol 51 | */ 52 | export class WebviewGlspClient implements GLSPClient, Disposable { 53 | readonly id: string; 54 | protected messenger: Messenger; 55 | protected toDispose = new DisposableCollection(); 56 | protected onActionMessageEmitter = new Emitter(); 57 | 58 | protected onCurrentStateChangedEmitter = new Emitter(); 59 | get onCurrentStateChanged(): Event { 60 | return this.onCurrentStateChangedEmitter.event; 61 | } 62 | 63 | protected _currentState: ClientState = ClientState.Initial; 64 | 65 | get currentState(): ClientState { 66 | return this._currentState; 67 | } 68 | 69 | protected _initializeResult?: InitializeResult; 70 | get initializeResult(): InitializeResult | undefined { 71 | return this._initializeResult; 72 | } 73 | 74 | protected onServerInitializedEmitter = new Emitter(); 75 | get onServerInitialized(): Event { 76 | return this.onServerInitializedEmitter.event; 77 | } 78 | 79 | constructor(options: WebviewGlspClientOptions) { 80 | this.id = options.id; 81 | this.messenger = options.messenger ?? new Messenger(); 82 | this.toDispose.push(this.onActionMessageEmitter, this.onServerInitializedEmitter, this.onCurrentStateChangedEmitter); 83 | this.messenger.onNotification(ActionMessageNotification, msg => this.onActionMessageEmitter.fire(msg)); 84 | this.messenger.onNotification(ClientStateChangeNotification, state => this.updateState(state)); 85 | } 86 | 87 | protected updateState(state: ClientState): void { 88 | if (this._currentState !== state) { 89 | this._currentState = state; 90 | this.onCurrentStateChangedEmitter.fire(this._currentState); 91 | } 92 | } 93 | 94 | async start(): Promise { 95 | try { 96 | await this.messenger.sendRequest(StartRequest, HOST_EXTENSION); 97 | } catch (error) { 98 | console.error('Failed to start connection to server', error); 99 | this.updateState(ClientState.StartFailed); 100 | } 101 | } 102 | 103 | async initializeServer(params: InitializeParameters): Promise { 104 | if (this.initializeResult) { 105 | return this.initializeResult; 106 | } 107 | const result = await this.messenger.sendRequest(InitializeServerRequest, HOST_EXTENSION, params); 108 | this._initializeResult = result; 109 | this.onServerInitializedEmitter.fire(result); 110 | return result; 111 | } 112 | 113 | initializeClientSession(params: InitializeClientSessionParameters): Promise { 114 | return this.messenger.sendRequest(InitializeClientSessionRequest, HOST_EXTENSION, params); 115 | } 116 | 117 | disposeClientSession(params: DisposeClientSessionParameters): Promise { 118 | return this.messenger.sendRequest(DisposeClientSessionRequest, HOST_EXTENSION, params); 119 | } 120 | 121 | shutdownServer(): void { 122 | this.messenger.sendNotification(ShutdownServerNotification, HOST_EXTENSION); 123 | } 124 | 125 | async stop(): Promise { 126 | if (this.currentState === ClientState.Stopped) { 127 | return; 128 | } 129 | await this.messenger.sendRequest(StopRequest, HOST_EXTENSION); 130 | } 131 | 132 | sendActionMessage(message: ActionMessage): void { 133 | this.messenger.sendNotification(ActionMessageNotification, HOST_EXTENSION, message); 134 | } 135 | 136 | onActionMessage(handler: ActionMessageHandler): Disposable { 137 | return this.onActionMessageEmitter.event(handler); 138 | } 139 | 140 | dispose(): void { 141 | this.toDispose.dispose(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /packages/vscode-integration-webview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config", 3 | "compilerOptions": { 4 | "composite": true, 5 | "rootDir": "src", 6 | "outDir": "lib" 7 | }, 8 | "include": ["src"], 9 | "references": [ 10 | { 11 | "path": "../vscode-integration" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/vscode-integration/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: '../../.eslintrc.js', 4 | rules: { 5 | 'import/no-unresolved': 'off' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /packages/vscode-integration/README.md: -------------------------------------------------------------------------------- 1 | # Eclipse GLSP VSCode Integration 2 | 3 | This package contains the glue code for integrating [GLSP](https://www.eclipse.org/glsp/) diagrams in VS Code. 4 | This library enables the implementation of GLSP Diagram editors for VS Code base on the [Custom Editor API](https://code.visualstudio.com/api/extension-guides/custom-editors). 5 | 6 | ## Where to find the sources? 7 | 8 | In addition to this repository, the related source code can be found here: 9 | 10 | - 11 | - 12 | - 13 | 14 | ## More information 15 | 16 | For more information, please visit the [Eclipse GLSP Umbrella repository](https://github.com/eclipse-glsp/glsp) and the [Eclipse GLSP Website](https://www.eclipse.org/glsp/). 17 | If you have questions, please raise them in the [discussions](https://github.com/eclipse-glsp/glsp/discussions) and have a look at our [communication and support options](https://www.eclipse.org/glsp/contact/). 18 | -------------------------------------------------------------------------------- /packages/vscode-integration/browser.d.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from './lib/browser/index'; 17 | -------------------------------------------------------------------------------- /packages/vscode-integration/browser.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 'use strict'; 17 | 18 | module.exports = require('./lib/browser/index'); 19 | -------------------------------------------------------------------------------- /packages/vscode-integration/node.d.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from './lib/node/index'; 17 | -------------------------------------------------------------------------------- /packages/vscode-integration/node.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 'use strict'; 17 | 18 | module.exports = require('./lib/node/index'); 19 | -------------------------------------------------------------------------------- /packages/vscode-integration/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@eclipse-glsp/vscode-integration", 3 | "displayName": "GLSP VSCode Integration", 4 | "version": "2.5.0", 5 | "description": "Glue code to integrate GLSP diagrams in VSCode extensions (extension part)", 6 | "keywords": [ 7 | "eclipse", 8 | "vscode-extension", 9 | "glsp", 10 | "modeling" 11 | ], 12 | "homepage": "https://www.eclipse.org/glsp/", 13 | "bugs": "https://github.com/eclipse-glsp/glsp/issues", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/eclipse-glsp/glsp-vscode-integration.git" 17 | }, 18 | "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", 19 | "author": { 20 | "name": "Eclipse GLSP" 21 | }, 22 | "contributors": [ 23 | { 24 | "name": "Eclipse GLSP Project", 25 | "email": "glsp-dev@eclipse.org", 26 | "url": "https://projects.eclipse.org/projects/ecd.glsp" 27 | } 28 | ], 29 | "main": "lib/node/index", 30 | "browser": { 31 | "lib/node/index": "lib/browser/index" 32 | }, 33 | "files": [ 34 | "lib", 35 | "src", 36 | "node.js", 37 | "node.d.ts", 38 | "browser.d.ts", 39 | "browser.js" 40 | ], 41 | "scripts": { 42 | "build": "tsc -b", 43 | "clean": "rimraf lib tsconfig.tsbuildinfo ", 44 | "generate:index": "glsp generateIndex src/browser src/common src/node -s -f", 45 | "lint": "eslint --ext .ts,.tsx ./src", 46 | "watch": "tsc -w" 47 | }, 48 | "dependencies": { 49 | "@eclipse-glsp/protocol": "next", 50 | "vscode-jsonrpc": "8.2.0", 51 | "vscode-messenger": "^0.4.5", 52 | "ws": "^8.13.0" 53 | }, 54 | "devDependencies": { 55 | "@types/vscode": "^1.54.0", 56 | "@types/ws": "^8.5.4" 57 | }, 58 | "engines": { 59 | "vscode": "^1.54.0" 60 | }, 61 | "publishConfig": { 62 | "access": "public" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/browser/index.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | export * from './quickstart-components/browser-glsp-vscode-server'; 18 | export * from './quickstart-components/websocket-glsp-vscode-server'; 19 | export * from './re-export'; 20 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/browser/quickstart-components/browser-glsp-vscode-server.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { BaseGLSPClient, GLSPClientProxy, GLSPServer } from '@eclipse-glsp/protocol'; 17 | import { ContainerConfiguration, initializeContainer } from '@eclipse-glsp/protocol/lib/di'; 18 | import { Container, ContainerModule } from 'inversify'; 19 | import { BaseGlspVscodeServer, GlspVscodeServerOptions } from '../../common/quickstart-components/base-glsp-vscode-server'; 20 | 21 | export interface BrowserGlspVscodeServerOptions extends GlspVscodeServerOptions { 22 | /** The server DI modules*/ 23 | readonly serverModules: ContainerModule[]; 24 | } 25 | 26 | /** 27 | * This component can be used to bootstrap your extension when using the typescript 28 | * GLSP server implementation directly in a web extension without a dedicated webworker, which you can find here: 29 | * https://github.com/eclipse-glsp/glsp-server-node 30 | * 31 | * It sets up a a server running directly in the extension context and 32 | * provides an interface, ready to be used by the `GlspVscodeConnector` for the 33 | * GLSP-VSCode integration. 34 | */ 35 | export class BrowserGlspVscodeServer extends BaseGlspVscodeServer { 36 | protected serverContainer: Container; 37 | 38 | constructor(protected override readonly options: BrowserGlspVscodeServerOptions) { 39 | super(options); 40 | } 41 | 42 | override createGLSPClient(): BaseGLSPClient { 43 | const client = new BaseGLSPClient({ 44 | id: this.options.clientId 45 | }); 46 | const proxyModule = new ContainerModule(bind => { 47 | bind(GLSPClientProxy).toConstantValue(client.proxy); 48 | }); 49 | this.serverContainer = this.createContainer(proxyModule); 50 | const server = this.serverContainer.get(GLSPServer); 51 | client.configureServer(server); 52 | return client; 53 | } 54 | 55 | protected createContainer(...additionalConfiguration: ContainerConfiguration): Container { 56 | const container = new Container(); 57 | return initializeContainer(container, ...this.options.serverModules, ...additionalConfiguration); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/browser/quickstart-components/websocket-glsp-vscode-server.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { BaseJsonrpcGLSPClient, listen } from '@eclipse-glsp/protocol'; 17 | import { MessageConnection } from 'vscode-jsonrpc'; 18 | import { BaseGlspVscodeServer, GlspVscodeServerOptions } from '../../common'; 19 | 20 | export interface WebsocketGlspVscodeServerOptions extends GlspVscodeServerOptions { 21 | /** (Web)socket connection options of the running server. */ 22 | readonly connectionOptions: WebSocketConnectionOptions; 23 | } 24 | 25 | export type WebSocketConnectionOptions = 26 | /* Socket connection options*/ 27 | | { 28 | /** Address of the server websocket endpoint */ 29 | webSocketAddress: string; 30 | } 31 | | { 32 | /** Server websocket port */ 33 | port: number; 34 | /** Server hostname. Default is 'localhost' */ 35 | host?: string; 36 | /** Websocket endpoint path*/ 37 | path: string; 38 | /** The websocket protocol used by the server. Default is 'ws' */ 39 | protocol?: 'ws' | 'wss'; 40 | }; 41 | 42 | /** 43 | * This component can be used to bootstrap your extension when using an external 44 | * GLSP server implementation that communicates via WebSocket connection 45 | * 46 | * It sets up a JSON-RPC connection to a server running on a specified port and 47 | * provides an interface, ready to be used by the `GlspVscodeConnector` for the 48 | * GLSP-VSCode integration. 49 | */ 50 | export class WebSocketGlspVscodeServer extends BaseGlspVscodeServer { 51 | constructor(protected override readonly options: WebsocketGlspVscodeServerOptions) { 52 | super(options); 53 | } 54 | 55 | protected getWebSocketAddress(): string | undefined { 56 | const opts = this.options.connectionOptions; 57 | if ('webSocketAddress' in opts) { 58 | return opts.webSocketAddress; 59 | } 60 | const protocol = opts.protocol ?? 'ws'; 61 | const host = opts.host ?? 'localhost'; 62 | return `${protocol}://${host}:${opts.port}/${opts.path}`; 63 | } 64 | 65 | override async createGLSPClient(): Promise { 66 | const connection = await this.createConnection(); 67 | this.toDispose.push(connection); 68 | return new BaseJsonrpcGLSPClient({ 69 | id: this.options.clientId, 70 | connectionProvider: connection 71 | }); 72 | } 73 | 74 | protected async createConnection(): Promise { 75 | const webSocketAddress = this.getWebSocketAddress(); 76 | if (!webSocketAddress || !isValidWebSocketAddress(webSocketAddress)) { 77 | throw new Error(`Could not connect to to GLSP Server. The WebSocket address is invalid: '${webSocketAddress}'`); 78 | } 79 | 80 | return this.createWebSocketConnection(webSocketAddress); 81 | } 82 | 83 | protected createWebSocketConnection(address: string): Promise { 84 | const webSocket = new WebSocket(address); 85 | return listen(webSocket); 86 | } 87 | } 88 | 89 | export function isValidWebSocketAddress(address: string): boolean { 90 | try { 91 | const { protocol } = new URL(address); 92 | return protocol === 'ws:' || protocol === 'wss:'; 93 | } catch (error) { 94 | return false; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/browser/re-export.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from '../common'; 17 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/client-actions.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | 17 | import { Action, Args, hasStringProp } from '@eclipse-glsp/protocol'; 18 | 19 | export interface NavigateAction extends Action { 20 | kind: typeof NavigateAction.KIND; 21 | readonly targetTypeId: string; 22 | readonly args?: Args; 23 | } 24 | 25 | export namespace NavigateAction { 26 | export const KIND = 'navigate'; 27 | 28 | export function is(object: any): object is NavigateAction { 29 | return Action.hasKind(object, KIND) && hasStringProp(object, 'targetTypeId'); 30 | } 31 | 32 | export function create(targetTypeId: string, options: { args?: Args } = {}): NavigateAction { 33 | return { 34 | kind: KIND, 35 | targetTypeId, 36 | ...options 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/index.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from './client-actions'; 17 | export * from './glsp-vscode-connector'; 18 | export * from './quickstart-components/base-glsp-vscode-server'; 19 | export * from './quickstart-components/configuration-util'; 20 | export * from './quickstart-components/glsp-editor-provider'; 21 | export * from './quickstart-components/webview-endpoint'; 22 | export * from './re-export'; 23 | export * from './types'; 24 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/quickstart-components/base-glsp-vscode-server.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { 17 | ActionMessage, 18 | ApplicationIdProvider, 19 | Deferred, 20 | DisposableCollection, 21 | GLSPClient, 22 | InitializeParameters, 23 | InitializeResult, 24 | MaybePromise 25 | } from '@eclipse-glsp/protocol'; 26 | import * as vscode from 'vscode'; 27 | import { GlspVscodeServer } from '../types'; 28 | 29 | export interface GlspVscodeServerOptions { 30 | /** Client ID to register the jsonRPC client with on the server. */ 31 | readonly clientId: string; 32 | /** Name to register the client with on the server. */ 33 | readonly clientName: string; 34 | } 35 | 36 | /** 37 | * Reusable base class for {@link GlspVscodeServer} implementations 38 | */ 39 | export abstract class BaseGlspVscodeServer implements GlspVscodeServer, vscode.Disposable { 40 | readonly onSendToServerEmitter = new vscode.EventEmitter(); 41 | 42 | protected readonly onServerSendEmitter = new vscode.EventEmitter(); 43 | get onServerMessage(): vscode.Event { 44 | return this.onServerSendEmitter.event; 45 | } 46 | 47 | protected readyDeferred = new Deferred(); 48 | protected _initializeResult: InitializeResult; 49 | protected _glspClient: C; 50 | protected toDispose = new DisposableCollection(); 51 | 52 | constructor(protected readonly options: GlspVscodeServerOptions) { 53 | this.onSendToServerEmitter.event(message => { 54 | this.onReady.then(() => { 55 | if (ActionMessage.is(message)) { 56 | this._glspClient.sendActionMessage(message); 57 | } 58 | }); 59 | }); 60 | this.toDispose.push(this.onSendToServerEmitter, this.onServerSendEmitter); 61 | } 62 | 63 | /** 64 | * Creates and configues the {@link GLSPClient} instance. 65 | */ 66 | abstract createGLSPClient(): MaybePromise; 67 | 68 | async start(): Promise { 69 | try { 70 | this._glspClient = await this.createGLSPClient(); 71 | await this._glspClient.start(); 72 | const parameters = await this.createInitializeParameters(); 73 | this._initializeResult = await this._glspClient.initializeServer(parameters); 74 | 75 | this._glspClient.onActionMessage(message => { 76 | this.onServerSendEmitter.fire(message); 77 | }); 78 | 79 | this.readyDeferred.resolve(); 80 | } catch (error) { 81 | this.readyDeferred.reject(error); 82 | } 83 | } 84 | 85 | protected async createInitializeParameters(): Promise { 86 | return { 87 | applicationId: ApplicationIdProvider.get(), 88 | protocolVersion: GLSPClient.protocolVersion 89 | }; 90 | } 91 | 92 | get onReady(): Promise { 93 | return this.readyDeferred.promise; 94 | } 95 | 96 | get initializeResult(): Promise { 97 | return this.onReady.then(() => this._initializeResult); 98 | } 99 | 100 | get glspClient(): Promise { 101 | return this.onReady.then(() => this._glspClient); 102 | } 103 | 104 | dispose(): void { 105 | this.toDispose.dispose(); 106 | if (this._glspClient) { 107 | this._glspClient.stop(); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/quickstart-components/configuration-util.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2022-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { CenterAction, FitToScreenAction, LayoutOperation, RequestExportSvgAction, SelectAllAction } from '@eclipse-glsp/protocol'; 17 | import * as vscode from 'vscode'; 18 | import { GlspVscodeConnector, SelectionState } from '../glsp-vscode-connector'; 19 | 20 | /** 21 | * The `CommandContext` provides the necessary information to 22 | * setup the default commands for a GLSP diagram extension. 23 | */ 24 | export interface CommandContext { 25 | /** 26 | * The {@link vscode.ExtensionContext} of the GLSP diagram extension 27 | */ 28 | extensionContext: vscode.ExtensionContext; 29 | /** 30 | * The diagram specific identifier that should be used to prefix command ids. 31 | */ 32 | diagramPrefix: string; 33 | /** 34 | * The {@link GlspVscodeConnector} of the GLSP diagram extension. 35 | */ 36 | connector: GlspVscodeConnector; 37 | } 38 | export function configureDefaultCommands(context: CommandContext): void { 39 | // keep track of diagram specific element selection. 40 | const { extensionContext, diagramPrefix, connector } = context; 41 | 42 | let selectionState: SelectionState | undefined; 43 | 44 | extensionContext.subscriptions.push(connector.onSelectionUpdate(_selectionState => (selectionState = _selectionState))); 45 | 46 | extensionContext.subscriptions.push( 47 | vscode.commands.registerCommand(`${diagramPrefix}.fit`, () => { 48 | connector.dispatchAction(FitToScreenAction.create(selectionState?.selectedElementsIDs ?? [])); 49 | }), 50 | vscode.commands.registerCommand(`${diagramPrefix}.center`, () => { 51 | connector.dispatchAction(CenterAction.create(selectionState?.selectedElementsIDs ?? [])); 52 | }), 53 | vscode.commands.registerCommand(`${diagramPrefix}.layout`, () => { 54 | connector.dispatchAction(LayoutOperation.create([])); 55 | }), 56 | vscode.commands.registerCommand(`${diagramPrefix}.selectAll`, () => { 57 | connector.dispatchAction(SelectAllAction.create()); 58 | }), 59 | vscode.commands.registerCommand(`${diagramPrefix}.exportAsSVG`, () => { 60 | connector.dispatchAction(RequestExportSvgAction.create()); 61 | }) 62 | ); 63 | 64 | extensionContext.subscriptions.push( 65 | connector.onSelectionUpdate(state => { 66 | vscode.commands.executeCommand('setContext', `${diagramPrefix}.editorSelectedElementsAmount`, state.selectedElementsIDs.length); 67 | }) 68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/quickstart-components/glsp-editor-provider.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.01 15 | ********************************************************************************/ 16 | import * as vscode from 'vscode'; 17 | import { GlspVscodeConnector } from '../glsp-vscode-connector'; 18 | import { GLSPDiagramIdentifier } from '../types'; 19 | import { WebviewEndpoint } from './webview-endpoint'; 20 | /** 21 | * An extensible base class to create a CustomEditorProvider that takes care of 22 | * diagram initialization and custom document events. 23 | * 24 | * Webview setup needs to be implemented. 25 | */ 26 | export abstract class GlspEditorProvider implements vscode.CustomEditorProvider { 27 | /** The diagram type identifier the diagram server is responsible for. */ 28 | abstract diagramType: string; 29 | 30 | /** Used to generate continuous and unique clientIds - TODO: consider replacing this with uuid. */ 31 | private viewCount = 0; 32 | 33 | onDidChangeCustomDocument: vscode.Event | vscode.Event; 34 | 35 | constructor(protected readonly glspVscodeConnector: GlspVscodeConnector) { 36 | this.onDidChangeCustomDocument = glspVscodeConnector.onDidChangeCustomDocument; 37 | } 38 | 39 | saveCustomDocument(document: vscode.CustomDocument, _cancellation: vscode.CancellationToken): Thenable { 40 | return this.glspVscodeConnector.saveDocument(document); 41 | } 42 | 43 | saveCustomDocumentAs( 44 | document: vscode.CustomDocument, 45 | destination: vscode.Uri, 46 | _cancellation: vscode.CancellationToken 47 | ): Thenable { 48 | return this.glspVscodeConnector.saveDocument(document, destination); 49 | } 50 | 51 | revertCustomDocument(document: vscode.CustomDocument, _cancellation: vscode.CancellationToken): Thenable { 52 | return this.glspVscodeConnector.revertDocument(document, this.diagramType); 53 | } 54 | 55 | backupCustomDocument( 56 | _document: vscode.CustomDocument, 57 | context: vscode.CustomDocumentBackupContext, 58 | _cancellation: vscode.CancellationToken 59 | ): Thenable { 60 | // Basically do the bare minimum - which is nothing 61 | return Promise.resolve({ id: context.destination.toString(), delete: () => undefined }); 62 | } 63 | 64 | openCustomDocument( 65 | uri: vscode.Uri, 66 | _openContext: vscode.CustomDocumentOpenContext, 67 | _token: vscode.CancellationToken 68 | ): vscode.CustomDocument | Thenable { 69 | // Return the most basic implementation possible. 70 | return { uri, dispose: () => undefined }; 71 | } 72 | 73 | async resolveCustomEditor( 74 | document: vscode.CustomDocument, 75 | webviewPanel: vscode.WebviewPanel, 76 | token: vscode.CancellationToken 77 | ): Promise { 78 | // This is used to initialize GLSP for our diagram 79 | const diagramIdentifier: GLSPDiagramIdentifier = { 80 | diagramType: this.diagramType, 81 | uri: serializeUri(document.uri), 82 | clientId: `${this.diagramType}_${this.viewCount++}` 83 | }; 84 | 85 | const endpoint = new WebviewEndpoint({ diagramIdentifier, messenger: this.glspVscodeConnector.messenger, webviewPanel }); 86 | 87 | // Register document/diagram panel/model in vscode connector 88 | this.glspVscodeConnector.registerClient({ 89 | clientId: diagramIdentifier.clientId, 90 | diagramType: diagramIdentifier.diagramType, 91 | document: document, 92 | webviewEndpoint: endpoint 93 | }); 94 | 95 | this.setUpWebview(document, webviewPanel, token, diagramIdentifier.clientId); 96 | } 97 | 98 | /** 99 | * Used to set up the webview within the webview panel. 100 | */ 101 | abstract setUpWebview( 102 | document: vscode.CustomDocument, 103 | webviewPanel: vscode.WebviewPanel, 104 | token: vscode.CancellationToken, 105 | clientId: string 106 | ): void; 107 | } 108 | 109 | function serializeUri(uri: vscode.Uri): string { 110 | let uriString = uri.toString(); 111 | const match = uriString.match(/file:\/\/\/([a-z])%3A/i); 112 | if (match) { 113 | uriString = 'file:///' + match[1] + ':' + uriString.substring(match[0].length); 114 | } 115 | return uriString; 116 | } 117 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/quickstart-components/index.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from './base-glsp-vscode-server'; 17 | export * from './configuration-util'; 18 | export * from './glsp-editor-provider'; 19 | export * from './webview-endpoint'; 20 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/quickstart-components/webview-endpoint.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { 17 | ActionMessage, 18 | ClientState, 19 | Deferred, 20 | Disposable, 21 | DisposableCollection, 22 | DisposeClientSessionParameters, 23 | GLSPClient, 24 | InitializeClientSessionParameters, 25 | InitializeParameters, 26 | InitializeResult 27 | } from '@eclipse-glsp/protocol'; 28 | import * as vscode from 'vscode'; 29 | import { Messenger } from 'vscode-messenger'; 30 | import { MessageParticipant, NotificationType, RequestType } from 'vscode-messenger-common'; 31 | import { GLSPDiagramIdentifier } from '../types'; 32 | 33 | export interface WebviewEndpointOptions { 34 | webviewPanel: vscode.WebviewPanel; 35 | messenger?: Messenger; 36 | diagramIdentifier: GLSPDiagramIdentifier; 37 | } 38 | 39 | export const WebviewReadyNotification: NotificationType = { method: 'ready' }; 40 | export const InitializeNotification: NotificationType = { method: 'initialize' }; 41 | 42 | export const ActionMessageNotification: NotificationType = { method: 'actionMessage' }; 43 | export const ClientStateChangeNotification: NotificationType = { method: 'notifyClientStateChange' }; 44 | export const StartRequest: RequestType = { method: 'start' }; 45 | export const InitializeServerRequest: RequestType = { method: 'initializeServer' }; 46 | export const InitializeClientSessionRequest: RequestType = { method: 'initializeClientSession' }; 47 | export const DisposeClientSessionRequest: RequestType = { method: 'disposeClientSession' }; 48 | export const ShutdownServerNotification: NotificationType = { method: 'shutdownServer' }; 49 | export const StopRequest: RequestType = { method: 'stop' }; 50 | 51 | /** 52 | * Wrapper class around a {@link vscode.WebviewPanel}. Takes care 53 | * of the communication between the webview and the host extension. 54 | * It's main responsibility is sending {@link ActionMessages} to the webview 55 | * and handling of action messages received from the webview. 56 | */ 57 | export class WebviewEndpoint implements Disposable { 58 | readonly webviewPanel: vscode.WebviewPanel; 59 | readonly messenger: Messenger; 60 | readonly messageParticipant: MessageParticipant; 61 | readonly diagramIdentifier: GLSPDiagramIdentifier; 62 | 63 | protected _readyDeferred = new Deferred(); 64 | protected toDispose = new DisposableCollection(); 65 | 66 | protected onActionMessageEmitter = new vscode.EventEmitter(); 67 | get onActionMessage(): vscode.Event { 68 | return this.onActionMessageEmitter.event; 69 | } 70 | 71 | protected _serverActions?: string[]; 72 | get serverActions(): string[] | undefined { 73 | return this._serverActions; 74 | } 75 | 76 | protected _clientActions?: string[]; 77 | get clientActions(): string[] | undefined { 78 | return this._clientActions; 79 | } 80 | 81 | constructor(options: WebviewEndpointOptions) { 82 | this.webviewPanel = options.webviewPanel; 83 | this.messenger = options.messenger ?? new Messenger(); 84 | this.diagramIdentifier = options.diagramIdentifier; 85 | this.messageParticipant = this.messenger.registerWebviewPanel(this.webviewPanel); 86 | 87 | this.toDispose.push( 88 | this.webviewPanel.onDidDispose(() => { 89 | this.dispose(); 90 | }), 91 | this.messenger.onNotification( 92 | WebviewReadyNotification, 93 | () => { 94 | this._readyDeferred.resolve(); 95 | }, 96 | { 97 | sender: this.messageParticipant 98 | } 99 | ), 100 | this.onActionMessageEmitter 101 | ); 102 | } 103 | 104 | protected async sendDiagramIdentifier(): Promise { 105 | await this.ready; 106 | if (this.diagramIdentifier) { 107 | this.messenger.sendNotification(InitializeNotification, this.messageParticipant, this.diagramIdentifier); 108 | } 109 | } 110 | 111 | /** 112 | * Hooks up a {@link GLSPClient} with the underlying webview and send the `initialize` message to the webview 113 | * (once its ready) 114 | * The GLSP client is called remotely from the webview context via the `vscode-messenger` RPC 115 | * protocol. 116 | * @param glspClient The client that should be connected 117 | * @returns A {@link Disposable} to dispose the remote connection and all attached listeners 118 | */ 119 | initialize(glspClient: GLSPClient): Disposable { 120 | const toDispose = new DisposableCollection(); 121 | toDispose.push( 122 | this.messenger.onNotification( 123 | ActionMessageNotification, 124 | msg => { 125 | this.onActionMessageEmitter.fire(msg); 126 | }, 127 | { 128 | sender: this.messageParticipant 129 | } 130 | ), 131 | this.messenger.onRequest(StartRequest, () => glspClient.start(), { sender: this.messageParticipant }), 132 | this.messenger.onRequest( 133 | InitializeServerRequest, 134 | async params => { 135 | const result = await glspClient.initializeServer(params); 136 | if (!this._serverActions) { 137 | this._serverActions = result.serverActions[this.diagramIdentifier.diagramType]; 138 | } 139 | return result; 140 | }, 141 | { 142 | sender: this.messageParticipant 143 | } 144 | ), 145 | this.messenger.onRequest( 146 | InitializeClientSessionRequest, 147 | params => { 148 | if (!this._clientActions) { 149 | this._clientActions = params.clientActionKinds; 150 | } 151 | glspClient.initializeClientSession(params); 152 | }, 153 | { 154 | sender: this.messageParticipant 155 | } 156 | ), 157 | this.messenger.onRequest(DisposeClientSessionRequest, params => glspClient.disposeClientSession(params), { 158 | sender: this.messageParticipant 159 | }), 160 | this.messenger.onRequest(ShutdownServerNotification, () => glspClient.shutdownServer(), { 161 | sender: this.messageParticipant 162 | }), 163 | this.messenger.onRequest(StopRequest, () => glspClient.stop(), { 164 | sender: this.messageParticipant 165 | }), 166 | glspClient.onCurrentStateChanged(state => 167 | this.messenger.sendNotification(ClientStateChangeNotification, this.messageParticipant, state) 168 | ) 169 | ); 170 | this.toDispose.push(toDispose); 171 | this.sendDiagramIdentifier(); 172 | return toDispose; 173 | } 174 | 175 | sendMessage(actionMessage: ActionMessage): void { 176 | this.messenger.sendNotification(ActionMessageNotification, this.messageParticipant, actionMessage); 177 | } 178 | 179 | get ready(): Promise { 180 | return this._readyDeferred.promise; 181 | } 182 | 183 | dispose(): void { 184 | this.toDispose.dispose(); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/re-export.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from '@eclipse-glsp/protocol'; 17 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/common/types.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { AnyObject, GLSPClient, InitializeResult, hasStringProp } from '@eclipse-glsp/protocol'; 17 | import * as vscode from 'vscode'; 18 | import { WebviewEndpoint } from '.'; 19 | 20 | /** 21 | * Any clients registered on the GLSP VSCode integration need to implement this 22 | * interface. 23 | */ 24 | export interface GlspVscodeClient { 25 | /** 26 | * A unique identifier for the client/panel with which the client will be registered 27 | * on the server. 28 | */ 29 | readonly clientId: string; 30 | 31 | /** 32 | * Unique identifier of the diagram type that this client can handle. 33 | */ 34 | readonly diagramType: string; 35 | 36 | /** 37 | * The {@link WebviewEndpoint} belonging to the client. 38 | */ 39 | readonly webviewEndpoint: WebviewEndpoint; 40 | 41 | /** 42 | * The document object belonging to the client; 43 | */ 44 | readonly document: D; 45 | } 46 | 47 | /** 48 | * The server or server wrapper used by the VSCode integration needs to implement 49 | * this interface. 50 | */ 51 | export interface GlspVscodeServer { 52 | /** 53 | * An event emitter used by the VSCode extension to send messages to the server. 54 | * 55 | * You should subscribe to the event attached to this emitter to receive messages 56 | * from the client/VSCode integration and pass them to the server. 57 | * 58 | * Use the properties `onBeforeReceiveMessageFromClient` and `onBeforePropagateMessageToServer` 59 | * of the GlspVscodeConnector in order to control what messages are propagated 60 | * and processed. 61 | */ 62 | readonly onSendToServerEmitter: vscode.EventEmitter; 63 | 64 | /** 65 | * An event the VSCode integration uses to receive messages from the server. 66 | * The messages are then propagated to the client or processed by the VSCode 67 | * integration to provide functionality. 68 | * 69 | * Fire this event with the message the server wants to send to the client. 70 | * 71 | * Use the properties `onBeforeReceiveMessageFromServer` and `onBeforePropagateMessageToClient` 72 | * of the GlspVscodeConnector in order to control what messages are propagated 73 | * and processed. 74 | */ 75 | readonly onServerMessage: vscode.Event; 76 | 77 | /** 78 | * The {@link GLSPClient} instance that is used by this server wrapper to communicate with the 79 | * GLSP server process. 80 | */ 81 | readonly glspClient: Promise; 82 | 83 | /** 84 | * The result of the {@link GLSPClient.initializeServer} call. Implementing classes are expected 85 | * to call this method during the their initialization phase. 86 | */ 87 | readonly initializeResult: Promise; 88 | 89 | /** 90 | * A promise that resolves once the `GLSPVscodeServer` is ready i.e. has been started. 91 | */ 92 | readonly onReady: Promise; 93 | 94 | /** 95 | * Starts up the GLSP client and connects it to a GLSP server. 96 | */ 97 | start(): Promise; 98 | } 99 | 100 | interface InterceptorCallback { 101 | /** 102 | * This callback controls what message should be propagated to the VSCode integration 103 | * and whether the VSCode integration should process it (ie. provide functionality 104 | * based on the message). 105 | * 106 | * @param newMessage The message to be propagated. This value can be anything, 107 | * however if it is `undefined` the message will not be propagated further. 108 | * @param shouldBeProcessedByConnector Optional parameter indicating whether the 109 | * VSCode integration should process the message. That usually means providing 110 | * functionality based on the message but also modifying it or blocking it from 111 | * being propagated further. 112 | */ 113 | (newMessage: unknown | undefined, shouldBeProcessedByConnector?: boolean): void; 114 | } 115 | 116 | export interface GlspVscodeConnectorOptions { 117 | /** 118 | * The GLSP server (or its wrapper) that the VSCode integration should use. 119 | */ 120 | server: GlspVscodeServer; 121 | 122 | /** 123 | * Wether the GLSP-VSCode integration should log various events. This is useful 124 | * if you want to find out what events the VSCode integration is receiving from 125 | * and sending to the server and clients. 126 | * 127 | * Defaults to `false`. 128 | */ 129 | logging?: boolean; 130 | 131 | /** 132 | * Optional property to intercept (and/or modify) messages sent from the client 133 | * to the VSCode integration via `GlspVscodeClient.onClientSend`. 134 | * 135 | * @param message Contains the original message sent by the client. 136 | * @param callback A callback to control how messages are handled further. 137 | */ 138 | onBeforeReceiveMessageFromClient?: (message: unknown, callback: InterceptorCallback) => void; 139 | 140 | /** 141 | * Optional property to intercept (and/or modify) messages sent from the server 142 | * to the VSCode integration via `GlspVscodeServer.onServerSend`. 143 | * 144 | * @param message Contains the original message sent by the client. 145 | * @param callback A callback to control how messages are handled further. 146 | */ 147 | onBeforeReceiveMessageFromServer?(message: unknown, callback: InterceptorCallback): void; 148 | 149 | /** 150 | * Optional property to intercept (and/or modify) messages sent from the VSCode 151 | * integration to the server via the `GlspVscodeServer.onServerReceiveEmitter`. 152 | * 153 | * The returned value from this function is the message that will be propagated 154 | * to the server. It can be modified to anything. Returning `undefined` will 155 | * cancel the propagation. 156 | * 157 | * @param originalMessage The original message received by the VSCode integration 158 | * from the client. 159 | * @param processedMessage If the VSCode integration modified the received message 160 | * in any way, this parameter will contain the modified message. If the VSCode 161 | * integration did not modify the message, this parameter will be identical to 162 | * `originalMessage`. 163 | * @param messageChanged This parameter will indicate wether the VSCode integration 164 | * modified the incoming message. In other words: Whether `originalMessage` 165 | * and `processedMessage` are different. 166 | * @returns A message that will be propagated to the server. If the message 167 | * is `undefined` the propagation will be cancelled. 168 | */ 169 | onBeforePropagateMessageToServer?(originalMessage: unknown, processedMessage: unknown, messageChanged: boolean): unknown | undefined; 170 | 171 | /** 172 | * Optional property to intercept (and/or modify) messages sent from the VSCode 173 | * integration to a client via the `GlspVscodeClient.onClientReceiveEmitter`. 174 | * 175 | * The returned value from this function is the message that will be propagated 176 | * to the client. It can be modified to anything. Returning `undefined` will 177 | * cancel the propagation. 178 | * 179 | * @param originalMessage The original message received by the VSCode integration 180 | * from the server. 181 | * @param processedMessage If the VSCode integration modified the received message 182 | * in any way, this parameter will contain the modified message. If the VSCode 183 | * integration did not modify the message, this parameter will be identical to 184 | * `originalMessage`. 185 | * @param messageChanged This parameter will indicate wether the VSCode integration 186 | * modified the incoming message. In other words: Whether `originalMessage` 187 | * and `processedMessage` are different. 188 | * @returns A message that will be propagated to the client. If the message 189 | * is `undefined` the propagation will be cancelled. 190 | */ 191 | onBeforePropagateMessageToClient?(originalMessage: unknown, processedMessage: unknown, messageChanged: boolean): unknown | undefined; 192 | } 193 | 194 | export const GLSPDiagramIdentifier = Symbol('GLSPDiagramIdentifier'); 195 | 196 | export interface GLSPDiagramIdentifier { 197 | clientId: string; 198 | diagramType: string; 199 | uri: string; 200 | } 201 | 202 | export function isDiagramIdentifier(object: any): object is GLSPDiagramIdentifier { 203 | return ( 204 | AnyObject.is(object) && // 205 | hasStringProp(object, 'clientId') && 206 | hasStringProp(object, 'diagramType') && 207 | hasStringProp(object, 'uri') 208 | ); 209 | } 210 | 211 | // ---------------------------------- 212 | // Initial Handshake 213 | 214 | export interface WebviewReadyMessage { 215 | readyMessage: string; 216 | } 217 | export namespace WebviewReadyMessage { 218 | export function is(object: unknown): object is WebviewReadyMessage { 219 | return AnyObject.is(object) && hasStringProp(object, 'readyMessage'); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/node/index.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2023-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from './quickstart-components/glsp-socket-server-launcher'; 17 | export * from './quickstart-components/node-glsp-vscode-server'; 18 | export * from './quickstart-components/socket-glsp-vscode-server'; 19 | export * from './re-export'; 20 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/node/quickstart-components/glsp-socket-server-launcher.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import * as childProcess from 'child_process'; 17 | import * as fs from 'fs'; 18 | import * as net from 'net'; 19 | import * as vscode from 'vscode'; 20 | 21 | const START_UP_COMPLETE_MSG = '[GLSP-Server]:Startup completed'; 22 | 23 | export interface SocketServerLauncherOptions { 24 | /** Path to the location of the server executable (JAR or node module) that should be launched as process */ 25 | readonly executable: string; 26 | /** Socket connection on which the server should listen for new client connections */ 27 | socketConnectionOptions: net.TcpSocketConnectOpts; 28 | /** Set to `true` if server stdout and stderr should be printed in extension host console. Default: `false` */ 29 | readonly logging?: boolean; 30 | /** Additional arguments that should be passed when starting the server process. */ 31 | readonly additionalArgs?: string[]; 32 | } 33 | 34 | /** 35 | * This component can be used to bootstrap your extension when using the default 36 | * GLSP server implementations, which you can find here: 37 | * https://github.com/eclipse-glsp/glsp-server 38 | * https://github.com/eclipse-glsp/glsp-server-node 39 | * 40 | * It simply starts up a server executable (JAR or node module) located at a specified path on a specified port. 41 | * You can pass additional launch arguments through the options. 42 | * 43 | * If you need a component to quickly connect your default GLSP server to the GLSP-VSCode 44 | * integration, take a look at the `SocketGlspVscodeServer` quickstart component. 45 | */ 46 | export class GlspSocketServerLauncher implements vscode.Disposable { 47 | protected readonly options: Required; 48 | protected serverProcess?: childProcess.ChildProcess; 49 | 50 | constructor(options: SocketServerLauncherOptions) { 51 | // Create default options 52 | this.options = { 53 | logging: false, 54 | additionalArgs: [], 55 | ...options 56 | }; 57 | } 58 | 59 | /** 60 | * Starts up the server. 61 | */ 62 | async start(): Promise { 63 | const executable = this.options.executable; 64 | 65 | if (!executable) { 66 | throw new Error('Could not launch GLSP server. No executable path is provided via the launch options'); 67 | } 68 | 69 | if (!fs.existsSync(executable)) { 70 | throw Error(`Could not launch GLSP server. The given server executable path is not valid: ${executable}`); 71 | } 72 | 73 | if (isNaN(this.options.socketConnectionOptions.port)) { 74 | throw new Error( 75 | `Could not launch GLSP Server. The given server port is not a number: ${this.options.socketConnectionOptions.port}` 76 | ); 77 | } 78 | 79 | const process = this.startProcess(); 80 | this.serverProcess = process; 81 | return this.configureProcess(process); 82 | } 83 | 84 | protected configureProcess(process: childProcess.ChildProcessWithoutNullStreams): Promise { 85 | return new Promise(resolve => { 86 | process.stdout.on('data', data => { 87 | if (data.toString().includes(START_UP_COMPLETE_MSG)) { 88 | const port = this.getPortFromStartupMessage(data.toString()); 89 | if (port) { 90 | if (this.options.socketConnectionOptions.port === 0) { 91 | this.options.socketConnectionOptions.port = port; 92 | } else { 93 | if (this.options.socketConnectionOptions.port !== port) { 94 | throw new Error( 95 | // eslint-disable-next-line max-len 96 | `The configured port ${this.options.socketConnectionOptions.port} does not match the port in the startup message: ${data}` 97 | ); 98 | } 99 | } 100 | } else { 101 | throw new Error('Could not find listening port in startup message of GLSP server!'); 102 | } 103 | resolve(); 104 | } 105 | 106 | this.handleStdoutData(data); 107 | }); 108 | 109 | process.stderr.on('data', error => this.handleStderrData(error)); 110 | process.on('error', error => this.handleProcessError(error)); 111 | }); 112 | } 113 | 114 | protected startProcess(): childProcess.ChildProcessWithoutNullStreams { 115 | if (this.options.executable.endsWith('.jar')) { 116 | return this.startJavaProcess(); 117 | } else if (this.options.executable.endsWith('.js')) { 118 | return this.startNodeProcess(); 119 | } else { 120 | throw new Error(`Could not launch GLSP Server. Invalid executable path ${this.options.executable}`); 121 | } 122 | } 123 | 124 | protected startJavaProcess(): childProcess.ChildProcessWithoutNullStreams { 125 | if (!this.options.executable.endsWith('jar')) { 126 | throw new Error(`Could not launch Java GLSP server. The given executable is no JAR: ${this.options.executable}`); 127 | } 128 | const args = [ 129 | '-jar', 130 | this.options.executable, 131 | '--port', 132 | `${this.options.socketConnectionOptions.port}`, 133 | '--host', 134 | `${this.options.socketConnectionOptions.host ?? '127.0.0.1'}`, 135 | ...this.options.additionalArgs 136 | ]; 137 | 138 | if (this.options.socketConnectionOptions.host) { 139 | args.push('--host', `${this.options.socketConnectionOptions.host}`); 140 | } 141 | return childProcess.spawn('java', args); 142 | } 143 | 144 | protected startNodeProcess(): childProcess.ChildProcessWithoutNullStreams { 145 | if (!this.options.executable.endsWith('.js')) { 146 | throw new Error(`Could not launch Node GLSP server. The given executable is no node module: ${this.options.executable}`); 147 | } 148 | const args = [ 149 | this.options.executable, 150 | '--port', 151 | `${this.options.socketConnectionOptions.port}`, 152 | '--host', 153 | `${this.options.socketConnectionOptions.host ?? '127.0.0.1'}`, 154 | ...this.options.additionalArgs 155 | ]; 156 | 157 | return childProcess.spawn('node', args); 158 | } 159 | 160 | protected getPortFromStartupMessage(message: string): number | undefined { 161 | if (message.includes(START_UP_COMPLETE_MSG)) { 162 | const port = message.substring(message.lastIndexOf(':') + 1); 163 | return parseInt(port, 10); 164 | } 165 | return undefined; 166 | } 167 | 168 | protected handleStdoutData(data: string | Buffer): void { 169 | if (this.options.logging) { 170 | console.log('GLSP-Server:', data.toString()); 171 | } 172 | } 173 | 174 | protected handleStderrData(data: string | Buffer): void { 175 | if (data && this.options.logging) { 176 | console.error('GLSP-Server:', data.toString()); 177 | } 178 | } 179 | 180 | protected handleProcessError(error: Error): never { 181 | if (this.options.logging) { 182 | console.error('GLSP-Server:', error); 183 | } 184 | 185 | throw error; 186 | } 187 | 188 | getPort(): number { 189 | return this.options.socketConnectionOptions.port; 190 | } 191 | 192 | /** 193 | * Stops the server. 194 | */ 195 | stop(): void { 196 | if (this.serverProcess && !this.serverProcess.killed) { 197 | this.serverProcess.kill('SIGINT'); 198 | // TODO: Think of a process that does this elegantly with the same consistency. 199 | } 200 | } 201 | 202 | dispose(): void { 203 | this.stop(); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/node/quickstart-components/node-glsp-vscode-server.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { BaseGLSPClient, GLSPClientProxy, GLSPServer } from '@eclipse-glsp/protocol'; 17 | import { ContainerConfiguration, initializeContainer } from '@eclipse-glsp/protocol/lib/di'; 18 | import { Container, ContainerModule } from 'inversify'; 19 | import { BaseGlspVscodeServer, GlspVscodeServerOptions } from '../../common/quickstart-components/base-glsp-vscode-server'; 20 | 21 | export interface NodeGlspVscodeServerOptions extends GlspVscodeServerOptions { 22 | /** The server DI modules*/ 23 | readonly serverModules: ContainerModule[]; 24 | } 25 | 26 | /** 27 | * This component can be used to bootstrap your extension when using the node 28 | * GLSP server implementation directly in an extension without a dedicated process, which you can find here: 29 | * https://github.com/eclipse-glsp/glsp-server-node 30 | * 31 | * It sets up a a server running directly in the extension context and 32 | * provides an interface, ready to be used by the `GlspVscodeConnector` for the 33 | * GLSP-VSCode integration. 34 | */ 35 | export class NodeGlspVscodeServer extends BaseGlspVscodeServer { 36 | protected serverContainer: Container; 37 | 38 | constructor(protected override readonly options: NodeGlspVscodeServerOptions) { 39 | super(options); 40 | } 41 | 42 | override createGLSPClient(): BaseGLSPClient { 43 | const client = new BaseGLSPClient({ 44 | id: this.options.clientId 45 | }); 46 | const proxyModule = new ContainerModule(bind => { 47 | bind(GLSPClientProxy).toConstantValue(client.proxy); 48 | }); 49 | this.serverContainer = this.createContainer(proxyModule); 50 | const server = this.serverContainer.get(GLSPServer); 51 | client.configureServer(server); 52 | return client; 53 | } 54 | 55 | protected createContainer(...additionalConfiguration: ContainerConfiguration): Container { 56 | const container = new Container(); 57 | return initializeContainer(container, ...this.options.serverModules, ...additionalConfiguration); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/node/quickstart-components/socket-glsp-vscode-server.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2021-2023 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | import { BaseJsonrpcGLSPClient, WebSocketWrapper, createWebSocketConnection } from '@eclipse-glsp/protocol'; 17 | import * as net from 'net'; 18 | import { MessageConnection, createMessageConnection } from 'vscode-jsonrpc'; 19 | import { SocketMessageReader, SocketMessageWriter } from 'vscode-jsonrpc/node'; 20 | import { WebSocket } from 'ws'; 21 | import { BaseGlspVscodeServer, GlspVscodeServerOptions } from '../../common/quickstart-components/base-glsp-vscode-server'; 22 | 23 | export interface SocketGlspVscodeServerOptions extends GlspVscodeServerOptions { 24 | /** (Web)socket connection options of the running server. */ 25 | readonly connectionOptions: SocketConnectionOptions; 26 | } 27 | 28 | export type SocketConnectionOptions = 29 | /* Socket connection options*/ 30 | | net.TcpSocketConnectOpts 31 | | { 32 | /** Address of the server websocket endpoint */ 33 | webSocketAddress: string; 34 | } 35 | | { 36 | /** Server websocket port */ 37 | port: number; 38 | /** Server hostname. Default is 'localhost' */ 39 | host?: string; 40 | /** Websocket endpoint path*/ 41 | path: string; 42 | /** The websocket protocol used by the server. Default is 'ws' */ 43 | protocol?: 'ws' | 'wss'; 44 | }; 45 | 46 | /** 47 | * This component can be used to bootstrap your extension when using the default 48 | * GLSP server implementation via (Web)socket connection 49 | * 50 | * It sets up a JSON-RPC connection to a server running on a specified port and 51 | * provides an interface, ready to be used by the `GlspVscodeConnector` for the 52 | * GLSP-VSCode integration. 53 | * 54 | * If you need a component to quickly start your default GLSP server, take a look 55 | * at the `GlspServerStarter` quickstart component. 56 | */ 57 | export class SocketGlspVscodeServer extends BaseGlspVscodeServer { 58 | constructor(protected override readonly options: SocketGlspVscodeServerOptions) { 59 | super(options); 60 | } 61 | 62 | protected getWebSocketAddress(): string | undefined { 63 | const opts = this.options.connectionOptions; 64 | if ('webSocketAddress' in opts) { 65 | return opts.webSocketAddress; 66 | } 67 | if ('path' in opts && opts.path !== undefined) { 68 | const protocol = opts.protocol ?? 'ws'; 69 | const host = opts.host ?? '127.0.0.1'; 70 | return `${protocol}://${host}:${opts.port}/${opts.path}`; 71 | } 72 | 73 | return undefined; 74 | } 75 | 76 | override async createGLSPClient(): Promise { 77 | const connection = await this.createConnection(); 78 | this.toDispose.push(connection); 79 | return new BaseJsonrpcGLSPClient({ 80 | id: this.options.clientId, 81 | connectionProvider: connection 82 | }); 83 | } 84 | 85 | protected async createConnection(): Promise { 86 | const webSocketAddress = this.getWebSocketAddress(); 87 | if (webSocketAddress && !isValidWebSocketAddress(webSocketAddress)) { 88 | throw new Error(`Could not connect to to GLSP Server. The WebSocket address is invalid: '${webSocketAddress}'`); 89 | } 90 | if (webSocketAddress) { 91 | return this.createWebSocketConnection(webSocketAddress); 92 | } 93 | 94 | if (!('port' in this.options.connectionOptions)) { 95 | throw new Error('Could not connect to to GLSP Server. The given server port is not defined'); 96 | } 97 | if (isNaN(this.options.connectionOptions.port)) { 98 | throw new Error( 99 | `Could not connect to to GLSP Server. The given server port is not a number: ${this.options.connectionOptions.port}` 100 | ); 101 | } 102 | return this.createSocketConnection(this.options.connectionOptions); 103 | } 104 | 105 | protected createSocketConnection(opts: net.TcpSocketConnectOpts): MessageConnection { 106 | const socket = new net.Socket(); 107 | const reader = new SocketMessageReader(socket); 108 | const writer = new SocketMessageWriter(socket); 109 | const connection = createMessageConnection(reader, writer); 110 | socket.connect(opts); 111 | return connection; 112 | } 113 | 114 | protected createWebSocketConnection(address: string): Promise { 115 | const webSocket = new WebSocket(address); 116 | return new Promise(resolve => { 117 | webSocket.onopen = () => { 118 | const socket = wrapNodeWs(webSocket); 119 | resolve(createWebSocketConnection(socket)); 120 | }; 121 | }); 122 | } 123 | } 124 | 125 | export function isValidWebSocketAddress(address: string): boolean { 126 | try { 127 | const { protocol } = new URL(address); 128 | return protocol === 'ws:' || protocol === 'wss:'; 129 | } catch (error) { 130 | return false; 131 | } 132 | } 133 | 134 | export function wrapNodeWs(socket: WebSocket): WebSocketWrapper { 135 | return { 136 | send: content => socket.send(content), 137 | onMessage: cb => (socket.onmessage = event => cb(event.data)), 138 | onClose: cb => (socket.onclose = event => cb(event.code, event.reason)), 139 | onError: cb => 140 | (socket.onerror = event => { 141 | if ('error' in event) { 142 | cb(event.error); 143 | } 144 | }), 145 | dispose: () => socket.close() 146 | }; 147 | } 148 | -------------------------------------------------------------------------------- /packages/vscode-integration/src/node/re-export.ts: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | * Copyright (c) 2024 EclipseSource and others. 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the Eclipse 10 | * Public License v. 2.0 are satisfied: GNU General Public License, version 2 11 | * with the GNU Classpath Exception which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | ********************************************************************************/ 16 | export * from '../common'; 17 | -------------------------------------------------------------------------------- /packages/vscode-integration/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config", 3 | "compilerOptions": { 4 | "composite": true, 5 | "rootDir": "src", 6 | "outDir": "lib" 7 | }, 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config/tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true 5 | }, 6 | "exclude": ["**/node_modules", "**/.eslintrc.js"], 7 | "include": ["packages/*/src", "example/**/*/src", "**/scripts/"] 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eclipse-glsp/ts-config", 3 | "include": [], 4 | "compilerOptions": { 5 | "composite": true 6 | }, 7 | "references": [ 8 | { 9 | "path": "./packages/vscode-integration" 10 | }, 11 | { 12 | "path": "./packages/vscode-integration-webview" 13 | }, 14 | { 15 | "path": "./example/workflow/extension" 16 | }, 17 | { 18 | "path": "./example/workflow/web-extension" 19 | }, 20 | { 21 | "path": "./example/workflow/webview" 22 | } 23 | ] 24 | } 25 | --------------------------------------------------------------------------------