diff --git a/README.md b/README.md index fe1255d..411c15b 100644 --- a/README.md +++ b/README.md @@ -356,6 +356,8 @@ If you start Neovim with `--listen` on macOS/Linux, use the documented `godotdev If you run Neovim in WSL2 and Godot on Windows, use the dedicated bridge workflow in [Windows + WSL2 external editor](doc/windows-wsl2.md). +For GDScript LSP in that setup, the recommended bridge is [`godot-wsl-lsp`](https://github.com/lucasecdb/godot-wsl-lsp). + > 🤌🫶🏻🥹❤️‍🩹 REQUEST: > I am not using Windows, so I did not test any of this. It would be great if anyone could help me to validate this and report your findings [here](https://github.com/Mathijs-Bakker/godotdev.nvim/issues/21). :pray: diff --git a/doc/godotdev.txt b/doc/godotdev.txt index 09271b0..77293b0 100644 --- a/doc/godotdev.txt +++ b/doc/godotdev.txt @@ -209,6 +209,8 @@ Windows: nvim --listen 127.0.0.1:6666 2. Configure Godot to connect to the same host:port. +If you run Neovim in WSL2 and Godot on Windows, see `doc/windows-wsl2.md` for the bridge workflow and `godot-wsl-lsp` for GDScript LSP. + ============================================================================== Reconnect LSP *godotdev-reconnect* @@ -316,6 +318,8 @@ Health checks *godotdev-checkhealth* Use `:checkhealth godotdev` to verify and troubleshoot: +If this plugin detects a WSL2 environment, the health report includes a `WSL2 bridge` section with the recommended bridge documentation and `godot-wsl-lsp` link. + Dependencies: - Built-in Neovim LSP support - nvim-treesitter diff --git a/doc/windows-wsl2.md b/doc/windows-wsl2.md index 22141cb..bbe519a 100644 --- a/doc/windows-wsl2.md +++ b/doc/windows-wsl2.md @@ -18,6 +18,13 @@ The bridge works in two steps: - Neovim started in WSL with `--listen`, or through the `godotdev` wrapper from this repository - `wsl.exe` available from Windows, which is standard on recent Windows installations with WSL enabled +For the GDScript LSP itself, the recommended option is the community bridge `godot-wsl-lsp`. It sits between Neovim in WSL and the Godot LSP server on Windows and rewrites Windows and WSL paths in both directions. + +- Repository: https://github.com/lucasecdb/godot-wsl-lsp +- Package summary: https://npm.io/package/godot-wsl-lsp + +`checkhealth godotdev` will also mention this bridge when it detects a WSL environment. + Microsoft documents both the WSL localhost forwarding behavior and Windows/Linux file-system interop: - Windows can reach services listening inside WSL on `localhost` when localhost forwarding is enabled. @@ -53,6 +60,14 @@ $env:GODOT_WSL_DISTRO = "Ubuntu" $env:GODOT_NVIM_SOCKET = "/tmp/godot.nvim" ``` +5. For GDScript LSP, install and run `godot-wsl-lsp` inside WSL instead of connecting Neovim directly to Godot. + +```bash +npm install -g godot-wsl-lsp +``` + +Then point your GDScript LSP setup at `godot-wsl-lsp` as described by the bridge project. + ## Script The bridge script is provided in this repository at: @@ -70,6 +85,6 @@ The current bridge uses the file and line arguments. The column is accepted for ## Notes - This is only for the editor open-file workflow. -- It does not change the plugin's LSP or DAP behavior. +- It does not change the plugin's DAP behavior. - If you are editing files stored on the Windows filesystem, WSL will see them under `/mnt//...`. - If you want to keep everything on the Linux side, store the project inside the WSL filesystem and open that path from Godot through the bridge. diff --git a/lua/godotdev/health.lua b/lua/godotdev/health.lua index 9f8dbbc..c06eb66 100644 --- a/lua/godotdev/health.lua +++ b/lua/godotdev/health.lua @@ -17,6 +17,12 @@ end local is_windows = uv.os_uname().sysname == "Windows_NT" +local function is_wsl() + local uname = uv.os_uname() + local release = (uname and uname.release or ""):lower() + return release:find("microsoft", 1, true) ~= nil or vim.env.WSL_DISTRO_NAME ~= nil +end + local function run_command(argv, opts) local ok, job = pcall(vim.system, argv, vim.tbl_extend("keep", opts or {}, { text = true })) if not ok then @@ -198,6 +204,17 @@ Windows: 'ncat' not found. Install via Scoop or Chocolatey: end end +local function report_wsl_bridge() + if not is_wsl() then + return + end + + health.start("WSL2 bridge") + health.info("WSL2 detected.") + health.info("If Godot runs on Windows and Neovim runs in WSL2, use the bridge doc: doc/windows-wsl2.md") + health.info("For GDScript LSP in that setup, use: https://github.com/lucasecdb/godot-wsl-lsp") +end + local function report_csharp() if not godotdev.opts.csharp then health.info("C# checks skipped (csharp=false)") @@ -289,6 +306,7 @@ function M.check() report_godot_detection() report_editor_server() report_windows_dependencies() + report_wsl_bridge() report_csharp() report_docs() report_formatter() diff --git a/tests/spec_health.lua b/tests/spec_health.lua index c45bba0..2061e45 100644 --- a/tests/spec_health.lua +++ b/tests/spec_health.lua @@ -478,4 +478,70 @@ return { h.assert_truthy(joined_ok:match("Godot editor debug server detected on port 6006") ~= nil) end, }, + { + name = "health reports the WSL2 bridge guidance when running under WSL", + run = function() + local recorder = make_health_recorder() + + h.with_temp("health", recorder.api, function() + h.with_package("godotdev", { + opts = { + csharp = false, + docs = { renderer = "browser", source_ref = "master" }, + formatter = false, + formatter_cmd = nil, + }, + }, function() + h.with_package("nvim-treesitter.configs", {}, function() + h.with_package("dapui", {}, function() + h.clear_module("godotdev.health") + h.with_field(vim.uv, "os_uname", function() + return { + sysname = "Linux", + release = "5.15.90.1-microsoft-standard-WSL2", + } + end, function() + local health = require("godotdev.health") + + h.with_field(vim.fn, "exists", function(cmd) + if cmd == ":LspInfo" or cmd == ":DapContinue" then + return 2 + end + return 0 + end, function() + h.with_field(vim.fn, "executable", function(name) + if name == "nc" then + return 0 + end + return 1 + end, function() + h.with_field(vim.fn, "systemlist", function() + return {} + end, function() + h.with_field(vim, "system", function(argv, _opts) + return { + wait = function() + if argv[1] == "godot" then + return { code = 0, stdout = "4.3.stable\n", stderr = "" } + end + return { code = 0, stdout = "", stderr = "" } + end, + } + end, function() + health.check() + end) + end) + end) + end) + end) + end) + end) + end) + end) + + local joined_info = table.concat(recorder.calls.info, "\n") + h.assert_truthy(joined_info:match("WSL2 detected") ~= nil) + h.assert_truthy(joined_info:match("godot%-wsl%-lsp") ~= nil) + end, + }, }