├── .python-version ├── LICENSE ├── LSP-bash.sublime-commands ├── LSP-bash.sublime-settings ├── Main.sublime-menu ├── README.md ├── boot.py ├── dependencies.json ├── language-server ├── package-lock.json └── package.json ├── messages.json ├── messages └── update_message.md └── plugin ├── __init__.py ├── client.py ├── constants.py ├── log.py └── template.py /.python-version: -------------------------------------------------------------------------------- 1 | 3.8 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 SublimeLSP 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LSP-bash.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences: LSP-bash Settings", 4 | "command": "edit_settings", 5 | "args": { 6 | "base_file": "${packages}/LSP-bash/LSP-bash.sublime-settings", 7 | "default": "// Settings in here override those in \"LSP-bash/LSP-bash.sublime-settings\"\n\n{\n\t$0\n}\n", 8 | }, 9 | }, 10 | ] 11 | -------------------------------------------------------------------------------- /LSP-bash.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | // Open "Preferences: LSP Utils Settings" from the Command Palette to customize the Node runtime. 3 | "command": ["${node_bin}", "${server_path}", "start"], 4 | "schemes": ["file", "buffer", "res"], 5 | // @see https://github.com/bash-lsp/bash-language-server/blob/main/server/src/config.ts 6 | "settings": { 7 | // Maximum number of files to analyze in the background. Set to 0 to disable background analysis. 8 | // "bashIde.backgroundAnalysisMaxFiles": 500, 9 | 10 | // Glob pattern for finding and parsing shell script files in the workspace. Used by the background analysis features across files. 11 | // "bashIde.globPattern": "**/*@(.sh|.inc|.bash|.command)", 12 | 13 | // Log level for the server. To set the right log level from the start please also use the environment variable 'BASH_IDE_LOG_LEVEL'. 14 | // Can be "debug", "info", "warning", "error". 15 | // "bashIde.logLevel": "info", 16 | 17 | // Controls if Treesitter parsing errors will be highlighted as problems. 18 | // "bashIde.highlightParsingErrors": false, 19 | 20 | // Controls how symbols (e.g. variables and functions) are included and used for completion and documentation. 21 | // If false, then we only include symbols from sourced files (i.e. using non dynamic statements like 'source file.sh' or '. file.sh'). 22 | // If true, then all symbols from the workspace are included. 23 | // "bashIde.includeAllWorkspaceSymbols": false, 24 | 25 | // Configure explainshell server endpoint in order to get hover documentation on flags and options. 26 | // And empty string will disable the feature. 27 | // "bashIde.explainshellEndpoint": "", 28 | 29 | // Controls the executable used for ShellCheck linting information. An empty string will disable linting. 30 | // To download shellcheck, go https://github.com/koalaman/shellcheck/releases/latest 31 | // "bashIde.shellcheckPath": "shellcheck", 32 | 33 | // Additional ShellCheck arguments. Note that we already add the following arguments: --shell, --format, --external-sources." 34 | // "bashIde.shellcheckArguments": [], 35 | 36 | // The (Jinja2) template of the status bar text which is inside the parentheses `(...)`. 37 | // See https://jinja.palletsprojects.com/templates/ 38 | "statusText": "{% if server_version %}v{{ server_version }}{% endif %}", 39 | }, 40 | "selector": "source.shell.bash", 41 | } 42 | -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "preferences", 4 | "children": [ 5 | { 6 | "caption": "Package Settings", 7 | "mnemonic": "P", 8 | "id": "package-settings", 9 | "children": [ 10 | { 11 | "caption": "LSP", 12 | "id": "lsp-settings", 13 | "children": [ 14 | { 15 | "caption": "Servers", 16 | "id": "lsp-servers", 17 | "children": [ 18 | { 19 | "caption": "LSP-bash", 20 | "command": "edit_settings", 21 | "args": { 22 | "base_file": "${packages}/LSP-bash/LSP-bash.sublime-settings", 23 | "default": "// Settings in here override those in \"LSP-bash/LSP-bash.sublime-settings\"\n\n{\n\t$0\n}\n", 24 | }, 25 | }, 26 | ], 27 | }, 28 | ], 29 | }, 30 | ], 31 | }, 32 | ], 33 | }, 34 | ] 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LSP-bash 2 | 3 | Bash support for Sublime's LSP plugin provided through [bash-language-server](https://github.com/bash-lsp/bash-language-server). 4 | 5 | ## Installation 6 | 7 | - Install [LSP](https://packagecontrol.io/packages/LSP) and [LSP-bash](https://packagecontrol.io/packages/LSP-bash) from Package Control. 8 | - Restart Sublime. 9 | 10 | ## Configuration 11 | 12 | There are some ways to configure the package and the language server. 13 | 14 | - From `Preferences > Package Settings > LSP > Servers > LSP-bash` 15 | - From the command palette `Preferences: LSP-bash Settings` 16 | -------------------------------------------------------------------------------- /boot.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def reload_plugin() -> None: 5 | import sys 6 | 7 | # remove all previously loaded plugin modules 8 | prefix = f"{__package__}." 9 | for module_name in tuple(filter(lambda m: m.startswith(prefix) and m != __name__, sys.modules)): 10 | del sys.modules[module_name] 11 | 12 | 13 | reload_plugin() 14 | 15 | from .plugin import * # noqa: E402, F401, F403 16 | -------------------------------------------------------------------------------- /dependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": { 3 | "*": [ 4 | "Jinja2", 5 | "jmespath", 6 | "lsp_utils", 7 | "markupsafe", 8 | "sublime_lib" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /language-server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-server", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "bash-language-server": "^5.4.3" 9 | } 10 | }, 11 | "node_modules/@mixmark-io/domino": { 12 | "version": "2.2.0", 13 | "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", 14 | "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" 15 | }, 16 | "node_modules/@nodelib/fs.scandir": { 17 | "version": "2.1.5", 18 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 19 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 20 | "dependencies": { 21 | "@nodelib/fs.stat": "2.0.5", 22 | "run-parallel": "^1.1.9" 23 | }, 24 | "engines": { 25 | "node": ">= 8" 26 | } 27 | }, 28 | "node_modules/@nodelib/fs.stat": { 29 | "version": "2.0.5", 30 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 31 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 32 | "engines": { 33 | "node": ">= 8" 34 | } 35 | }, 36 | "node_modules/@nodelib/fs.walk": { 37 | "version": "1.2.8", 38 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 39 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 40 | "dependencies": { 41 | "@nodelib/fs.scandir": "2.1.5", 42 | "fastq": "^1.6.0" 43 | }, 44 | "engines": { 45 | "node": ">= 8" 46 | } 47 | }, 48 | "node_modules/@one-ini/wasm": { 49 | "version": "0.1.1", 50 | "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", 51 | "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" 52 | }, 53 | "node_modules/balanced-match": { 54 | "version": "1.0.2", 55 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 56 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 57 | }, 58 | "node_modules/bash-language-server": { 59 | "version": "5.4.3", 60 | "resolved": "https://registry.npmjs.org/bash-language-server/-/bash-language-server-5.4.3.tgz", 61 | "integrity": "sha512-bWpLfob5YAOKKbhxyIldvalP+xrBORrUDZMbcPJAhrhC+xiEVREGV9LfFc01Ce5HhpN+f3sNn+sOYlBf+EO98g==", 62 | "dependencies": { 63 | "editorconfig": "2.0.0", 64 | "fast-glob": "3.3.2", 65 | "fuzzy-search": "3.2.1", 66 | "node-fetch": "2.7.0", 67 | "turndown": "7.2.0", 68 | "vscode-languageserver": "8.0.2", 69 | "vscode-languageserver-textdocument": "1.0.12", 70 | "web-tree-sitter": "0.24.5", 71 | "zod": "3.24.1" 72 | }, 73 | "bin": { 74 | "bash-language-server": "out/cli.js" 75 | }, 76 | "engines": { 77 | "node": ">=16" 78 | } 79 | }, 80 | "node_modules/brace-expansion": { 81 | "version": "2.0.1", 82 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 83 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 84 | "dependencies": { 85 | "balanced-match": "^1.0.0" 86 | } 87 | }, 88 | "node_modules/braces": { 89 | "version": "3.0.3", 90 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 91 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 92 | "dependencies": { 93 | "fill-range": "^7.1.1" 94 | }, 95 | "engines": { 96 | "node": ">=8" 97 | } 98 | }, 99 | "node_modules/commander": { 100 | "version": "11.1.0", 101 | "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", 102 | "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", 103 | "engines": { 104 | "node": ">=16" 105 | } 106 | }, 107 | "node_modules/editorconfig": { 108 | "version": "2.0.0", 109 | "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-2.0.0.tgz", 110 | "integrity": "sha512-s1NQ63WQ7RNXH6Efb2cwuyRlfpbtdZubvfNe4vCuoyGPewNPY7vah8JUSOFBiJ+jr99Qh8t0xKv0oITc1dclgw==", 111 | "dependencies": { 112 | "@one-ini/wasm": "0.1.1", 113 | "commander": "^11.0.0", 114 | "minimatch": "9.0.2", 115 | "semver": "^7.5.3" 116 | }, 117 | "bin": { 118 | "editorconfig": "bin/editorconfig" 119 | }, 120 | "engines": { 121 | "node": ">=16" 122 | } 123 | }, 124 | "node_modules/fast-glob": { 125 | "version": "3.3.2", 126 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 127 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 128 | "dependencies": { 129 | "@nodelib/fs.stat": "^2.0.2", 130 | "@nodelib/fs.walk": "^1.2.3", 131 | "glob-parent": "^5.1.2", 132 | "merge2": "^1.3.0", 133 | "micromatch": "^4.0.4" 134 | }, 135 | "engines": { 136 | "node": ">=8.6.0" 137 | } 138 | }, 139 | "node_modules/fastq": { 140 | "version": "1.16.0", 141 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", 142 | "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", 143 | "dependencies": { 144 | "reusify": "^1.0.4" 145 | } 146 | }, 147 | "node_modules/fill-range": { 148 | "version": "7.1.1", 149 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 150 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 151 | "dependencies": { 152 | "to-regex-range": "^5.0.1" 153 | }, 154 | "engines": { 155 | "node": ">=8" 156 | } 157 | }, 158 | "node_modules/fuzzy-search": { 159 | "version": "3.2.1", 160 | "resolved": "https://registry.npmjs.org/fuzzy-search/-/fuzzy-search-3.2.1.tgz", 161 | "integrity": "sha512-vAcPiyomt1ioKAsAL2uxSABHJ4Ju/e4UeDM+g1OlR0vV4YhLGMNsdLNvZTpEDY4JCSt0E4hASCNM5t2ETtsbyg==" 162 | }, 163 | "node_modules/glob-parent": { 164 | "version": "5.1.2", 165 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 166 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 167 | "dependencies": { 168 | "is-glob": "^4.0.1" 169 | }, 170 | "engines": { 171 | "node": ">= 6" 172 | } 173 | }, 174 | "node_modules/is-extglob": { 175 | "version": "2.1.1", 176 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 177 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 178 | "engines": { 179 | "node": ">=0.10.0" 180 | } 181 | }, 182 | "node_modules/is-glob": { 183 | "version": "4.0.3", 184 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 185 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 186 | "dependencies": { 187 | "is-extglob": "^2.1.1" 188 | }, 189 | "engines": { 190 | "node": ">=0.10.0" 191 | } 192 | }, 193 | "node_modules/is-number": { 194 | "version": "7.0.0", 195 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 196 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 197 | "engines": { 198 | "node": ">=0.12.0" 199 | } 200 | }, 201 | "node_modules/merge2": { 202 | "version": "1.4.1", 203 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 204 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 205 | "engines": { 206 | "node": ">= 8" 207 | } 208 | }, 209 | "node_modules/micromatch": { 210 | "version": "4.0.8", 211 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 212 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 213 | "dependencies": { 214 | "braces": "^3.0.3", 215 | "picomatch": "^2.3.1" 216 | }, 217 | "engines": { 218 | "node": ">=8.6" 219 | } 220 | }, 221 | "node_modules/minimatch": { 222 | "version": "9.0.2", 223 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", 224 | "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", 225 | "dependencies": { 226 | "brace-expansion": "^2.0.1" 227 | }, 228 | "engines": { 229 | "node": ">=16 || 14 >=14.17" 230 | }, 231 | "funding": { 232 | "url": "https://github.com/sponsors/isaacs" 233 | } 234 | }, 235 | "node_modules/node-fetch": { 236 | "version": "2.7.0", 237 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 238 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 239 | "dependencies": { 240 | "whatwg-url": "^5.0.0" 241 | }, 242 | "engines": { 243 | "node": "4.x || >=6.0.0" 244 | }, 245 | "peerDependencies": { 246 | "encoding": "^0.1.0" 247 | }, 248 | "peerDependenciesMeta": { 249 | "encoding": { 250 | "optional": true 251 | } 252 | } 253 | }, 254 | "node_modules/picomatch": { 255 | "version": "2.3.1", 256 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 257 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 258 | "engines": { 259 | "node": ">=8.6" 260 | }, 261 | "funding": { 262 | "url": "https://github.com/sponsors/jonschlinkert" 263 | } 264 | }, 265 | "node_modules/queue-microtask": { 266 | "version": "1.2.3", 267 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 268 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 269 | "funding": [ 270 | { 271 | "type": "github", 272 | "url": "https://github.com/sponsors/feross" 273 | }, 274 | { 275 | "type": "patreon", 276 | "url": "https://www.patreon.com/feross" 277 | }, 278 | { 279 | "type": "consulting", 280 | "url": "https://feross.org/support" 281 | } 282 | ] 283 | }, 284 | "node_modules/reusify": { 285 | "version": "1.0.4", 286 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 287 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 288 | "engines": { 289 | "iojs": ">=1.0.0", 290 | "node": ">=0.10.0" 291 | } 292 | }, 293 | "node_modules/run-parallel": { 294 | "version": "1.2.0", 295 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 296 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 297 | "funding": [ 298 | { 299 | "type": "github", 300 | "url": "https://github.com/sponsors/feross" 301 | }, 302 | { 303 | "type": "patreon", 304 | "url": "https://www.patreon.com/feross" 305 | }, 306 | { 307 | "type": "consulting", 308 | "url": "https://feross.org/support" 309 | } 310 | ], 311 | "dependencies": { 312 | "queue-microtask": "^1.2.2" 313 | } 314 | }, 315 | "node_modules/semver": { 316 | "version": "7.6.2", 317 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", 318 | "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", 319 | "bin": { 320 | "semver": "bin/semver.js" 321 | }, 322 | "engines": { 323 | "node": ">=10" 324 | } 325 | }, 326 | "node_modules/to-regex-range": { 327 | "version": "5.0.1", 328 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 329 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 330 | "dependencies": { 331 | "is-number": "^7.0.0" 332 | }, 333 | "engines": { 334 | "node": ">=8.0" 335 | } 336 | }, 337 | "node_modules/tr46": { 338 | "version": "0.0.3", 339 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 340 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 341 | }, 342 | "node_modules/turndown": { 343 | "version": "7.2.0", 344 | "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", 345 | "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", 346 | "dependencies": { 347 | "@mixmark-io/domino": "^2.2.0" 348 | } 349 | }, 350 | "node_modules/vscode-jsonrpc": { 351 | "version": "8.0.2", 352 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz", 353 | "integrity": "sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==", 354 | "engines": { 355 | "node": ">=14.0.0" 356 | } 357 | }, 358 | "node_modules/vscode-languageserver": { 359 | "version": "8.0.2", 360 | "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.0.2.tgz", 361 | "integrity": "sha512-bpEt2ggPxKzsAOZlXmCJ50bV7VrxwCS5BI4+egUmure/oI/t4OlFzi/YNtVvY24A2UDOZAgwFGgnZPwqSJubkA==", 362 | "dependencies": { 363 | "vscode-languageserver-protocol": "3.17.2" 364 | }, 365 | "bin": { 366 | "installServerIntoExtension": "bin/installServerIntoExtension" 367 | } 368 | }, 369 | "node_modules/vscode-languageserver-protocol": { 370 | "version": "3.17.2", 371 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2.tgz", 372 | "integrity": "sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg==", 373 | "dependencies": { 374 | "vscode-jsonrpc": "8.0.2", 375 | "vscode-languageserver-types": "3.17.2" 376 | } 377 | }, 378 | "node_modules/vscode-languageserver-textdocument": { 379 | "version": "1.0.12", 380 | "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", 381 | "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" 382 | }, 383 | "node_modules/vscode-languageserver-types": { 384 | "version": "3.17.2", 385 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", 386 | "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" 387 | }, 388 | "node_modules/web-tree-sitter": { 389 | "version": "0.24.5", 390 | "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.5.tgz", 391 | "integrity": "sha512-+J/2VSHN8J47gQUAvF8KDadrfz6uFYVjxoxbKWDoXVsH2u7yLdarCnIURnrMA6uSRkgX3SdmqM5BOoQjPdSh5w==" 392 | }, 393 | "node_modules/webidl-conversions": { 394 | "version": "3.0.1", 395 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 396 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 397 | }, 398 | "node_modules/whatwg-url": { 399 | "version": "5.0.0", 400 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 401 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 402 | "dependencies": { 403 | "tr46": "~0.0.3", 404 | "webidl-conversions": "^3.0.0" 405 | } 406 | }, 407 | "node_modules/zod": { 408 | "version": "3.24.1", 409 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", 410 | "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", 411 | "funding": { 412 | "url": "https://github.com/sponsors/colinhacks" 413 | } 414 | } 415 | }, 416 | "dependencies": { 417 | "@mixmark-io/domino": { 418 | "version": "2.2.0", 419 | "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", 420 | "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" 421 | }, 422 | "@nodelib/fs.scandir": { 423 | "version": "2.1.5", 424 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 425 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 426 | "requires": { 427 | "@nodelib/fs.stat": "2.0.5", 428 | "run-parallel": "^1.1.9" 429 | } 430 | }, 431 | "@nodelib/fs.stat": { 432 | "version": "2.0.5", 433 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 434 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" 435 | }, 436 | "@nodelib/fs.walk": { 437 | "version": "1.2.8", 438 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 439 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 440 | "requires": { 441 | "@nodelib/fs.scandir": "2.1.5", 442 | "fastq": "^1.6.0" 443 | } 444 | }, 445 | "@one-ini/wasm": { 446 | "version": "0.1.1", 447 | "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", 448 | "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" 449 | }, 450 | "balanced-match": { 451 | "version": "1.0.2", 452 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 453 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 454 | }, 455 | "bash-language-server": { 456 | "version": "5.4.3", 457 | "resolved": "https://registry.npmjs.org/bash-language-server/-/bash-language-server-5.4.3.tgz", 458 | "integrity": "sha512-bWpLfob5YAOKKbhxyIldvalP+xrBORrUDZMbcPJAhrhC+xiEVREGV9LfFc01Ce5HhpN+f3sNn+sOYlBf+EO98g==", 459 | "requires": { 460 | "editorconfig": "2.0.0", 461 | "fast-glob": "3.3.2", 462 | "fuzzy-search": "3.2.1", 463 | "node-fetch": "2.7.0", 464 | "turndown": "7.2.0", 465 | "vscode-languageserver": "8.0.2", 466 | "vscode-languageserver-textdocument": "1.0.12", 467 | "web-tree-sitter": "0.24.5", 468 | "zod": "3.24.1" 469 | } 470 | }, 471 | "brace-expansion": { 472 | "version": "2.0.1", 473 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 474 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 475 | "requires": { 476 | "balanced-match": "^1.0.0" 477 | } 478 | }, 479 | "braces": { 480 | "version": "3.0.3", 481 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 482 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 483 | "requires": { 484 | "fill-range": "^7.1.1" 485 | } 486 | }, 487 | "commander": { 488 | "version": "11.1.0", 489 | "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", 490 | "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==" 491 | }, 492 | "editorconfig": { 493 | "version": "2.0.0", 494 | "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-2.0.0.tgz", 495 | "integrity": "sha512-s1NQ63WQ7RNXH6Efb2cwuyRlfpbtdZubvfNe4vCuoyGPewNPY7vah8JUSOFBiJ+jr99Qh8t0xKv0oITc1dclgw==", 496 | "requires": { 497 | "@one-ini/wasm": "0.1.1", 498 | "commander": "^11.0.0", 499 | "minimatch": "9.0.2", 500 | "semver": "^7.5.3" 501 | } 502 | }, 503 | "fast-glob": { 504 | "version": "3.3.2", 505 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 506 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 507 | "requires": { 508 | "@nodelib/fs.stat": "^2.0.2", 509 | "@nodelib/fs.walk": "^1.2.3", 510 | "glob-parent": "^5.1.2", 511 | "merge2": "^1.3.0", 512 | "micromatch": "^4.0.4" 513 | } 514 | }, 515 | "fastq": { 516 | "version": "1.16.0", 517 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", 518 | "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", 519 | "requires": { 520 | "reusify": "^1.0.4" 521 | } 522 | }, 523 | "fill-range": { 524 | "version": "7.1.1", 525 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 526 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 527 | "requires": { 528 | "to-regex-range": "^5.0.1" 529 | } 530 | }, 531 | "fuzzy-search": { 532 | "version": "3.2.1", 533 | "resolved": "https://registry.npmjs.org/fuzzy-search/-/fuzzy-search-3.2.1.tgz", 534 | "integrity": "sha512-vAcPiyomt1ioKAsAL2uxSABHJ4Ju/e4UeDM+g1OlR0vV4YhLGMNsdLNvZTpEDY4JCSt0E4hASCNM5t2ETtsbyg==" 535 | }, 536 | "glob-parent": { 537 | "version": "5.1.2", 538 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 539 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 540 | "requires": { 541 | "is-glob": "^4.0.1" 542 | } 543 | }, 544 | "is-extglob": { 545 | "version": "2.1.1", 546 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 547 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" 548 | }, 549 | "is-glob": { 550 | "version": "4.0.3", 551 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 552 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 553 | "requires": { 554 | "is-extglob": "^2.1.1" 555 | } 556 | }, 557 | "is-number": { 558 | "version": "7.0.0", 559 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 560 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" 561 | }, 562 | "merge2": { 563 | "version": "1.4.1", 564 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 565 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" 566 | }, 567 | "micromatch": { 568 | "version": "4.0.8", 569 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 570 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 571 | "requires": { 572 | "braces": "^3.0.3", 573 | "picomatch": "^2.3.1" 574 | } 575 | }, 576 | "minimatch": { 577 | "version": "9.0.2", 578 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", 579 | "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", 580 | "requires": { 581 | "brace-expansion": "^2.0.1" 582 | } 583 | }, 584 | "node-fetch": { 585 | "version": "2.7.0", 586 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 587 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 588 | "requires": { 589 | "whatwg-url": "^5.0.0" 590 | } 591 | }, 592 | "picomatch": { 593 | "version": "2.3.1", 594 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 595 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" 596 | }, 597 | "queue-microtask": { 598 | "version": "1.2.3", 599 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 600 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" 601 | }, 602 | "reusify": { 603 | "version": "1.0.4", 604 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 605 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" 606 | }, 607 | "run-parallel": { 608 | "version": "1.2.0", 609 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 610 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 611 | "requires": { 612 | "queue-microtask": "^1.2.2" 613 | } 614 | }, 615 | "semver": { 616 | "version": "7.6.2", 617 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", 618 | "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==" 619 | }, 620 | "to-regex-range": { 621 | "version": "5.0.1", 622 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 623 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 624 | "requires": { 625 | "is-number": "^7.0.0" 626 | } 627 | }, 628 | "tr46": { 629 | "version": "0.0.3", 630 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 631 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 632 | }, 633 | "turndown": { 634 | "version": "7.2.0", 635 | "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", 636 | "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", 637 | "requires": { 638 | "@mixmark-io/domino": "^2.2.0" 639 | } 640 | }, 641 | "vscode-jsonrpc": { 642 | "version": "8.0.2", 643 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz", 644 | "integrity": "sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==" 645 | }, 646 | "vscode-languageserver": { 647 | "version": "8.0.2", 648 | "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.0.2.tgz", 649 | "integrity": "sha512-bpEt2ggPxKzsAOZlXmCJ50bV7VrxwCS5BI4+egUmure/oI/t4OlFzi/YNtVvY24A2UDOZAgwFGgnZPwqSJubkA==", 650 | "requires": { 651 | "vscode-languageserver-protocol": "3.17.2" 652 | } 653 | }, 654 | "vscode-languageserver-protocol": { 655 | "version": "3.17.2", 656 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2.tgz", 657 | "integrity": "sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg==", 658 | "requires": { 659 | "vscode-jsonrpc": "8.0.2", 660 | "vscode-languageserver-types": "3.17.2" 661 | } 662 | }, 663 | "vscode-languageserver-textdocument": { 664 | "version": "1.0.12", 665 | "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", 666 | "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" 667 | }, 668 | "vscode-languageserver-types": { 669 | "version": "3.17.2", 670 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", 671 | "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" 672 | }, 673 | "web-tree-sitter": { 674 | "version": "0.24.5", 675 | "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.5.tgz", 676 | "integrity": "sha512-+J/2VSHN8J47gQUAvF8KDadrfz6uFYVjxoxbKWDoXVsH2u7yLdarCnIURnrMA6uSRkgX3SdmqM5BOoQjPdSh5w==" 677 | }, 678 | "webidl-conversions": { 679 | "version": "3.0.1", 680 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 681 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 682 | }, 683 | "whatwg-url": { 684 | "version": "5.0.0", 685 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 686 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 687 | "requires": { 688 | "tr46": "~0.0.3", 689 | "webidl-conversions": "^3.0.0" 690 | } 691 | }, 692 | "zod": { 693 | "version": "3.24.1", 694 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", 695 | "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==" 696 | } 697 | } 698 | } 699 | -------------------------------------------------------------------------------- /language-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "bash-language-server": "^5.4.3" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "2.0.0": "messages/update_message.md" 3 | } 4 | -------------------------------------------------------------------------------- /messages/update_message.md: -------------------------------------------------------------------------------- 1 | ## 2.0.0 2 | 3 | ### Breaking Changes 4 | 5 | - refactor: migrate settings from `env` to `settings` 6 | 7 | Load settings from `env` have been deprecated on the sever side. 8 | For more details, see the `settings` key of LSP-bash settings. 9 | -------------------------------------------------------------------------------- /plugin/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from .client import LspBashPlugin 4 | 5 | __all__ = ( 6 | # ST: core 7 | "plugin_loaded", 8 | "plugin_unloaded", 9 | # ST: commands 10 | # ST: listeners 11 | # ... 12 | "LspBashPlugin", 13 | ) 14 | 15 | 16 | def plugin_loaded() -> None: 17 | """Executed when this plugin is loaded.""" 18 | LspBashPlugin.setup() 19 | 20 | 21 | def plugin_unloaded() -> None: 22 | """Executed when this plugin is unloaded.""" 23 | LspBashPlugin.cleanup() 24 | -------------------------------------------------------------------------------- /plugin/client.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import json 4 | import os 5 | from typing import Any 6 | 7 | import jmespath 8 | import sublime 9 | from LSP.plugin import DottedDict 10 | from lsp_utils import NpmClientHandler 11 | 12 | from .constants import PACKAGE_NAME 13 | from .log import log_warning 14 | from .template import load_string_template 15 | 16 | 17 | class LspBashPlugin(NpmClientHandler): 18 | package_name = PACKAGE_NAME 19 | server_directory = "language-server" 20 | server_binary_path = os.path.join(server_directory, "node_modules", "bash-language-server", "out", "cli.js") 21 | 22 | server_version = "" 23 | """The version of the language server.""" 24 | 25 | @classmethod 26 | def required_node_version(cls) -> str: 27 | """ 28 | Testing playground at https://semver.npmjs.com 29 | And `0.0.0` means "no restrictions". 30 | """ 31 | return ">=14.18.0" 32 | 33 | @classmethod 34 | def should_ignore(cls, view: sublime.View) -> bool: 35 | return bool( 36 | # SublimeREPL views 37 | view.settings().get("repl") 38 | # syntax test files 39 | or os.path.basename(view.file_name() or "").startswith("syntax_test") 40 | # zsh scripts 41 | or view.match_selector(0, "source.shell.zsh") 42 | ) 43 | 44 | @classmethod 45 | def setup(cls) -> None: 46 | super().setup() 47 | 48 | cls.server_version = cls.parse_server_version() 49 | 50 | def on_settings_changed(self, settings: DottedDict) -> None: 51 | super().on_settings_changed(settings) 52 | 53 | self.update_status_bar_text() 54 | 55 | # -------------- # 56 | # custom methods # 57 | # -------------- # 58 | 59 | def update_status_bar_text(self, extra_variables: dict[str, Any] | None = None) -> None: 60 | if not (session := self.weaksession()): 61 | return 62 | 63 | variables: dict[str, Any] = { 64 | "server_version": self.server_version, 65 | } 66 | 67 | if extra_variables: 68 | variables.update(extra_variables) 69 | 70 | rendered_text = "" 71 | if template_text := str(session.config.settings.get("statusText") or ""): 72 | try: 73 | rendered_text = load_string_template(template_text).render(variables) 74 | except Exception as e: 75 | log_warning(f'Invalid "statusText" template: {e}') 76 | session.set_config_status_async(rendered_text) 77 | 78 | @classmethod 79 | def parse_server_version(cls) -> str: 80 | lock_file_content = sublime.load_resource(f"Packages/{PACKAGE_NAME}/language-server/package-lock.json") 81 | return jmespath.search('dependencies."bash-language-server".version', json.loads(lock_file_content)) or "" 82 | -------------------------------------------------------------------------------- /plugin/constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | assert __package__ 4 | 5 | PACKAGE_NAME = __package__.partition(".")[0] 6 | -------------------------------------------------------------------------------- /plugin/log.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | 5 | import sublime 6 | 7 | from .constants import PACKAGE_NAME 8 | 9 | 10 | def log_debug(message: str) -> None: 11 | print(f"[{PACKAGE_NAME}][DEBUG] {message}") 12 | 13 | 14 | def log_info(message: str) -> None: 15 | print(f"[{PACKAGE_NAME}][INFO] {message}") 16 | 17 | 18 | def log_warning(message: str) -> None: 19 | print(f"[{PACKAGE_NAME}][WARNING] {message}") 20 | 21 | 22 | def log_error(message: str) -> None: 23 | print(f"[{PACKAGE_NAME}][ERROR] {message}") 24 | 25 | 26 | def pluginfy_msg(msg: str, *args: Any, **kwargs: Any) -> str: 27 | return msg.format(*args, _=PACKAGE_NAME, **kwargs) 28 | 29 | 30 | def console_msg(msg: str, *args: Any, **kwargs: Any) -> None: 31 | print(pluginfy_msg(msg, *args, **kwargs)) 32 | 33 | 34 | def status_msg(msg: str, *args: Any, **kwargs: Any) -> None: 35 | sublime.status_message(pluginfy_msg(msg, *args, **kwargs)) 36 | 37 | 38 | def info_box(msg: str, *args: Any, **kwargs: Any) -> None: 39 | sublime.message_dialog(pluginfy_msg(msg, *args, **kwargs)) 40 | 41 | 42 | def error_box(msg: str, *args: Any, **kwargs: Any) -> None: 43 | sublime.error_message(pluginfy_msg(msg, *args, **kwargs)) 44 | -------------------------------------------------------------------------------- /plugin/template.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from functools import lru_cache 4 | 5 | import jinja2 6 | import sublime 7 | 8 | from .constants import PACKAGE_NAME 9 | 10 | JINJA_TEMPLATE_ENV = jinja2.Environment( 11 | extensions=[ 12 | "jinja2.ext.do", 13 | "jinja2.ext.loopcontrols", 14 | ], 15 | ) 16 | 17 | 18 | @lru_cache 19 | def load_string_template(template: str) -> jinja2.Template: 20 | return JINJA_TEMPLATE_ENV.from_string(template) 21 | 22 | 23 | @lru_cache 24 | def load_resource_template(resource_name: str) -> jinja2.Template: 25 | content = sublime.load_resource(f"Packages/{PACKAGE_NAME}/plugin/templates/{resource_name}") 26 | return load_string_template(content) 27 | --------------------------------------------------------------------------------