Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Copilot instructions

Personal Neovim config (Lua, lazy.nvim) for Neovim 0.12+, used on Windows with pwsh for C#/.NET, Go and Vite/React work. CI checks are described in `README.md`.
Personal Neovim config (Lua, lazy.nvim) for Neovim 0.12+, used on Windows with pwsh for C#/.NET, Go, Rust and Vite/React work. CI checks are described in `README.md`.

## Layout

- `init.lua` loads `lua/simonkdev/`: `options.lua`, `keymaps.lua`, `autocmds.lua`, then `lazy_init.lua`, which bootstraps lazy.nvim.
- Plugin specs live in `lua/simonkdev/lazy/`, with `lsp/` and `debugger/` subfolders. Each file returns a lazy.nvim spec.
- Language servers are installed and enabled by mason-lspconfig (`lazy/lsp/mason.lua`) and configured with `vim.lsp.config` (`lazy/lsp/lspconfig.lua`).
- Language servers are installed and enabled by mason-lspconfig (`lazy/lsp/mason.lua`) and configured with `vim.lsp.config` (`lazy/lsp/lspconfig.lua`). The exception is Rust: rustaceanvim (`lazy/rust.lua`) runs the toolchain's rust-analyzer, so never add `rust_analyzer` to mason-lspconfig.
- Per-filetype settings go in `after/ftplugin/<filetype>.lua`.
- `lazy-lock.json` pins every plugin's commit. `tests/smoke.lua` is the headless startup test.
- Treesitter uses nvim-treesitter's `main` branch: it only installs parsers (`lazy/treesitter.lua`), and Neovim's built-in treesitter does highlighting, started per buffer from a FileType autocmd. There is no `nvim-treesitter.configs`.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Other than small retouch the setup is virtually identitcal to Josean's setup, ch

