{"id":32126251,"url":"https://github.com/tikoci/lsp-routeros-ts","last_synced_at":"2026-02-21T10:31:54.548Z","repository":{"id":298252870,"uuid":"999266979","full_name":"tikoci/lsp-routeros-ts","owner":"tikoci","description":"RouterOS LSP for syntax checking and accurate completions in VSCode, NeoVim, and others.","archived":false,"fork":false,"pushed_at":"2025-07-22T16:21:43.000Z","size":482,"stargazers_count":14,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-12-09T09:29:38.161Z","etag":null,"topics":["lsp","mikrotik","neovim-plugin","routeros","vscode","vscode-extension","vscode-language"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tikoci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-10T02:09:46.000Z","updated_at":"2025-11-18T07:05:47.000Z","dependencies_parsed_at":"2025-06-10T07:03:04.989Z","dependency_job_id":"437bcf6a-e0a7-4d77-8b19-99e45399965d","html_url":"https://github.com/tikoci/lsp-routeros-ts","commit_stats":null,"previous_names":["tikoci/lsp-routeros-ts"],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/tikoci/lsp-routeros-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikoci%2Flsp-routeros-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikoci%2Flsp-routeros-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikoci%2Flsp-routeros-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikoci%2Flsp-routeros-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tikoci","download_url":"https://codeload.github.com/tikoci/lsp-routeros-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikoci%2Flsp-routeros-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29679049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T09:33:50.764Z","status":"ssl_error","status_checked_at":"2026-02-21T09:33:19.949Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lsp","mikrotik","neovim-plugin","routeros","vscode","vscode-extension","vscode-language"],"created_at":"2025-10-20T23:21:08.705Z","updated_at":"2026-02-21T10:31:54.541Z","avatar_url":"https://github.com/tikoci.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# RouterOS LSP\n\n![LSP running VSCode GIF](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNDl4NXg5ZXB0YWd2Z2s5b2t0Z2t6enN6Y3NmbTRsZ2o5dWM3MTJqMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/Rm4TUg15fUuUhHVvSx/giphy.gif)\n\nThe RouterOS LSP can be installed into most LSP clients.  Specifically, the following LSP capacities are supported:\n  * completion (\"tab completion\")\n  * semantic tokens (colorization)\n  * diagnostics (\"Problems\" in VSCode terms)\n  * configuration (connection to RouterOS used by LSP)\n  * hover (WIP, currently for debugging found tokens)\n  * symbols (WIP, currently just variables)\n  * _VSCode Only_ \"Walkthrough\" (WIP, shows wizard to setup LSP)\n  * _VSCode Only_ \"Commands\" (via Command Palette) \n\nThe \"trigger\" to load the RouterOS LSP is a file ending in `.rsc` or language being set to `routeros` (typically in bottom right of task bar in VS Code).  In most other clients, you can also force the \"language\" (\"syntax\") type to be \"routeros\". \n\n\u003e [!TIP]\n\u003e\n\u003e Both \"Known Issues\" and a per-version \"Changelog\" (as well as future feature tracking) are now in [`CHANGELOG.md`](https://github.com/tikoci/lsp-routeros-ts/blob/main/CHANGELOG.md) which tracks the _current_ state of affairs for `routeros-lsp-ts`.\n\n## Install and Configuration\n\n### Editor (_LSP client_) Setup \n\nSpecific steps to install for common LSP clients:\n\n### Visual Studio Code (VSCode)\n\n#### Download `prerelease` from \"Extensions\" within VSCode\n\nPrerelease versions are published on the VSCode Marketplace.  Installation of the RouterOS LSP should be similar to other extension.\n\nIf you have VSCode install, use the following link to navigate to the extension within VSCode.  There will be a button for \"Install\" button.  Configuration is required after installation, see \"Configuration\" section below.\n\nhttps://marketplace.visualstudio.com/items?itemName=TIKOCI.lsp-routeros-ts\n\n\u003e [!TIP]\n\u003e\n\u003e Also, please check out – \"TikBook\" – another extension that uses the RouterOS LSP but adds a VSCode's notebook interface for RouterOS script.  Please see the [TikBook VSCode Extension](https://marketplace.visualstudio.com/items?itemName=TIKOCI.tikbook) page for details.\n\nConfiguration is required, specifically **RouterOS credentials must be configured in VSCode settings**...\n\n##### Configuring LSP with Visual Studio Code\n\n\u003e In 0.5.1, you can use the Command Palette to access RouterOS LSP setting.  Typically \u003ckbd\u003e⌘\u003c/kbd\u003e+\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eP\u003c/kbd\u003e (or \u003ckbd\u003eCtrl\u003c/kbd\u003e instead of ⌘ on Windows).  Search for \"RouterOS LSP\" and command will appear for \"Show Settings\".\n\nLaunch VSCode, if not already running. LSP configuration can be done by \"Open User Settings\":\n1. Use \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003e,\u003c/kbd\u003e (on Mac, \u003ckbd\u003e⌘\u003c/kbd\u003e + \u003ckbd\u003e,\u003c/kbd\u003e) to show settings\n2. Select \"Extensions\" from left\n3. Locate \"RouterOS LSP\" section in the list of extensions\n4. Adjust the \"Base URL\" with the IP address and protocol needed (_without_ trailing slash or path), and provide username and password with at least `policy=read,api,rest-api` access to RouterOS\n5. Close the Settings window. Settings should be picked up automatically.\n\n![img](https://i.ibb.co/6JfjhwKT/Screenshot-2025-06-09-at-10-30-05-AM.png)\n\n\u003e ![Router-OS-LSP-as-VSIX-loaded-in-VSCode](https://i.ibb.co/1t1y3kLL/Router-OS-LSP-as-VSIX-loaded-in-VSCode.png)\n\n##### Customizing Colors in VSCode\n\nRouterOS LSP provides \"semantic tokens\" which are used for \"colorization\" and uses custom \"syntax types\" to match RouterOS names and style.  By default, the LSP uses RouterOS's color scheme – so syntax _should_ match RouterOS CLI colors. \n\n\u003e If colors are not shown, or incorrectly match RouterOS CLI, then you can use the \"Refresh Semantic Tokens (Syntax Colors)\" command to refresh them.\n\n\n##### Troubleshooting VSCode and RouterOS LSP\n\nRouterOS LSP logs most operations, perhaps too many.  If there are problems, logs may offer clues and be needed to provide any fix.\n\nIn VSCode, logs go to the \"Output\" view.  To bring up the \"Output\" view, use \u003ckbd\u003eShift\u003c/kbd\u003e + \u003ckbd\u003e⌘\u003c/kbd\u003e + \u003ckbd\u003eU\u003c/kbd\u003e then\nselect \"RouterOS LSP\" from the dropdown at top to show the logs. \n\n\n#### _Alternatively_ Installing a VSCode VSIX file from GitHub Release\n \nInstead, a `VSIX` file is provided with the RouterOS LSP VSCode extension for download via https://github.com/tikoci/lsp-routeros-ts/releases. This will locally install the LSP and VSCode extension needed for RouterOS LSP support.  The VSCode UI does allow for adding the `lsp-routeros-ts-*.vsix`, but the CLI is shown for brevity: \n \n ##### GitHub Download Install\n \n The option lets you pick a version to install, since the \"Extension Marketplace\" will always get latest version.\n \n To download the latest VSIX from Terminal, use:\n ```\n wget -N https://github.com/tikoci/lsp-routeros-ts/releases/latest/download/lsp-routeros-ts.vsix\n ```\n \nAfter downloading the VSIX, to install use the following command, adjusting the download path and file as needed:\n```\ncode --install-extension lsp-routeros-ts.vsix\n```\n##### Removing the VSIX\n\nIf you want to remove the VSIX, use:\n```\ncode --uninstall-extension tikoci.lsp-routeros-ts\n```\n\n#### NeoVim (`nvim`)\n\n![LSP running in NeoVim](https://media4.giphy.com/media/v1.Y2lkPTc5MGI3NjExZDJiOHV6ZDZsamN6bDJxN21zb3hjZ3I2cm5hNDJzbGpqeWtydXAxMyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/reM309KJpRbotDSkL5/giphy.gif)\n\n\n\u003e **NOTE**  Only limited testing has been done using `nvim` – likely many things could be done for\n\u003e a text-mode LSP client like `nvim` (NeoVim).  For example, no testing has been done using common LSP \"managers\" plugins. \n\nA Lua file is provided with the needed code to load the RouterOS LSP, [`nvim-routeros-lsp-init.lua`](https://github.com/tikoci/lsp-routeros-ts/blob/main/nvim-routeros-lsp-init.lua).  This uses the low-level built-in LSP for configuration, but in reality only the \"settings\" Lua code likely needs to be changed (unless bugs ;).\nThe code is loaded from `init.lua`, which is used by `nvim` on startup.  Since there are many schemes possible, exactly where `init.lua` lives your steps may vary.  The following was tested on Mac with homebrew-installed `nvim`.\n\n1. Create or edit the `init.lua`, typically located in `~/config/nvim/init.lua`.  Consult `nvim` docs for locating your `init.lua`.\n1. Download and copy a `lsp-routeros-server-*` for your platform from GitHub to `~/.bin`.  If a different path is used, that will have to be changed in `nvim-routeros-lsp-init.lua`\n2. Add the following line to the `init.lua`:\n ```\n dofile(os.getenv('HOME') .. '/.config/nvim/nvim-routeros-lsp-init.lua')\n ```\n3. Copy [`nvim-routeros-lsp-init.lua`](https://github.com/tikoci/lsp-routeros-ts/nvim-routeros-lsp-init.lua) to the local `~/config/nvim` with the same name - which be called by the `dofile()` in `init.lua`.  Adjust any paths as needed\n4. Adjust settings at top in your copy of `nvim-routeros-lsp-init.lua`.  See \"NeoVim Example Configuration\" section below for more details – critically the RouterOS information must be correct for the LSP to work \u0026 the platform **must** be included in \n5. Launch `nvim` with `*.rsc` file and the LSP should load.  If it loads a message will appear at bottom of `nvim`\n6. To trigger completions, the default in `nvim` is \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eZ\u003c/kbd\u003e followed by \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eO\u003c/kbd\u003e (omni-complete) **while** in `vi` INSERT mode (\u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003ei\u003c/kbd\u003e or \u003ckbd\u003ea\u003c/kbd\u003e).  Again, your configuration may vary.\n\n\u003e On macOS, any downloaded file may be flagged and thus not start with a message that it has been \"blocked\".\n\u003e This is because it lacks code signing, as it was built using GitHub.  \n\u003e To allow the standalone LSP to run, its \"quarantine\" flag must removed using:\n\u003e ```\n\u003e xattr -d com.apple.quarantine ~/.bin/lsp-routeros-server-darwin-x64\n\u003e ```\n\u003e _Adjust path as needed_\n\n\n##### NeoVim Example Configuration\n\nThe following section in example `nvim-routeros-lsp-init.lua` (_i.e. in ~/.bin/nvim) must be **edited** with **correct** RouterOS host and login details, both http:// and https:// are supported by changing the `baseUrl`:\n```lua\nlocal settings = {\n routeroslsp = {\n maxNumberOfProblems = 100,\n baseUrl = \"http://192.168.88.1\",\n username = \"lsp\",\n password = \"changeme\",\n hotlock = true\n }\n}\n```\n\n\u003e In same file, the **platform** must be included in `local lspexe =...` variable.  The \"default\" uses just `lsp-routeros-server` – which is what a local build will produce – but if using a packaged or downloaded LSP binary, this needs to include the right platform.  For example, using macOS on Apple Silicon the name of the executable LSP is `lsp-routeros-server-darwin-arm64`, the top line in `nvim-routeros-lsp-init.lua` becomes\n\u003e ```lua\n\u003e local lspexec =  { os.getenv(\"HOME\") .. \"/.bin/lsp-routeros-server-darwin-arm64\", \"--stdio\" }\n\u003e ```\n\u003e Additionally `lspexec` must use the correct path — so be careful since `lspexec` is a **2** element \"array\", with `--stdio` argument being the _2nd_ element, while the 1st uses `..` concatenates the user home directory (`os.getenv(\"HOME\")`) with the default path to LSP binary.  But `lspexe` must be an array and `--stdio` must be provided for LSP to function.\n\n\n#### Other LSP clients\n\nOther LSP clients (\"editors\") should work, if the LSP client supports the \"configuration capacity\" API.  LSP configuration may vary substantially between editors – but configuration variables shown above in `LspSettings` **must** be provided somehow to the LSP client editor.  \n\n\u003e The LSP spec's `workspace/configuration` (\"configuration capability\") is **required** for all LSP clients – since that is how RouterOS connection information is obtained.  Without it, the LSP will use the default configuration and be un-configurable by the user (since defaults are compiled in code).  Both `nvim` and VSCode support `workspace/configuration`, most other editors with LSP do too.\n\n### Settings and Configuration\n\n_more cleanup need_\n\n#### LSP `workspace/configuration` Options\n\nThe supported settings are defined as:\n```typescript\ninterface LspSettings {\n  baseUrl: string;     // \"http://192.168.88.1\"\n  username: string;    // \"lsp\"\n  password: string;    // \"changeme\"\n  apiTimeout: number   // 15 \n  allowClientProvidedCredentials: boolean //true\n}\n```\n\n### Enabling RouterOS REST API in RouterOS\n\n**For all LSP clients, the REST API must be allowed in RouterOS** and the firewall must allow traffic from the computer running the editor to the router.  \n\nBy default on RouterOS, unsecured HTTP access is enabled.  To enable HTTPS, if not already enabled, use:\n```\n/certificate/enable-ssl-certificate \n/ip/service enable www-ssl\n```\n_RouterOS LSP defaults to plain HTTP, so LSP configuration needs to change from http:// to https://_ when configuring an editor._\n\nUsing a different RouterOS account with lower permissions is recommended.  The LSP default configuration assumes a user named \"lsp\", that can be created using:\n```\n/user/group add name=list policy=read,api,rest-api\n/user add name=lsp password=changeme group=lsp\n```\n\n\u003e ### Security Considerations\n\u003e \n\u003e RouterOS LSP does not use \"write\" or \"sensitive\" policies.  As such, it is highly recommended to avoid using \"full\" users in the configuration.  Instead, a new RouterOS user can be used to limit the needed permissions.  \n\n\n\u003e [!TIP]\n\u003e\n\u003e A virtual machine can be used with the \"free\" version of RouterOS's \"CHR\" as the `baseUrl`.  This approach avoids storing any \"real\" router's password in the LSP configuration.  For Mac, UTM can be used as the host, and tikoci's \"mikropkl\" has ready-to-use images can bring up RouterOS CHR in a few steps, see [tikoci/mikropkl](https://github.com/tikoci/mikropkl) for details. \n\n\nOn the router, either the \"www\" or \"www-ssl\" service must be enabled, and accessible to any editor using the LSP server.  Firewall configuration may need to be adjusted, but beyond the scope here. \n\nWhen using \"https://\" (TLS), the certificate chain must be valid from the LSP client editor. So self-signed certificates on REST API may not work out-of-box.\n\n\u003e Also the LSP has **no** \"allow unsafe certificates\" option, so the router TLS certificate (and/or it's CAs and intermediates) must be installed via OS into the system's \"keychain\" (certificate store).\n\n## Features and Usage \n\n_section under development_\n\n![](https://i.ibb.co/d4C7x7xy/VS-Code-LSP-Commands.png)\n\n#### Available Commands in Visual Studio Code\n\n  * **Test RouterOS Connection** - verifies LSP has working connection to RouterOS \n  * **Refresh Semantic Tokens** - forces re-calculation of color for open docs in editor\n  * **Show Logs (Output)** - shows VS Code \"Output\" window, with \"RouterOS LSP\" selected\n  * **Show Settings** - shows RouterOS LSP settings, including RouterOS credentials\n  * **Apply Semantic Color Overrides to Settings** - if applied, allows manual tweaking of colors in \"Settings (JSON)\"\n\n### Unicode Handling\n\nFor syntax checking and colorization any characters outside of `us-ascii` (\"lower ASCII\") are encoded as a `_` when checked by RouterOS `/console/inspect`.  This keeps character indexes the same between RouterOS's Windows1252 and VS Code's UTF-16 internal representation, even through UTF-8 is used by HTTP.  \n\nSince unicode characters are not in path/cmd/attributes/etc, the LSP can substitute any high-ASCII characters with a `_` since they cannot be \"syntax\", only comments and similar - which all use 'none' token anyway.  This  _should_ be harmless as the replaced character are only used as input when processing to get tokens, so editing and saving are unaffected.  As such, script files can use any codepage or Unicode encoding in editor.  \n\nAlthough remains possible some unknown \"corner cases\" could cause tokens to be misaligned, any codepage/unicode will be always preserved in script files, in all cases.  _i.e._ LSP will never change or convert _your_ file, just it's representation to RouterOS `/console/inspect` _e.g._ with _any_ high-ASCII encoded as `_`.  \n\n\u003e If you find issues where colors are off by a few characters, and not fixed by a \"Refresh Semantic Tokens\" commands, please report in GitHub [issues](https://github.com/tikoci/lsp-routeros-ts/issues) and include your script with problem.\n\n\u003e #### Background on RouterOS and Unicode\n\u003e RouterOS does not support unicode, although it will accept UTF-8 in some UIs and locations (_i.e._ webfig, REST).  In fact, the OS does not actually know unicode - it just pass the bytes through its single-byte string type.  Historically RouterOS has used Windows1252 (or another) codepage, so LSP cannot just assume all strings are UTF-8 as other MikroTik clients (WinBox, Dude) may use codepages and locale.  \n\u003e\n\u003eComplicating this further is LSP protocol internally uses UTF-16, but when serialized via HTTP to RouterOS it \"becomes\" UTF-8.  However, the UTF-8 adds more characters to output returned \"highlight\" semantic tokens too - so the index between editor position and highlight token is off by \"extra\" bytes in multi-byte UTF-8 characters.  This gets confusing quick for the LSP that needs to match RouterOS highlights to the editors \"position\" (line#/col#), with RouterOS \"highlights\" (semantic tokens) using index into string array not line/cols.\n\n\n## Implementation and Development\n\nThe code uses Microsoft's node/TypeScript bun library [vscode-languageserver-node](https://github.com/microsoft/vscode-languageserver-node), with some implementation coming from Microsoft's VSCode [`lsp-*` extension examples][sample].\nWhile this allows first-class support for Visual Studio Code (\"VSCode\"), the LSP server also work with other editors - either via `node` or using TypeScript compiled by `bun build --compile` into a standalone executable.\n\nTo provide \"AST-like\" data to the LSP, HTTP/S REST calls to a running RouterOS device to retrieve data from `/console/inspect`, specifically `request=highlight` and `request=completion` operations.  Using `/console/inspect` via REST means the LSP is always matched to a specific RouterOS version's AST — so newer commands and attributes will automatically be available simply by upgrading the connected RouterOS.  But this also means **without a running RouterOS device, the LSP will cannot function.**  \n\n### Building LSP\n\n\u003e All TypeScript packaging is done using `bun`.  It is recommended to install `bun` using your OS package manager or from https://bun.sh.  Although `bun` can still be used for local development, since no specific `bun` syntax is used.\n\nThe LSP can be built using just `bun`.\n\n1. Clone this repo, and `cd` to the root directory of the repo\n2. Run `bun install` \n3. Run `bun compile`\n\nAfter which the LSP server will be generated as `./server/dist/server.js`, and can be invoked using `node` to start the server.\n\n### Packaging LSP\n\nThe project supports a few packaging methods, mainly one for VSCode and a standalone binary for all other LSP clients.\n\n#### VSCode using `vsix` package\nThe RouterOS LSP can be built to a `.vsix` file for Visual Studio Code use.  A `vsix` file can be manually install the LSP and associated VSCode language extension.\nTo built the `lsp-routeros-ts-x.y.z.vsix` file from repo root directory, use:\n```\nbun run vsix:package\n```\nThe file can be installed using `code --install-extension lsp-routeros-ts-*.vsix`.  Alternatively `bun run vsix:install` which will _both build and install_ the RouterOS LSP.  To remove the LSP/extension use `bun run vsix:remove`.\n\n\n#### Standalone LSP Server (using `bun build --compile`)\nTo create a single file executable, `bun run bun:exe` can be used.  This will compile the TypeScript and dependencies into an executable (for current platform/OS).  Additionally, it installs to `~/.bin/lsp-routeros-server`, which matches the example `nvim` configuration file in `nvim-routeros-lsp-init.lua`. `lsp-routeros-server` also support options to control which LSP protocol to listen on:\n  * `--node-ipc` - use by VSCode for streaming JSON\n  * `--stdio` - user by `nvim` and most LSP clients that exec() it and use stdin and stdout for LSP messages\n  * `--socket=\u003cport\u003e` - similar to `--stdio` but listens on TCP socket specified in the option\n\n\u003e `--socket` is untested.  In the future, this _could_ enable the LSP to live in a RouterOS `/container` - so the LSP Server be the same as router with `/console/inspect` API, allowing syntax to always be in-sync.  \n\n\n### Developing the LSP using VSCode\n\nThe source code is at [GitHub](https://github.com/tikoci/lsp-routeros-ts) and can be cloned for local development.  To modify the project, VSCode is recommended since it has good debugging tools and other support for LSP development.   Additionally, see Microsoft's [debugging instructions][debug] for using VSCode \"Extension Development Host\" support.\n\n\n#### Project Structure\n\nThe most important files used in the code are below.  Many other files are used,\nbut most are generated by some tool or mostly boilerplate that does not effect\noperation of the LSP itself.\n\n\n```\n.\n├── .github\n│   └── workflows\n│       └── build.yaml      // build script use in GitHub Actions CI\n├── .vscode\n│   ├── launch.json         // Tells VS Code how to launch our extension\n│   └── tasks.json          // Tells VS Code how to build our extension\n├── .vscodeignore           // VSIX creator (`vsce`) uses to exclude files\n├── .gitignore              // `git` uses to prevent checkin of some files (like binaries)\n├── icon.png                // used by VSIX package (manually generated from SVG)\n├── icon.svg                // \"source\" to the `png` icon used by VSIX package\n├── LICENSE\n├── README.md\n├── client\n│   ├── language-configuration.json   // define basics of RouterOS to VSCode\n│   ├── package.json        // extension client node dependencies\n│   └── src\n│       └── *.ts    // \"shim\" between VSCode and LSP server\n├── package.json            // both Makefile and manifest \u0026 stores config schema\n├── server\n│   ├── package.json        // LSP server node dependencies\n│   └── src\n│       └── *.ts       // LSP server code\n└── nvim-routeros-lsp-init.lua    // `init.lua` code to add LSP to `nvim`\n```\n\nAs a result of various build processes, the following \"artifacts\" are produced as \"outputs\":\n```\n.\n├── client\n│   └── out\n|       ├── extension.js      // compiled TypeScript from `.ts` \n│       └── extension.js.map  // used by debugger/errors to map line# between `js` and `ts`\n├── server\n│   └── out\n|       ├── server.js         // compiled `.ts` - can use to start LSP using \nnode ./server/dist/server.js`\n│       └── server.map.js     // used by debugger/errors to map line# between `js` and `ts`\n├── lsp-routeros-server                   // always same platform as build system (used for development/locally)\n├── lsp-routeros-server-darwin-x64        // macOS \"Intel\" - static binary of `server.ts`\n├── lsp-routeros-server-darwin-arm64      // macOS \"Silicon\" - static binary of `server.ts` \n├── lsp-routeros-server-linux-x64         // Linux - static binary of `server.ts`\n├── lsp-routeros-server-linux-arm64       // Linux (aarch64) - static binary of `server.ts`\n├── lsp-routeros-server-linux-x64-musl    // Alpine - static binary of `server.ts`\n├── lsp-routeros-server-linux-arm64-musl  // Alpine (aarch64) - static binary of `server.ts`\n├── lsp-routeros-server-windows-x64.exe   // Windows - static binary of `server.ts`\n├── lsp-routeros-server-windows-arm64.exe // Windows for ARM - static binary of `server.ts`\n└── lsp-routeros-ts-0.1.0.vsix            // Packaged and downloadable version of VSCode LSP extension\n\n```\n\n#### `bun run` Scripts\n\nSome \"helper scripts\" for developers can be run use `bun run \u003cscriptname\u003e`, \nand maintained in the `package.json` in root directory.  The common \"user facing\" `\u003cscriptname\u003e` being:\n  *   `compile`: run TypeScript compiler (\"tsc -b\") for server and client\n  *   `vsix:package`: \"bun run postinstall \u0026\u0026 rm -f *.vsix \u0026\u0026 vsce package\",\n  *   `vsix:install`: install the VSIX file locally for `tikoci.lsp-routeros-ts`\n  *   `vsix:remove`: removes the VSIX file locally for `tikoci.lsp-routeros-ts`\n  *   `bun:exe`: builds `lsp-routeros-server` for local OS/platform\n  *   `nvim:install`: for local development use to install (or re-install) into NeoVim (`nvim`)\n\n\u003e The `bun run` scripts are mainly for local development.  The GitHub Action CI generally directly invokes tools.  For example, to cross-compile for various platforms, `build.yaml` will just call `bun --compiler` directly and NOT use `bun run bun:exe`.\n\n#### ID Fields\n\nIn many places some \"id\" field is used, to clarify naming:\n* `lsp-routeros-ts` is generally used to refer to the entire project, the `-ts` refers that the LSP is implemented in **T**ype**S**cript – as it possible to implement the LSP in other languages\n* `lsp-routeros-server-*` refers to just the actual LSP **server** code or build products\n* `vscode-lsp-routeros` refers to the VSCode-specific \"language extension\" that \"binds\" the LSP server with VSCode extension ecosystem, but largely \"proxies\" VSCode requests into the LSP server code.\n* `routeroslsp` is used when `-` is cannot be used for name, like configuration (\"settings\") and also the \"server\" `package.json` to ensure alignment with configuration.\n\n\n### Understanding LSP Protocols\nThere are a few dozen APIs that make up an LSP Server.  The ones implemented by RouterOS LSP are listed at top of page.  For a richer experience (i.e. more \"help\" from LSP in editor), additional protocols _could_ be implemented.  This section attempts to catalog from LSP protocol to implementation to \"real features\".\n\n#### LSP Specification\n\nThe [official LSP specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#languageFeatures) is what really defines possible language features:\n\n\n* Go to Declaration\n* Go to Definition\n* Go to Type Definition\n* Go to Implementation\n* Find References\n* Prepare Call Hierarchy\n* Call Hierarchy Incoming Calls\n* Call Hierarchy Outgoing Calls\n* Prepare Type Hierarchy\n* Type Hierarchy Super Types\n* Type Hierarchy Sub Types\n* Document Highlight\n* Document Link\n* Document Link Resolve\n* Hover\n* Code Lens\n* Code Lens Refresh\n* Folding Range\n* Selection Range\n* Document Symbols\n* Semantic Tokens\n* Inline Value\n* Inline Value Refresh\n* Inlay Hint\n* Inlay Hint Resolve\n* Inlay Hint Refresh\n* Moniker\n* Completion Proposals\n* Completion Item Resolve\n* Publish Diagnostics\n* Pull Diagnostics\n* Signature Help\n* Code Action\n* Code Action Resolve\n* Document Color\n* Color Presentation\n* Formatting\n* Range Formatting\n* On type Formatting\n* Rename\n* Prepare Rename\n* Linked Editing Range\n\nThe spec is pretty abstract, since LSP servers support a few transports, so\n_how_ to implement them depends on the library – but the list above gives the \"full menu\" of LSP language features.\n\n#### Microsoft's `vscode-languageserver`\n\nThe RouterOS LSP implementation uses Microsoft's `vscode-languageserver` Node library, and the documentation describes many of the LSP protocols and using with the library.  The following tables is from the [VSCode docs on Language Extensions](https://code.visualstudio.com/api/language-extensions/programmatic-language-features#language-features-listing), which gives a sense of the possibilities:\n\n| VS Code API | LSP method |\n| --- | --- |\n| [`createDiagnosticCollection`](https://code.visualstudio.com/api/references/vscode-api#languages.createDiagnosticCollection) | [PublishDiagnostics](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics) |\n| [`registerCompletionItemProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerCompletionItemProvider) | [Completion](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) \u0026 [Completion Resolve](https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve) |\n| [`registerHoverProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerHoverProvider) | [Hover](https://microsoft.github.io/language-server-protocol/specification#textDocument_hover) |\n| [`registerSignatureHelpProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerSignatureHelpProvider) | [SignatureHelp](https://microsoft.github.io/language-server-protocol/specification#textDocument_signatureHelp) |\n| [`registerDefinitionProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerDefinitionProvider) | [Definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) |\n| [`registerTypeDefinitionProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerTypeDefinitionProvider) | [TypeDefinition](https://microsoft.github.io/language-server-protocol/specification#textDocument_typeDefinition) |\n| [`registerImplementationProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerImplementationProvider) | [Implementation](https://microsoft.github.io/language-server-protocol/specification#textDocument_implementation) |\n| [`registerReferenceProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerReferenceProvider) | [References](https://microsoft.github.io/language-server-protocol/specification#textDocument_references) |\n| [`registerDocumentHighlightProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerDocumentHighlightProvider) | [DocumentHighlight](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight) |\n| [`registerDocumentSymbolProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerDocumentSymbolProvider) | [DocumentSymbol](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol) |\n| [`registerCodeActionsProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerCodeActionsProvider) | [CodeAction](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeAction) |\n| [`registerCodeLensProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerCodeLensProvider) | [CodeLens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens) \u0026 [CodeLens Resolve](https://microsoft.github.io/language-server-protocol/specification#codeLens_resolve) |\n| [`registerDocumentLinkProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerDocumentLinkProvider) | [DocumentLink](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentLink) \u0026 [DocumentLink Resolve](https://microsoft.github.io/language-server-protocol/specification#documentLink_resolve) |\n| [`registerColorProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerColorProvider) | [DocumentColor](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentColor) \u0026 [Color Presentation](https://microsoft.github.io/language-server-protocol/specification#textDocument_colorPresentation) |\n| [`registerDocumentFormattingEditProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerDocumentFormattingEditProvider) | [Formatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting) |\n| [`registerDocumentRangeFormattingEditProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerDocumentRangeFormattingEditProvider) | [RangeFormatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_rangeFormatting) |\n| [`registerOnTypeFormattingEditProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerOnTypeFormattingEditProvider) | [OnTypeFormatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_onTypeFormatting) |\n| [`registerRenameProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerRenameProvider) | [Rename](https://microsoft.github.io/language-server-protocol/specification#textDocument_rename) \u0026 [Prepare Rename](https://microsoft.github.io/language-server-protocol/specification#textDocument_prepareRename) |\n| [`registerFoldingRangeProvider`](https://code.visualstudio.com/api/references/vscode-api#languages.registerFoldingRangeProvider) | [FoldingRange](https://microsoft.github.io/language-server-protocol/specification#textDocument_foldingRange)\n\n\n#### langserver.org\n https://langserver.org tracks supported protocols against LSPs, with an LSP \"declaring\" their support (\"Implemented\", \"WIP\", \"Not implemented\", \"Not applicable\"). Classifying RouterOS LSP in this scheme:\n  * ✅ **Implemented** - Code completion - _could be improved but functional_\n  * 💡 **WIP*** - Hover - _only shows highlight \"syntax\" codes but does \"something\"_\n  * 🚫 **Not implemented** - Jump to def - _somewhat possible but need complex multi-step process and still be lossy and error prone_\n  * ❓ **WIP** - Workspace symbols - _semantic tokens supported, unsure if same_\n  * 🚫 **Not implemented** - Find references - _similar to \"Jump to def\"_ \n  * ✅ **Implemented** - Diagnostics - _could be improved, but do flag the first error found_\n\n \u003e #### langserver.org also tracks \"Additional capabilities\" like:\n \u003e * **Automatic dependency management** - `Not applicable` - _Language servers that support this feature are able to resolve / install a project's 3rd-party dependencies without the need for a user to manually intervene._\n \u003e * **No arbitrary code execution** - `Implemented` - _Language servers that support this feature don't execute arbitrary code (some language servers do this when running build scripts, analyzing the project, etc.)._\n \u003e * **Tree View Protocol** - `Not implemented` - _Language servers that support this feature are able to render tree views. See this link for more information._\n \u003e * **Decoration Protocol** - `Not implemented` - _Language servers that support this feature are able to provide text to be displayed as \"non-editable\" text in the text editor. See this link for more information._\n\n#### Microsoft Sample LSP Code\n\nSee https://github.com/microsoft/vscode-extension-sample, for example \"[Code Actions](https://github.com/microsoft/vscode-extension-samples/blob/main/lsp-user-input-sample/server/src/sampleServer.ts)\" \n\n#### Implementation \"Tips and Tricks\"\n\nSome various notes that are not obvious from docs or specific to RouterOS\n\n##### Position vs Offset\n\nThe `vscode-languageserver` library provides a \"position\" generally, which is line and char position.  But for programmatic use the \"index\" into an array with code is often more useful, this is called \"offset\" in the library.  The \"offset\" is more useful with /console/inspect. To handle this, the `TextDocument` object supports an `offsetAt()` and `positionAt()` to enable conversion from the two forms. \n\n##### `/console/inspect request=syntax`\n\nNot currently used — but be useful.  It's not used since it requires \"tricks\" to get useful information for completions and other things.\nFor example, to get useful data, stuff like a \u003ckbd\u003espace\u003c/kbd\u003e or \u003ckbd\u003e=\u003c/kbd\u003e may need to be added to `input=` — even though it does not exist in loaded script/config.\n\nFor now, just documenting how `/console/inspect` with `request=syntax` works in various cases:\n\n###### \"TEXT\" in output could provide a \"description\" to some LSP data for a \"dir\"\n```\n\u003e /console/inspect request=syntax input=\"/ip/route add\" \nColumns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT\nTYPE    SYMBOL   SYMBOL-TYPE  NESTED  NONORM  TEXT                                                                    \nsyntax           collection        0  yes                                                                             \nsyntax  ..       explanation       1  no      go up to ip                                                             \nsyntax  add      explanation       1  no      Create a new item                                                       \nsyntax  check    explanation       1  no                                                                              \nsyntax  comment  explanation       1  no      Set static route comment                                                \nsyntax  disable  explanation       1  no      Disable route                                                           \nsyntax  edit     explanation       1  no                                                                              \nsyntax  enable   explanation       1  no      Enable route                                                            \nsyntax  export   explanation       1  no      Print or save an export script that can be used to restore configuration\nsyntax  find     explanation       1  no      Find items by value                                                     \nsyntax  get      explanation       1  no      Gets value of item's property                                           \nsyntax  print    explanation       1  no      Print values of item properties                                         \nsyntax  remove   explanation       1  no      Remove route                                                            \nsyntax  reset    explanation       1  no                                                                              \nsyntax  set      explanation       1  no      Change item properties                                                  \nsyntax  unset    explanation       1  no         \n```\n\n###### Adding a fake \u003ckbd\u003espace\u003c/kbd\u003e to `input` gets \"arg\"'s for a \"cmd\"\n```\n\u003e /console/inspect request=syntax input=\"/ip/route add \"\nColumns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT\nTYPE    SYMBOL               SYMBOL-TYPE  N  NON  TEXT                                                                                                            \nsyntax                       collection   0  yes                                                                                                                  \nsyntax  blackhole            explanation  1  no                                                                                                                   \nsyntax  check-gateway        explanation  1  no   Whether all nexthops of this route are checking reachability of gateway by sending arp requests every 10 seconds\nsyntax  comment              explanation  1  no   Short description of the item                                                                                   \nsyntax  copy-from            explanation  1  no   Item number                                                                                                     \nsyntax  disabled             explanation  1  no   Defines whether item is ignored or used                                                                         \nsyntax  distance             explanation  1  no   Administrative distance of the route                                                                            \nsyntax  dst-address          explanation  1  no   Destination address                                                                                             \nsyntax  gateway              explanation  1  no                                                                                                                   \nsyntax  pref-src             explanation  1  no                                                                                                                   \nsyntax  routing-table        explanation  1  no                                                                                                                   \nsyntax  scope                explanation  1  no                                                                                                                   \nsyntax  suppress-hw-offload  explanation  1  no                                                                                                                   \nsyntax  target-scope         explanation  1  no                                                                                                                   \nsyntax  vrf-interface        explanation  1  no                 \n```\n\n###### Adding a fake \u003ckbd\u003e=\u003c/kbd\u003e to `input` gets some \"definition\"\n```\n\u003e /console/inspect request=syntax input=\"/ip/route add check-gateway=\"\nColumns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT\nTYPE    SYMBOL        SYMBOL-TYPE  NESTED  NONORM  TEXT             \nsyntax  CheckGateway  definition        0  no                       \nsyntax                definition        1  no      arp | none | ping\n```\nThe issue here being the TEXT is not always well-formed – why `request=completion` is used to retrieve value like above.\nLike for num types there is an expression that shows the _range_ allowed:\n```\n\u003e /console/inspect request=syntax input=\"/ip/service set port=\"\nColumns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT\nTYPE    SYMBOL  SYMBOL-TYPE  NESTED  NONORM  TEXT                        \nsyntax  Port    definition        0  no      Num                         \nsyntax  Num     definition        1  no      1..65535    (integer number)\n```\n\nPoint being the format of TEXT varies a good bit – and requires parsing to make it actionable in LSP - and all without any documentation on `/console/inspect`.\n\n\n\n\n\n---\n[debug]: https://code.visualstudio.com/api/language-extensions/language-server-extension-guide#debugging-both-client-and-server\n[sample]: https://github.com/microsoft/vscode-extension-samples/tree/main/lsp-sample\n[publish]: https://code.visualstudio.com/api/working-with-extensions/publishing-extension\n[vsix]: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#packaging-extensions\n\n\n\n\u003e #### Disclaimers\n\u003e **Not affiliated, associated, authorized, endorsed by, or in any way officially connected with MikroTik, Apple, nor UTM from Turing Software, LLC.**\n\u003e **Any trademarks and/or copyrights remain the property of their respective holders** unless specifically noted otherwise.\n\u003e Use of a term in this document should not be regarded as affecting the validity of any trademark or service mark. Naming of particular products or brands should not be seen as endorsements.\n\u003e MikroTik is a trademark of Mikrotikls SIA.\n\u003e Apple and macOS are trademarks of Apple Inc., registered in the U.S. and other countries and regions. UNIX is a registered trademark of The Open Group. \n\u003e **No liability can be accepted.** No representation or warranty of any kind, express or implied, regarding the accuracy, adequacy, validity, reliability, availability, or completeness of any information is offered.  Use the concepts, code, examples, and other content at your own risk. There may be errors and inaccuracies, that may of course be damaging to your system. Although this is highly unlikely, you should proceed with caution. The author(s) do not accept any responsibility for any damage incurred. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftikoci%2Flsp-routeros-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftikoci%2Flsp-routeros-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftikoci%2Flsp-routeros-ts/lists"}