A Neovim plugin for Godot 4 that brings GDScript/GDShader LSP, DAP debugging, and formatting to your external‑editor workflow.
This plugin helps you to set up:
- LSP support for GDScript and Godot shaders (
.gdshaderfiles) - Godot class docs in Neovim, rendered from the official docs source as Markdown
- Debugging via
nvim-dapfor GDScript - Treesitter syntax highlighting for Godot shader files
- Automatic formatting of
.gdfiles usinggdformat - Optional C# support (user-managed LSP, plus debugging and tooling checks)
- Built-in health checks to verify environment, dependencies, and editor integration
While it is possible to configure Neovim manually for Godot development, this plugin simplifies setup and ensures a consistent, cross-platform workflow. It automatically configures LSP, debugging, formatting, and environment checks, so you can focus on writing game code rather than troubleshooting editor setup.
- Why godotdev.nvim?
- Features
- Requirements
- Installation (Lazy.nvim)
- Installation (
vim.pack, Neovim 0.12+) - Quickstart
- Configuration
- Testing
- Optimize Godot editor for Neovim
- Open scripts from Godot Editor in Neovim (running in a terminal)
- Godot editor server
- Reconnect to Godot's LSP server
- Run Godot
- Godot class docs
- C# Installation Support
- Autoformatting / Indentation
- Recommended Godot addon (Node Copy)
- Hiding Godot Project Files in oil.nvim and mini.files
- Turn Neovim into a first‑class external editor for Godot 4 projects.
- Get LSP features for GDScript/GDShader without manual wiring.
- Debug GDScript via DAP and validate setup with built‑in health checks.
Below is a quick overview of what you get out of the box:
- Full GDScript language support (Go to definition, references, hover, rename, code actions, etc.)
.gdshadersyntax highlighting and language features via Treesitter- Optional C# LSP support (user-managed
csharp-lsor OmniSharp) for Godot projects with C# scripts
- Debug GDScript directly from Neovim using
nvim-dap - Optional C# debugging via
netcoredbg
- Automatic
.gdfile formatting usinggdtoolkit - Reloads buffer after formatting for immediate feedback
- Recommended
.editorconfigincluded for consistent indentation (4 spaces per indent)
:checkhealth godotdevvalidates:- Built-in Neovim LSP support plus plugin dependencies:
nvim-dap,nvim-dap-ui,nvim-treesitter - Godot editor LSP and debug servers
- Floating Godot docs support (
curland active docs source configuration) - Optional C# tooling:
dotnet,csharp-ls/OmniSharp,netcoredbg - Formatter:
gdformat(with installation instructions)
- Built-in Neovim LSP support plus plugin dependencies:
- Commands to start or reconnect to Godot’s editor LSP:
:GodotStartEditorServer:GodotReconnectLSP
- Commands to run Godot from Neovim without DAP:
:GodotRunProject:GodotRunCurrentScene:GodotRunScene {path}:GodotRunScenePicker(optional Telescope integration)
- Commands to open Godot class reference docs:
:GodotDocs [ClassName]:GodotDocsFloat [ClassName]:GodotDocsBuffer [ClassName]:GodotDocsBrowser [ClassName]:GodotDocsCursor
- Automatic LSP attachment for Godot filetypes (
.gd,.gdshader,.gdresource, optional.cs) - Works cross-platform (macOS, Linux, Windows) with TCP or named pipes
- Enable by setting
csharp = trueinrequire("godotdev").setup() - C# LSP is configured by you (the plugin only checks that
csharp-lsor OmniSharp is installed) - Health checks and DAP integration included
- Neovim 0.11+
- Godot 4.x+ with TCP LSP enabled
nvim-dapandnvim-dap-uifor debuggingnvim-treesitter- Windows users must have
ncatin PATH - Optional C# support requires (you manage the LSP configuration):
- .NET SDK (dotnet)
- C# LSP server (csharp-ls recommended or omnisharp)
- netcoredbg debugger
{
'Mathijs-Bakker/godotdev.nvim',
dependencies = { 'nvim-dap', 'nvim-dap-ui', 'nvim-treesitter' },
}vim.pack.add({
"https://github.com/Mathijs-Bakker/godotdev.nvim",
"https://github.com/mfussenegger/nvim-dap",
"https://github.com/rcarriga/nvim-dap-ui",
"https://github.com/nvim-treesitter/nvim-treesitter",
})- Open your Godot project in Neovim
- Start Godot editor with TCP LSP enabled (Editor Settings → Network → Enable TCP LSP server)
- Open a
.gdor.gdshaderfile - LSP will automatically attach
- Use Neovim's built-in LSP mappings such as
K,grr,grn, andgri, or your own custom mappings - Start debugging with DAP (Launch scene configuration)
- Optional: Enable C# support by setting
csharp = truein the plugin setup - Run
:checkhealth godotdevat any time to verify plugin, LSP, debug server, and C# dependencies
require("godotdev").setup({
editor_host = "127.0.0.1", -- Godot editor host
editor_port = 6005, -- Godot LSP port
debug_port = 6006, -- Godot debugger port
csharp = true, -- Enable C# Installation Support
autostart_editor_server = false, -- opt-in: start a Neovim server automatically on setup
formatter = "gdformat", -- "gdformat" | "gdscript-format" | false
formatter_cmd = nil, -- string or argv list, e.g. { "gdscript-format", "--check" }
editor_server = {
address = nil, -- nil uses the current server or the platform default
remove_stale_socket = true,
},
treesitter = {
auto_setup = true, -- convenience default; disable if you manage nvim-treesitter yourself
ensure_installed = { "gdscript" },
},
docs = {
renderer = "float", -- default: open docs in a floating window
fallback_renderer = "browser", -- nil | "browser" | "buffer"; browser is the only fetch-recovery fallback
missing_symbol_feedback = "message", -- "message" | "notify"
version = "stable", -- e.g. "stable", "latest", "4.5"
language = "en",
source_ref = "master", -- godot-docs git ref used for floating docs
source_base_url = nil, -- optional override for raw docs source
timeout_ms = 10000,
cache = {
enabled = true,
max_entries = 64,
},
float = {
width = 0.8,
height = 0.8,
border = "rounded",
},
buffer = {
position = "right", -- "right" | "bottom" | "current"
size = 0.4,
},
},
})For formatter commands with flags, prefer an argv list:
formatter_cmd = { "gdscript-format", "--check" }To disable autoformat-on-save entirely:
formatter = falseIf you already manage nvim-treesitter yourself, you can disable plugin-managed setup:
treesitter = {
auto_setup = false,
}Default notes:
autostart_editor_server = falseis the safer default because starting a Neovim server is an external-editor concern and should be opt-in.treesitter.auto_setup = truestays enabled by default for convenience, but it is safe to turn off if you already configurenvim-treesitteryourself.docs.fallback_renderer = "browser"remains the default because browser fallback is the only option that can recover when rendered.rstdocs cannot be fetched.- The plugin uses Neovim's built-in LSP APIs;
nvim-lspconfigis not required unless you want it for other servers in your own config.
Note: This plugin does not define any keymaps by default, so it will not interfere with the standard DAP mappings. If you want custom keybindings, you can configure them yourself. For example, you could map :GDebug to DapNew to start one or more new debug sessions.
See :help dap-mappings and :help dap-user-commands for more details.
Additional references:
Run the headless test suite:
nvim --headless -u NONE -i NONE -c "lua dofile('tests/run.lua')" -c qaThe same command runs in GitHub Actions on pushes to master and on pull requests.
For integration testing, also run the plugin inside Neovim against a real Godot project and verify editor server, docs, formatting, and debugging flows on your target platform.
Below are the recommended settings for configuring the Godot editor for optimal integration with Neovim as your external editor. To access these settings, make sure that the Advanced Settings switch is enabled at the top of the Editor Settings dialog.
-
Editor Settings > Text Editor > Behavior > Auto Reload Scripts on External Change -
Editor Settings > Interface > Editor > Save on Focus Loss -
Editor Settings > Interface > Editor > Import Resources When Unfocused
When you click on a gdscript in Godot's FileSystem dock it doesn't open automatically in Neovim. A workaround is to to create a small script which launches the file in Neovim.
Complete instructions here
If you start Neovim with --listen on macOS/Linux, use the documented godotdev wrapper instead of raw nvim --listen ... so stale socket files are cleaned up automatically after crashes. If your wrapper still reports Neovim server already running at /tmp/godot.pipe after you already quit, update its probe to use nvr --nostart --servername ... --remote-expr '1'.
- Set Neovim to listen on a TCP port
--listen works with host:port on Windows.
nvim --listen 127.0.0.1:6666
- Tell Godot to connect to that port
In Godot, configure your external editor or plugin to connect to
127.0.0.1:6666. Make sure the TCP port you choose is free and consistent between Neovim and Godot.
🤌🫶🏻🥹❤️🩹 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. 🙏
You can manually start the Neovim editor server used by Godot:
:GodotStartEditorServerIf Neovim is already running with --listen, the plugin will reuse that address instead of trying to start a second server.
Or automatically on plugin setup:
require("godotdev").setup({
autostart_editor_server = true,
})You can also pin a specific address:
require("godotdev").setup({
autostart_editor_server = true,
editor_server = {
address = "/tmp/godot.pipe",
},
})On macOS/Linux, plugin-managed startup removes stale Unix socket files before retrying. This hardens :GodotStartEditorServer, but it does not affect a raw shell launch like nvim --listen /tmp/godot.pipe, because that failure happens before the plugin loads.
If the LSP disconnects or you opened a script before Neovim, run:
:GodotReconnectLSPReconnects all Godot buffers to the LSP.
You can run the current Godot project or scene from Neovim without using DAP:
:GodotRunProject
:GodotRunCurrentScene
:GodotRunScene scenes/Main.tscn
:GodotRunScenePickerNotes:
:GodotRunProjectlaunches Godot for the current project root.:GodotRunCurrentSceneworks from a.tscn, or from a.gd/.csbuffer when that script is attached to a scene in the current project.- If the current script is attached to multiple scenes, the command uses Telescope to let you choose one when Telescope is installed.
:GodotRunScene {path}acceptsres://..., a project-relative path, or an absolute path inside the current project.:GodotRunScenePickeruses Telescope to browse.tscnfiles in the current project and run the selected scene.- These commands shell out to
godoton yourPATH. :GodotRunScenePickerrequires Telescope to be installed; the rest do not.
Open the official Godot class reference from Neovim:
:GodotDocs NodeBy default, :GodotDocs renders the docs in a floating window. You can also:
:GodotDocsFloat Node
:GodotDocsBuffer Node
:GodotDocsBrowser Node
:GodotDocsCursor- If
:GodotDocsis called without an argument, it uses the symbol under the cursor. Browser opening uses your configured system opener. - Float and buffer rendering fetch the class reference source from
godotengine/godot-docswithcurl, converts the.rstto markdown, and displays that inside Neovim. :GodotDocsBufferreuses a scratch markdown buffer so the docs stay open while you keep working.- Configure persistent buffer placement with
docs.buffer.position = "right" | "bottom" | "current"anddocs.buffer.size = 0.4. - Docs fetches and rendered markdown are cached in memory by default. Configure this with
docs.cache.enabledanddocs.cache.max_entries. - The float and buffer renderers use the
markdownfiletype, so Markdown rendering plugins such as MeanderingProgrammer/render-markdown.nvim can improve its presentation. docs.fallback_renderer = "browser"is the only fallback that can recover when the rendered.rstsource cannot be fetched. Abufferfallback only changes presentation after rendering succeeds.- When a symbol does not resolve to a Godot class page, the plugin shows a regular Neovim message by default. Set
docs.missing_symbol_feedback = "notify"if you prefer notifications instead.
ℹ️ Recommended docs mapping:
vim.keymap.set("n", "gK", "<cmd>GodotDocs<cr>", { desc = "Godot docs" })If you prefer a leader mapping instead:
vim.keymap.set("n", "<leader>gd", "<cmd>GodotDocs<cr>", { desc = "Godot docs" })Why gK:
Kis commonly LSP hover under cursor.- ✅
gKis close enough semantically to “keyword docs” and is usually free. gd,gD,grare already established LSP/navigation motions.- ✅
<leader>gdreads likegodotdocs. - It fits well because
:GodotDocsalready defaults to the symbol under cursor.
- Enable by setting
csharp = trueinrequire("godotdev").setup() - C# LSP setup is user-managed;
:checkhealth godotdevwill only verify tooling is installed:- .NET SDK (
dotnet) - C# LSP server (
csharp-lsoromnisharp) - Debugger (
netcoredbg)
- .NET SDK (
Godot expects spaces, 4 per indent (for both GDScript and C#).
This plugin automatically sets buffer options for .gd files.
Additionally, .gd files are autoformatted on save with gdtoolkit unless you set formatter = false:
Make sure gdformat is installed and in your PATH. If not, you will see a warning notification.
For more info on indentation: :help godotdev-indent
If you use godotdev.nvim as your main external-editor workflow, the companion addon
godotdev.nvim-node-copy
is recommended.
Why it helps:
- Godot's built-in external editor integration does not provide drag-and-drop of nodes into Neovim.
- The addon adds copy actions for selected nodes in the Scene Tree and 2D editor, so you can paste useful references directly into your script.
- It keeps the workflow explicit and safe: select a node in Godot, copy the reference you want, then paste it at the cursor in Neovim.
It currently supports copying:
- node paths
$Nodereferencesget_node(...)expressions- typed
@onready varsnippets - C# property snippets
Godot generates files and folders like .uid, .import, or .godot/ that can clutter your file explorer.
You can hide them in both oil.nvim and mini.files by filtering against their patterns.
Show me how