- Neovim 0.12 or later.
- A C compiler on `PATH` (e.g. gcc from MinGW) to build treesitter parsers and telescope-fzf-native. nvim-treesitter also needs the `tree-sitter` CLI, which Mason installs; on a fresh machine parsers install once Mason has it.
- For Rust, rust-analyzer from your toolchain: `rustup component add rust-analyzer`. rustaceanvim starts it (and Mason's codelldb for debugging); don't install rust-analyzer through Mason.

## Updates

Expand All @@ -18,7 +19,7 @@ Other than small retouch the setup is virtually identitcal to Josean's setup, ch
Every pull request (and push to `main`) runs `.github/workflows/ci.yml`:

- **StyLua**: `stylua --check .` using `.stylua.toml`. Fix locally with `stylua .`.
- **Startup smoke test (Windows)**: installs every plugin from `lazy-lock.json` and every treesitter parser into empty directories, opens a Lua and a C# buffer, loads all plugins, and fails on any error. It also checks wiring that wouldn't raise an error: every mason-lspconfig server name resolves to an LSP config, Go/TSX/Lua buffers get the expected formatter and treesitter highlighting, files without a formatter get trailing whitespace trimmed (patches excepted), and web filetypes use 2-space indents. Mason package download failures are ignored because they depend on the network, not the config; language servers aren't installed in headless runs, so they're never started.
- **Startup smoke test (Windows)**: installs every plugin from `lazy-lock.json` and every treesitter parser into empty directories, opens a Lua and a C# buffer, loads all plugins, and fails on any error. It also checks wiring that wouldn't raise an error: every mason-lspconfig server name resolves to an LSP config, Go/TSX/Lua/Rust buffers get the expected formatter and treesitter highlighting, files without a formatter get trailing whitespace trimmed (patches excepted), and web filetypes use 2-space indents. Mason package download failures are ignored because they depend on the network, not the config; language servers aren't installed in headless runs, so they're never started.

Run the smoke test locally from this directory:

Expand Down
12 changes: 12 additions & 0 deletions after/ftplugin/rust.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- :make (<leader>b) runs `cargo build` and loads rustc's errors into the quickfix list
vim.cmd.compiler("cargo")
vim.opt_local.makeprg = "cargo build"

local function map(lhs, subcommand, desc)
vim.keymap.set("n", lhs, function()
vim.cmd.RustLsp(subcommand)
end, { buffer = true, desc = desc })
end
map("<leader>rr", "runnables", "Rust: Runnables")
map("<leader>rd", "debuggables", "Rust: Debuggables")
map("<leader>re", "explainError", "Rust: Explain Error")
1 change: 1 addition & 0 deletions lazy-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"nvim-ts-context-commentstring": { "branch": "main", "commit": "6141a40173c6efa98242dc951ed4b6f892c97027" },
"nvim-web-devicons": { "branch": "master", "commit": "ec309a0eaff6ea967e58c275996155ab5c16938d" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
"rustaceanvim": { "branch": "main", "commit": "9cb125de42c0256ed1bc1f9ded8d8f0381317a17" },
"substitute.nvim": { "branch": "main", "commit": "0d2077398552f069abccbd964a26dd7cd26882cd" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" },
"telescope.nvim": { "branch": "master", "commit": "40aedd8a68c78a656a10a8d62d80c54af59420fb" },
Expand Down
2 changes: 1 addition & 1 deletion lua/simonkdev/lazy/debugger/dap-virtual-text.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ return {
dependencies = {
"mfussenegger/nvim-dap",
},
ft = { "go", "cs" },
ft = { "go", "cs", "rust" },
opts = {},
}
6 changes: 5 additions & 1 deletion lua/simonkdev/lazy/debugger/mason-nvim-dap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ return {
"chrome-debug-adapter",
"js-debug-adapter",
"coreclr",
"codelldb", -- Rust, through rustaceanvim
},
handlers = {
-- rustaceanvim registers codelldb and Rust's debug configurations itself (lazy/rust.lua)
codelldb = function() end,
},
handlers = {},
},
event = "VeryLazy",
}
8 changes: 8 additions & 0 deletions lua/simonkdev/lazy/rust.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Rust: rustaceanvim starts and configures rust-analyzer itself, so don't also enable it through mason-lspconfig.
-- It runs the rust-analyzer on PATH (`rustup component add rust-analyzer`), which matches the toolchain, and
-- debugs with Mason's codelldb, which it finds on its own. Clippy is the on-save checker when it's installed.
return {
"mrcjkb/rustaceanvim",
version = "^9",
lazy = false, -- a filetype plugin that already loads lazily
}
1 change: 1 addition & 0 deletions lua/simonkdev/lazy/testing.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ return {
dap_settings = { type = "coreclr" },
}),
require("neotest-golang")(), -- debugs tests through nvim-dap-go
require("rustaceanvim.neotest"), -- debugs tests through codelldb
},
status = { virtual_text = true },
output = {
Expand Down
2 changes: 2 additions & 0 deletions lua/simonkdev/lazy/treesitter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ return {
"gomod",
"gosum",
"gowork",
"rust",
"toml",
"css",
"html",
"json",
Expand Down
10 changes: 9 additions & 1 deletion tests/smoke.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,22 @@ local function run()
for _, name in ipairs({ "gopls", "ts_ls", "lua_ls", "csharp_ls" }) do
check(vim.tbl_contains(servers, name), name .. " is missing from mason-lspconfig ensure_installed")
end
-- rustaceanvim runs rust-analyzer; a second client from lspconfig would duplicate every result.
check(not vim.lsp.is_enabled("rust_analyzer"), "rust_analyzer is enabled alongside rustaceanvim")
for _, name in ipairs(servers) do
local config = vim.lsp.config[name]
check(config and config.cmd ~= nil, "no LSP config named " .. name)
end

-- Scratch buffers get FileType without BufEnter, so nvim-lint doesn't try to run eslint_d.
local conform = require("conform")
local expected = { go = "goimports", typescriptreact = "prettier", lua = "stylua", text = "trim_whitespace" }
local expected = {
go = "goimports",
typescriptreact = "prettier",
lua = "stylua",
rust = "trim_whitespace", -- after rust-analyzer's rustfmt
text = "trim_whitespace",
}
for ft, formatter in pairs(expected) do
local buf = vim.api.nvim_create_buf(true, true)
vim.bo[buf].filetype = ft
Expand Down
Loading