Refactor LSP, DAP, and gitsigns; add markdown lint config and formatter

- Fix deprecated vim.lsp.stop_client → client:stop(true) in LSP restart
- Preserve virtual_text settings on LSP diagnostic toggle
- Fix LspDetach augroup cleared on every attach (buffer-local autocmds)
- Fix clangd switch_source_header and symbol_info error handling
- Rename preview_hunk_inline keybind <leader>ph → <leader>hP
- Add markdown formatter (prettier) and linter config (.markdownlint.json)
- Unreal C++ auto-init now triggers on BufNewFile
- Python DAP setup wired via mason install event
- Update README with keybind reference and Unreal section
- Rewrite requirements.md as clean plugin-link tables
This commit is contained in:
Arthur Gonze Machado 2026-05-31 17:12:02 -04:00
parent b765b10497
commit 0013b65974
35 changed files with 974 additions and 281 deletions

11
.markdownlint.json Normal file
View File

@ -0,0 +1,11 @@
{
"MD013": false,
"MD012": false,
"MD028": false,
"MD033": false,
"MD034": false,
"MD036": false,
"MD024": false,
"MD041": false,
"MD060": false
}

241
README.md
View File

@ -1 +1,240 @@
This was forked from kickstart.nvim initially and all praise to this amazing project for being an amazing starting point
# Neovim Configuration
This is my personal Neovim configuration, originally forked from [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim) and expanded into a Windows-first setup. It uses [lazy.nvim](https://github.com/folke/lazy.nvim) for plugin management and is aimed at Unreal Engine and game-development workflows, especially C++ and Python. It also supports general-purpose development in Lua, TypeScript, CSS, and HTML.
## Managing Plugins
### Adding a plugin
Create a new file in `lua/plugins/` that returns a lazy.nvim plugin spec table. Those plugin specs are loaded through `lua/setup/lazy.lua`, so keeping each plugin in its own file is the intended workflow.
### Removing a plugin
Delete the plugin file in `lua/plugins/`, empty it, or remove the plugin spec you no longer want. If you want to keep the file around, you can also disable the plugin in place.
### Disabling a plugin temporarily
Add `enabled = false` to the plugin spec table.
```lua
return {
'plugin/name',
enabled = false,
-- other options...
}
```
### Machine-specific paths
Copy `machine.json.template` to `machine.json` (it is gitignored), then fill in the machine-specific paths for `basedpyright`, `clangd`, and optionally `ue_python`.
## Keybinds
Leader key: `<Space>`
### Navigation
| Key | Mode | Action |
| ------------- | ---- | ---------------------------------------- |
| `\` | n | Open file tree (Neo-tree) |
| `<C-h>` | n | Move to left split |
| `<C-j>` | n | Move to lower split |
| `<C-k>` | n | Move to upper split |
| `<C-l>` | n | Move to right split |
| `<A-h>` | n | Resize split left |
| `<A-j>` | n | Resize split down |
| `<A-k>` | n | Resize split up |
| `<A-l>` | n | Resize split right |
| `<C-d>` | n | Scroll half-page down (centered) |
| `<C-u>` | n | Scroll half-page up (centered) |
| `n` / `N` | n | Next/prev search result (centered) |
| `]b` / `[b` | n | Next/prev buffer |
| `]d` / `[d` | n | Next/prev diagnostic |
| `]c` / `[c` | n | Next/prev git hunk (in git buffers) |
| `]q` / `[q` | n | Next/prev quickfix item |
| `j` / `k` | n | Move by visual lines when no count given |
| `<C-h/j/k/l>` | i | Move cursor in insert mode |
| `J` / `K` | v | Move selected lines down/up |
### Search (Telescope)
| Key | Action |
| ------------------ | ------------------------------ |
| `<leader>sf` | Find files |
| `<leader>sg` | Live grep |
| `<leader>sw` | Search current word |
| `<leader>sd` | Search diagnostics |
| `<leader>sh` | Search help tags |
| `<leader>sk` | Search keymaps |
| `<leader>ss` | Select Telescope picker |
| `<leader>sr` | Resume last search |
| `<leader>s.` | Recent files |
| `<leader><leader>` | Find open buffers |
| `<leader>/` | Fuzzy search in current buffer |
| `<leader>s/` | Grep in open files |
| `<leader>sn` | Search Neovim config files |
### LSP
| Key | Action |
| ------------ | ------------------------------------------------------ |
| `grd` | Go to definition (Telescope) |
| `grD` | Go to declaration |
| `grr` | Go to references (Telescope) |
| `gri` | Go to implementation (Telescope) |
| `grt` | Go to type definition (Telescope) |
| `gd` | Go to definition (native) |
| `gO` | Document symbols |
| `gW` | Workspace symbols |
| `K` | Hover documentation |
| `grn` | Rename symbol |
| `<leader>n` | Rename symbol |
| `gra` | Code action (n/x) |
| `<leader>lh` | Toggle inlay hints (per buffer) |
| `<leader>ld` | Toggle diagnostic mode (all lines ↔ current line only) |
| `<leader>li` | Toggle inlay hints (global) |
| `<leader>q` | Send diagnostics to quickfix list |
| `<leader>pi` | Organize imports (Python/basedpyright) |
### Git
| Key | Action |
| ------------ | ------------------------- |
| `<leader>gs` | Git status (fugitive) |
| `<leader>gd` | Git diff split |
| `<leader>gb` | Git blame (fugitive) |
| `<leader>gl` | Git log |
| `<leader>gp` | Git push |
| `<leader>hs` | Stage hunk (n/v) |
| `<leader>hr` | Reset hunk (n/v) |
| `<leader>hS` | Stage buffer |
| `<leader>hu` | Undo stage hunk |
| `<leader>hR` | Reset buffer |
| `<leader>hp` | Preview hunk (popup) |
| `<leader>hP` | Preview hunk inline |
| `<leader>hb` | Blame line |
| `<leader>hd` | Diff against index |
| `<leader>hD` | Diff against last commit |
| `<leader>tb` | Toggle line blame |
| `<leader>tD` | Toggle show deleted lines |
| `<leader>tw` | Toggle word diff |
### Debug (DAP)
| Key | Action |
| ----------- | -------------------------- |
| `<F5>` | Start / Continue |
| `<F1>` | Step into |
| `<F2>` | Step over |
| `<F3>` | Step out |
| `<F7>` | Toggle DAP UI |
| `<leader>b` | Toggle breakpoint |
| `<leader>B` | Set conditional breakpoint |
### Build (CMake)
| Key | Action |
| ------------- | -------------- |
| `<leader>cmg` | CMake Generate |
| `<leader>cmb` | CMake Build |
| `<leader>cmr` | CMake Run |
| `<leader>cmd` | CMake Debug |
| `<leader>cms` | CMake Stop |
### AI
| Key | Action |
| ------------ | --------------------------- |
| `<leader>cc` | CodeCompanion Chat toggle |
| `<leader>ca` | CodeCompanion Actions (n/v) |
| `<leader>cd` | Generate docstring (visual) |
### Toggles & Utilities
| Key | Action |
| ---------------- | -------------------------------------- |
| `<C-\>` | Toggle terminal (float) |
| `<leader>tf` | Toggle floating terminal |
| `<leader>th` | Toggle horizontal terminal |
| `<Esc>` | Clear search highlight |
| `<Space><Space>` | Clear search highlight |
| `<leader>jk` | Escape (n/v/i/t) |
| `<leader>p` | Paste over selection (v, no overwrite) |
| `<leader>d` | Delete to black hole (n/v) |
### Commands (no keybind, but worth knowing)
| Command | Action |
| --------------------------------- | ---------------------------------- |
| `:LspRestart <name>` | Restart a named LSP server |
| `:LspInfo` | Show comprehensive LSP info |
| `:LspStatus` | Show LSP clients on current buffer |
| `:LspCapabilities` | Show LSP capabilities |
| `:LspDiagnostics` | Show diagnostic counts |
| `:Unreal` | Manually initialize Unreal-Nvim |
| `:LspPyrightOrganizeImports` | Organize Python imports |
| `:LspPyrightSetPythonPath <path>` | Set Python interpreter path |
## Unreal Engine
### Auto-initialization
Unreal-Nvim auto-initializes when opening:
- `*.uproject`, `*.uplugin`, `*.Build.cs`, `*.Target.cs`
- C/C++ files (`*.cpp`, `*.h`, `*.hpp`, `*.c`) when the cwd contains a `.uproject`
- New C/C++ files created inside a UE project cwd
If auto-init does not trigger, run `:Unreal` manually.
### C++ Workflow
- Open Neovim from the Unreal project root so `clangd` picks up `compile_commands.json` or `compile_flags.txt`
- Use `CMakeGenerate` / `CMakeBuild` (`<leader>cmg`, `<leader>cmb`) or UBT directly
- Debugging uses the `codelldb` adapter via DAP (`<F5>` to start, `<leader>b` for breakpoints)
- `clangd` provides completion, hover, and go-to-definition for UE C++ headers
- You can set a machine-specific `clangd` binary path in `machine.json` under the `clangd` key
### Python (Editor Scripting)
- Open Neovim from the Unreal project root so Python stub detection works correctly
- `basedpyright` picks up `Intermediate/PythonStub` automatically when Unreal-Nvim is initialized
- Plugin Python paths (`Plugins/*/Content/Python`) are added to `extraPaths` automatically
- Set the UE Python interpreter in `machine.json` under the `ue_python` key
- Use `<leader>pi` to organize imports
- Python debugging uses `debugpy` via DAP (`<F5>`)
## Troubleshooting
### LSP not starting
- Run `:LspInfo` to check whether a client is attached
- Ensure the language server binary is on `PATH` or configured in `machine.json`
- Run `:LspRestart <name>` to force-restart a specific server
### Plugins not loading
- Run `:Lazy` to open the plugin manager UI
- Check `:Lazy log` for errors
- Run `:Lazy sync` to update all plugins
### machine.json missing
- Copy `machine.json.template` to `machine.json` and fill in the required paths
- Without it, LSP servers fall back to binaries on `PATH`, which may or may not work on your system
### Python debugging fails on first launch
- On first run, Mason installs `debugpy` in the background; Python DAP is wired automatically once installation completes
- If it still fails, restart Neovim and try again
### Unreal LSP/Python not working
- Ensure Neovim is opened from the Unreal project root (the directory containing the `.uproject`)
- Run `:Unreal` to manually trigger Unreal-Nvim initialization
- Check that `ue_python` is set in `machine.json` for the correct UE Python interpreter
### Clangd not finding headers
- Ensure a `compile_commands.json` or `compile_flags.txt` exists in the project root (generated by CMake or UBT)
- Set the `clangd` path in `machine.json` if you use a custom LLVM build

View File

@ -1,24 +0,0 @@
================================================================================
INTRODUCTION *kickstart.nvim*
Kickstart.nvim is a project to help you get started on your neovim journey.
*kickstart-is-not*
It is not:
- Complete framework for every plugin under the sun
- Place to add every plugin that could ever be useful
*kickstart-is*
It is:
- Somewhere that has a good start for the most common "IDE" type features:
- autocompletion
- goto-definition
- find references
- fuzzy finding
- and hinting at what more can be done :)
- A place to _kickstart_ your journey.
- You should fork this project and use/modify it so that it matches your
style and preferences. If you don't want to do that, there are probably
other projects that would fit much better for you (and that's great!)!
vim:tw=78:ts=8:ft=help:norl:

View File

@ -1,3 +0,0 @@
kickstart-is kickstart.txt /*kickstart-is*
kickstart-is-not kickstart.txt /*kickstart-is-not*
kickstart.nvim kickstart.txt /*kickstart.nvim*

View File

@ -2,11 +2,12 @@
"CopilotChat.nvim": { "branch": "main", "commit": "9fec6c3c2a4069b1f649e116c10e6fbcf1463764" },
"LuaSnip": { "branch": "master", "commit": "5a1e39223db9a0498024a77b8441169d260c8c25" },
"Unreal-Nvim": { "branch": "main", "commit": "b0991bbd83645717cc0b3c98dd1fbf6ee7684c25" },
"blink-cmp-copilot": { "branch": "main", "commit": "439cff78780c033aa23cf061d7315314b347e3c1" },
"blink.cmp": { "branch": "main", "commit": "451168851e8e2466bc97ee3e026c3dcb9141ce07" },
"cmake-tools.nvim": { "branch": "master", "commit": "906fd4816bf4d588162d5ec78830456f0d969c5f" },
"codecompanion.nvim": { "branch": "main", "commit": "78203ccaa36469b4a212123c7d532e2367ad9dd4" },
"conform.nvim": { "branch": "master", "commit": "086a40dc7ed8242c03be9f47fbcee68699cc2395" },
"copilot.vim": { "branch": "release", "commit": "a12fd5672110c8aa7e3c8419e28c96943ca179be" },
"copilot.lua": { "branch": "master", "commit": "e8b9be2e51c393bedc893cef3bd1c5555a4d45f5" },
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
"fidget.nvim": { "branch": "main", "commit": "7fa433a83118a70fe24c1ce88d5f0bd3453c0970" },
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
@ -27,7 +28,6 @@
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" },
"nvim-dap": { "branch": "master", "commit": "2a8799ad91a1495c6bdf753f9b2179b3ff0f5bba" },
"nvim-dap-go": { "branch": "main", "commit": "b4421153ead5d726603b02743ea40cf26a51ed5f" },
"nvim-dap-python": { "branch": "master", "commit": "1808458eba2b18f178f990e01376941a42c7f93b" },
"nvim-dap-ui": { "branch": "master", "commit": "f5b6673f374626515401c5bc51b005f784a4f252" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" },

View File

@ -1,24 +1,38 @@
local machine = require('machine')
local function set_python_path(path)
local clients = vim.lsp.get_clients {
bufnr = vim.api.nvim_get_current_buf(),
name = 'basedpyright',
}
for _, client in ipairs(clients) do
client.config.settings = vim.tbl_deep_extend('force', client.config.settings or {}, { python = { pythonPath = path } })
if client.settings then
client.settings.python = vim.tbl_deep_extend('force', client.settings.python or {}, { pythonPath = path })
else
client.config.settings = vim.tbl_deep_extend('force', client.config.settings, { python = { pythonPath = path } })
end
client.notify('workspace/didChangeConfiguration', { settings = nil })
client.notify('workspace/didChangeConfiguration', { settings = client.config.settings })
end
end
local function is_ue_project()
local ok, unreal_nvim = pcall(require, 'unreal-nvim')
if ok and unreal_nvim.find_uproject and unreal_nvim.find_uproject() then
return true
end
return vim.fn.glob(vim.fn.getcwd() .. '/*.uproject') ~= ''
end
local function get_python_path()
local venv_path = os.getenv 'VIRTUAL_ENV'
if venv_path then
return venv_path .. '/scripts/python.exe'
end
return 'C:/Program Files/Epic Games/UE_5.7/Engine/Binaries/ThirdParty/Python3/Win64/python.exe'
if is_ue_project() then
local ue_python = machine.get('ue_python', nil)
if ue_python then return ue_python end
end
local python_on_path = vim.fn.exepath('python')
return python_on_path ~= '' and python_on_path or 'python'
end
local function get_current_ue_python_stub()
@ -40,13 +54,14 @@ local function get_ue_python_plugins()
if ue_project then
local ue_folder = ue_project:match '^(.*[\\/])'
local ue_plugins = ue_folder .. 'Plugins\\'
local handle = vim.loop.fs_scandir(ue_plugins)
local handle = vim.uv.fs_scandir(ue_plugins)
if not handle then return folders end
while true do
local name, t = vim.loop.fs_scandir_next(handle)
local name, t = vim.uv.fs_scandir_next(handle)
if not name then break end
if t == 'directory' then
local plugin_folder = ue_plugins .. name .. '\\Content\\Python'
local stat = vim.loop.fs_stat(plugin_folder)
local stat = vim.uv.fs_stat(plugin_folder)
if stat ~= nil and stat.type == 'directory' then
table.insert(folders, plugin_folder)
end
@ -67,7 +82,7 @@ local function get_extra_paths()
end
return {
cmd = { 'D:\\language-servers\\basedpyright\\Scripts\\basedpyright-langserver.exe', '--stdio' },
cmd = { machine.get('basedpyright', vim.fn.exepath('basedpyright-langserver')), '--stdio' },
filetypes = { 'python' },
root_markers = {
'pyproject.toml',
@ -95,7 +110,7 @@ return {
autoImportCompletions = true,
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'workspace',
diagnosticMode = 'openFilesOnly',
extraPaths = get_extra_paths(),
},
},
@ -109,10 +124,14 @@ return {
}
end, { desc = 'Organize Imports' })
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightSetPythonPath', set_python_path, {
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightSetPythonPath', function(opts)
set_python_path(opts.args)
end, {
desc = 'Reconfigure basedpyright with the provided python path',
nargs = 1,
complete = 'file',
})
vim.keymap.set('n', '<leader>pi', '<cmd>LspPyrightOrganizeImports<CR>', { buffer = bufnr, desc = '[P]ython Organize [I]mports' })
end,
}

View File

@ -1,3 +1,5 @@
local machine = require('machine')
local function switch_source_header(bufnr)
local method_name = 'textDocument/switchSourceHeader'
local client = vim.lsp.get_clients({ bufnr = bufnr, name = 'clangd' })[1]
@ -7,7 +9,8 @@ local function switch_source_header(bufnr)
local params = vim.lsp.util.make_text_document_params(bufnr)
client.request(method_name, params, function(err, result)
if err then
error(tostring(err))
vim.notify(tostring(err), vim.log.levels.ERROR)
return
end
if not result then
vim.notify 'corresponding file cannot be determined'
@ -26,7 +29,7 @@ local function symbol_info()
local win = vim.api.nvim_get_current_win()
local params = vim.lsp.util.make_position_params(win, clangd_client.offset_encoding)
clangd_client.request('textDocument/symbolInfo', params, function(err, res)
if err or #res == 0 then
if err or not res or #res == 0 then
-- Clangd always returns an error, there is not reason to parse it
return
end
@ -47,7 +50,7 @@ end
---@field offsetEncoding? string
return {
cmd = { 'D:\\language-servers\\clangd\\bin\\clangd.exe' },
cmd = { machine.get('clangd', vim.fn.exepath('clangd')) },
filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' },
root_markers = {
'.clangd',
@ -81,5 +84,9 @@ return {
vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdShowSymbolInfo', function()
symbol_info()
end, { desc = 'Show symbol info' })
vim.keymap.set('n', '<leader>ch', function()
switch_source_header(bufnr)
end, { buffer = bufnr, desc = '[C]langd Switch [H]eader/Source' })
end,
}

View File

@ -1,17 +0,0 @@
-- Get virtual env if active otherwise get the unreal python
local function get_python_path()
local venv_path = os.getenv 'VIRTUAL_ENV'
if venv_path then
return venv_path .. '/scripts/python.exe'
end
return 'C:\\Program Files\\Epic Games\\UE_5.6.0\\Engine\\Binaries\\ThirdParty\\Python3\\Win64\\python.exe'
end
return {
cmd = { 'D:\\language-servers\\tylsp\\Scripts\\ty', 'server' },
filetypes = { 'python' },
root_markers = { 'ty.toml', 'pyproject.toml', '.git' },
environment = {
python = get_python_path(),
},
}

View File

@ -1,5 +0,0 @@
return {
cmd = { 'C:/user_data/language-servers/typos/extension/bundled/typos-lsp.exe' },
cmd_env = { RUST_LOG = 'error' },
root_markers = { 'typos.toml', '_typos.toml', '.typos.toml', 'pyproject.toml', 'Cargo.toml' },
}

30
lua/machine.lua Normal file
View File

@ -0,0 +1,30 @@
-- machine.lua
-- Loads machine-specific paths from machine.json in the config directory.
-- Copy machine.json.template to machine.json and fill in your paths.
local M = {}
local _cache = nil
local function load()
local path = vim.fn.stdpath('config') .. '/machine.json'
local f = io.open(path, 'r')
if not f then return {} end
local content = f:read('*a')
f:close()
local ok, data = pcall(vim.fn.json_decode, content)
return (ok and type(data) == 'table') and data or {}
end
--- Get a machine-specific path by key.
--- Falls back to `fallback` if the key is missing or empty.
---@param key string
---@param fallback string|nil
---@return string|nil
function M.get(key, fallback)
if not _cache then _cache = load() end
local val = _cache[key]
if val and val ~= '' then return val end
return fallback
end
return M

View File

@ -23,6 +23,8 @@ return {
opts = {},
},
'folke/lazydev.nvim',
'zbirenbaum/copilot.lua',
'giuxtaposition/blink-cmp-copilot',
},
opts = {
-- 'default' (recommended) for mappings similar to built-in completions (C-y to accept)
@ -38,9 +40,10 @@ return {
documentation = { auto_show = false, auto_show_delay_ms = 200 },
},
sources = {
default = { 'lsp', 'path', 'snippets', 'lazydev', 'buffer' },
default = { 'lsp', 'path', 'snippets', 'lazydev', 'buffer', 'copilot' },
providers = {
lazydev = { module = 'lazydev.integrations.blink', score_offset = 100 },
copilot = { module = 'blink-cmp-copilot', score_offset = 100, async = true },
},
},
snippets = { preset = 'luasnip' },

View File

@ -2,5 +2,12 @@ return {
'Civitasv/cmake-tools.nvim',
dependencies = { 'nvim-lua/plenary.nvim' },
ft = { 'c', 'cpp' },
keys = {
{ '<leader>cmg', '<cmd>CMakeGenerate<CR>', desc = '[C]Make [G]enerate' },
{ '<leader>cmb', '<cmd>CMakeBuild<CR>', desc = '[C]Make [B]uild' },
{ '<leader>cmr', '<cmd>CMakeRun<CR>', desc = '[C]Make [R]un' },
{ '<leader>cmd', '<cmd>CMakeDebug<CR>', desc = '[C]Make [D]ebug' },
{ '<leader>cms', '<cmd>CMakeStop<CR>', desc = '[C]Make [S]top' },
},
opts = {},
}

View File

@ -29,7 +29,7 @@ return {
lua = { 'stylua' },
c = { 'clang_format' },
cpp = { 'clang_format' },
python = { 'isort', 'black' },
python = { 'ruff_format', 'ruff_organize_imports' },
javascript = { 'prettier' },
typescript = { 'prettier' },
javascriptreact = { 'prettier' },
@ -37,6 +37,7 @@ return {
json = { 'prettier' },
html = { 'prettier' },
css = { 'prettier' },
markdown = { 'prettier' },
},
},
}

View File

@ -1,7 +1,8 @@
return {
'CopilotC-Nvim/CopilotChat.nvim',
cmd = { 'CopilotChat', 'CopilotChatToggle', 'CopilotChatOpen' },
dependencies = {
'github/copilot.vim',
'zbirenbaum/copilot.lua',
'nvim-lua/plenary.nvim',
},
opts = {

View File

@ -1,4 +1,10 @@
return {
'github/copilot.vim',
event = 'InsertEnter',
{
'zbirenbaum/copilot.lua',
event = 'InsertEnter',
opts = {
suggestion = { enabled = false }, -- handled by blink.cmp
panel = { enabled = false },
},
},
}

View File

@ -22,7 +22,6 @@ return {
'jay-babu/mason-nvim-dap.nvim',
-- Add your own debuggers here
'leoluz/nvim-dap-go',
'theHamsta/nvim-dap-virtual-text',
'mfussenegger/nvim-dap-python',
},
@ -96,10 +95,41 @@ return {
-- online, please don't ask me how to install them :)
ensure_installed = {
-- Update this to ensure that you have the debuggers for the langs you want
'delve',
'codelldb', -- C/C++/Unreal Engine debugging
'debugpy', -- Python debugging
},
}
-- Configure Python debugger using Mason-installed debugpy
local function setup_dap_python()
local ok2, reg = pcall(require, 'mason-registry')
if not ok2 then return end
if not reg.is_installed('debugpy') then return end
local debugpy_path = reg.get_package('debugpy'):get_install_path()
-- Windows uses Scripts/, Unix uses bin/
local python_exec = debugpy_path .. '/venv/Scripts/python.exe'
if vim.fn.filereadable(python_exec) == 0 then
python_exec = debugpy_path .. '/venv/bin/python'
end
require('dap-python').setup(python_exec)
end
-- Configure immediately if already installed
setup_dap_python()
-- Also configure when debugpy finishes installing on first run
local ok_reg, reg2 = pcall(require, 'mason-registry')
if ok_reg then
reg2:on('package:install:success', function(pkg)
if pkg.name == 'debugpy' then
vim.schedule(setup_dap_python)
end
end)
end
-- Configure virtual text for DAP
require('nvim-dap-virtual-text').setup()
-- Dap UI setup
-- For more information, see |:help nvim-dap-ui|
dapui.setup {
@ -138,13 +168,5 @@ return {
dap.listeners.before.event_terminated['dapui_config'] = dapui.close
dap.listeners.before.event_exited['dapui_config'] = dapui.close
-- Install golang specific config
require('dap-go').setup {
delve = {
-- On Windows delve must be run attached or it crashes.
-- See https://github.com/leoluz/nvim-dap-go/blob/main/README.md#configuring
detached = vim.fn.has 'win32' == 0,
},
}
end,
}

View File

@ -44,9 +44,10 @@ return {
map('n', '<leader>hs', gitsigns.stage_hunk, { desc = 'git [s]tage hunk' })
map('n', '<leader>hr', gitsigns.reset_hunk, { desc = 'git [r]eset hunk' })
map('n', '<leader>hS', gitsigns.stage_buffer, { desc = 'git [S]tage buffer' })
map('n', '<leader>hu', gitsigns.stage_hunk, { desc = 'git [u]ndo stage hunk' })
map('n', '<leader>hu', gitsigns.undo_stage_hunk, { desc = 'git [u]ndo stage hunk' })
map('n', '<leader>hR', gitsigns.reset_buffer, { desc = 'git [R]eset buffer' })
map('n', '<leader>hp', gitsigns.preview_hunk, { desc = 'git [p]review hunk' })
map('n', '<leader>hP', gitsigns.preview_hunk_inline, { desc = 'git [P]review hunk inline' })
map('n', '<leader>hb', gitsigns.blame_line, { desc = 'git [b]lame line' })
map('n', '<leader>hd', gitsigns.diffthis, { desc = 'git [d]iff against index' })
map('n', '<leader>hD', function()
@ -54,7 +55,8 @@ return {
end, { desc = 'git [D]iff against last commit' })
-- Toggles
map('n', '<leader>tb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' })
map('n', '<leader>tD', gitsigns.preview_hunk_inline, { desc = '[T]oggle git show [D]eleted' })
map('n', '<leader>tD', gitsigns.toggle_deleted, { desc = '[T]oggle git show [D]eleted' })
map('n', '<leader>tw', gitsigns.toggle_word_diff, { desc = '[T]oggle git [W]ord diff' })
end,
},
},

View File

@ -7,6 +7,7 @@ return {
local lint = require 'lint'
lint.linters_by_ft = {
markdown = { 'markdownlint' },
python = { 'ruff' },
}
-- To allow other plugins to add linters to require('lint').linters_by_ft,

View File

@ -11,6 +11,8 @@ return {
capabilities = require('blink.cmp').get_lsp_capabilities(),
})
local detach_augroup = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true })
-- LspAttach: keymaps only. Server setup is handled by vim.lsp.enable in setup/lsp.lua
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }),
@ -22,13 +24,16 @@ return {
map('grn', vim.lsp.buf.rename, '[R]e[n]ame')
map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' })
map('grr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences')
map('gri', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation')
map('grd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition')
map('grr', function() require('telescope.builtin').lsp_references() end, '[G]oto [R]eferences')
map('gri', function() require('telescope.builtin').lsp_implementations() end, '[G]oto [I]mplementation')
map('grd', function() require('telescope.builtin').lsp_definitions() end, '[G]oto [D]efinition')
map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
map('gO', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols')
map('gW', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Open Workspace Symbols')
map('grt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition')
map('gO', function() require('telescope.builtin').lsp_document_symbols() end, 'Open Document Symbols')
map('gW', function() require('telescope.builtin').lsp_dynamic_workspace_symbols() end, 'Open Workspace Symbols')
map('grt', function() require('telescope.builtin').lsp_type_definitions() end, '[G]oto [T]ype Definition')
map('gd', vim.lsp.buf.definition, '[G]oto [D]efinition')
map('K', vim.lsp.buf.hover, 'Hover Documentation')
map('<leader>n', vim.lsp.buf.rename, '[R]e[n]ame')
local function client_supports_method(client, method, bufnr)
if vim.fn.has 'nvim-0.11' == 1 then
@ -47,13 +52,14 @@ return {
group = hl_group,
callback = vim.lsp.buf.document_highlight,
})
-- vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
-- buffer = event.buf,
-- group = hl_group,
-- callback = vim.lsp.buf.clear_references,
-- })
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
buffer = event.buf,
group = hl_group,
callback = vim.lsp.buf.clear_references,
})
vim.api.nvim_create_autocmd('LspDetach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }),
group = detach_augroup,
buffer = event.buf,
callback = function(event2)
vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf }
@ -62,9 +68,9 @@ return {
end
if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then
map('<leader>th', function()
map('<leader>lh', function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf })
end, '[T]oggle Inlay [H]ints')
end, '[L]SP Toggle Inlay [H]ints')
end
end,
})

View File

@ -4,7 +4,7 @@ return {
-- See `:help lualine.txt`
opts = {
options = {
icons_enabled = false,
icons_enabled = true,
theme = 'gruvbox',
component_separators = '|',
section_separators = '',

View File

@ -28,8 +28,9 @@ return {
-- Formatters / linters
'stylua',
'prettier',
'black',
'isort',
'ruff',
'clang-format',
'markdownlint',
},
}
end,

View File

@ -17,8 +17,8 @@ return {
picker = { enabled = true },
quickfile = { enabled = true },
scope = { enabled = true },
-- scroll = { enabled = true },
words = { enabled = false },
scroll = { enabled = false },
words = { enabled = true },
-- image = {
-- enabled = true,
-- resolve = function(path, src)

View File

@ -1,6 +1,6 @@
return {
'nvim-telescope/telescope.nvim',
-- event = 'VimEnter',
cmd = { 'Telescope' },
dependencies = {
'nvim-lua/plenary.nvim',
{
@ -13,6 +13,45 @@ return {
{ 'nvim-telescope/telescope-ui-select.nvim' },
{ 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font },
},
keys = {
{ '<leader>sh', function() require('telescope.builtin').help_tags() end, desc = '[S]earch [H]elp' },
{ '<leader>sk', function() require('telescope.builtin').keymaps() end, desc = '[S]earch [K]eymaps' },
{ '<leader>sf', function() require('telescope.builtin').find_files() end, desc = '[S]earch [F]iles' },
{ '<leader>ss', function() require('telescope.builtin').builtin() end, desc = '[S]earch [S]elect Telescope' },
{ '<leader>sw', function() require('telescope.builtin').grep_string() end, desc = '[S]earch current [W]ord' },
{ '<leader>sg', function() require('telescope.builtin').live_grep() end, desc = '[S]earch by [G]rep' },
{ '<leader>sd', function() require('telescope.builtin').diagnostics() end, desc = '[S]earch [D]iagnostics' },
{ '<leader>sr', function() require('telescope.builtin').resume() end, desc = '[S]earch [R]esume' },
{ '<leader>s.', function() require('telescope.builtin').oldfiles() end, desc = '[S]earch Recent Files' },
{ '<leader><leader>', function() require('telescope.builtin').buffers() end, desc = '[ ] Find buffers' },
{
'<leader>/',
function()
require('telescope.builtin').current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
winblend = 10,
previewer = false,
})
end,
desc = '[/] Search in current buffer',
},
{
'<leader>s/',
function()
require('telescope.builtin').live_grep {
grep_open_files = true,
prompt_title = 'Live Grep in Open Files',
}
end,
desc = '[S]earch [/] in Open Files',
},
{
'<leader>sn',
function()
require('telescope.builtin').find_files { cwd = vim.fn.stdpath 'config' }
end,
desc = '[S]earch [N]eovim files',
},
},
config = function()
require('telescope').setup {
extensions = {
@ -24,35 +63,5 @@ return {
pcall(require('telescope').load_extension, 'fzf')
pcall(require('telescope').load_extension, 'ui-select')
local builtin = require 'telescope.builtin'
vim.keymap.set('n', '<leader>sh', builtin.help_tags, { desc = '[S]earch [H]elp' })
vim.keymap.set('n', '<leader>sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' })
vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = '[S]earch [F]iles' })
vim.keymap.set('n', '<leader>ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' })
vim.keymap.set('n', '<leader>sw', builtin.grep_string, { desc = '[S]earch current [W]ord' })
vim.keymap.set('n', '<leader>sg', builtin.live_grep, { desc = '[S]earch by [G]rep' })
vim.keymap.set('n', '<leader>sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' })
vim.keymap.set('n', '<leader>sr', builtin.resume, { desc = '[S]earch [R]esume' })
vim.keymap.set('n', '<leader>s.', builtin.oldfiles, { desc = '[S]earch Recent Files' })
vim.keymap.set('n', '<leader><leader>', builtin.buffers, { desc = '[ ] Find buffers' })
vim.keymap.set('n', '<leader>/', function()
builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
winblend = 10,
previewer = false,
})
end, { desc = '[/] Search in current buffer' })
vim.keymap.set('n', '<leader>s/', function()
builtin.live_grep {
grep_open_files = true,
prompt_title = 'Live Grep in Open Files',
}
end, { desc = '[S]earch [/] in Open Files' })
vim.keymap.set('n', '<leader>sn', function()
builtin.find_files { cwd = vim.fn.stdpath 'config' }
end, { desc = '[S]earch [N]eovim files' })
end,
}

View File

@ -25,6 +25,10 @@ return {
'tsx',
'json',
'css',
'glsl',
'cmake',
'hlsl',
'ini',
},
auto_install = true,
highlight = {

View File

@ -1,15 +1,42 @@
-- Unreal
return {
'PlayKigai/Unreal-Nvim',
-- ft = { 'cpp', 'c', 'h', 'hpp', 'cs', 'ini', 'uproject', 'uplugin' },
cmd = { 'Unreal' },
init = function()
local group = vim.api.nvim_create_augroup('UnrealAutoInit', { clear = true })
local initialized = false
local function try_init()
if initialized then return end
initialized = true
vim.api.nvim_del_augroup_by_id(group)
require('lazy').load { plugins = { 'Unreal-Nvim' } }
require('unreal-nvim').setup({})
end
-- Auto-init on explicit UE project/plugin/build files
vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, {
group = group,
pattern = { '*.uproject', '*.uplugin', '*.Build.cs', '*.Target.cs' },
callback = try_init,
})
-- Auto-init on C++ files when a .uproject exists in cwd (UE source code)
vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, {
group = group,
pattern = { '*.cpp', '*.h', '*.hpp', '*.c' },
callback = function()
if vim.fn.glob(vim.fn.getcwd() .. '/*.uproject') ~= '' then
try_init()
end
end,
})
end,
config = function()
-- Plugin is set up by try_init() above; this is only reached when
-- loaded manually via :Unreal or by the auto-init path.
vim.api.nvim_create_user_command('Unreal', function()
require('unreal-nvim').setup()
end, {})
-- require('unreal-nvim').setup {
-- engine_path = "C:\\Program Files\\Epic Games\\UE_5.6.1", -- optional
-- auto_register_clangd = true -- if true, tries to auto-configure clangd for Unreal (needs nvim-lspconfig)
-- }
require('unreal-nvim').setup({})
end, { desc = 'Manually initialize Unreal-Nvim' })
end,
}

View File

@ -1,6 +1,6 @@
return {
'folke/which-key.nvim',
event = 'VimEnter',
event = 'VeryLazy',
opts = {
delay = 0,
icons = {
@ -40,7 +40,14 @@ return {
{ '<leader>s', group = '[S]earch' },
{ '<leader>t', group = '[T]oggle' },
{ '<leader>h', group = 'Git [H]unk', mode = { 'n', 'v' } },
{ '<leader>b', group = '[B]uild ' },
{ '<leader>b', group = '[B]reakpoint' },
{ '<leader>l', group = '[L]SP' },
{ '<leader>g', group = '[G]it' },
{ '<leader>c', group = '[C]ode / C++' },
{ '<leader>d', group = '[D]ebug' },
{ '<leader>r', group = '[R]un' },
{ '<leader>u', group = '[U]nreal' },
{ '<leader>a', group = '[A]I' },
},
},
}

View File

@ -1,106 +1,14 @@
-- Attach LSP
local lsp_attach_group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true })
vim.api.nvim_create_autocmd('LspAttach', {
group = lsp_attach_group,
callback = function(event)
local function map(keys, func, desc, mode)
mode = mode or 'n'
vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
end
-- Key mappings table: {keys, function, description, [mode]}
local mappings = {
{ 'grn', vim.lsp.buf.rename, '[R]e[n]ame' },
{ 'gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' } },
{
'grr',
function()
require('telescope.builtin').lsp_references()
end,
'[G]oto [R]eferences',
},
{
'gri',
function()
require('telescope.builtin').lsp_implementations()
end,
'[G]oto [I]mplementation',
},
{
'grd',
function()
require('telescope.builtin').lsp_definitions()
end,
'[G]oto [D]efinition',
},
{ 'grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration' },
{
'gO',
function()
require('telescope.builtin').lsp_document_symbols()
end,
'Open Document Symbols',
},
{
'gW',
function()
require('telescope.builtin').lsp_dynamic_workspace_symbols()
end,
'Open Workspace Symbols',
},
{
'grt',
function()
require('telescope.builtin').lsp_type_definitions()
end,
'[G]oto [T]ype Definition',
},
{ 'gd', vim.lsp.buf.definition, '[G]oto [D]efinition' },
{ 'K', vim.lsp.buf.hover, 'Hover Documentation' },
{ '<leader>ca', vim.lsp.buf.code_action, 'Code [A]ction' },
{ '<leader>n', vim.lsp.buf.rename, '[R]e[n]ame' },
}
for _, m in ipairs(mappings) do
map(m[1], m[2], m[3], m[4])
end
local function client_supports_method(client, method, bufnr)
if vim.fn.has 'nvim-0.11' == 1 then
return client:supports_method(method, bufnr)
else
return client.supports_method(method, { bufnr = bufnr })
end
end
local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then
local highlight_augroup = vim.api.nvim_create_augroup('lsp-highlight', { clear = false })
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
buffer = event.buf,
group = highlight_augroup,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
buffer = event.buf,
group = highlight_augroup,
callback = vim.lsp.buf.clear_references,
})
vim.api.nvim_create_autocmd('LspDetach', {
group = vim.api.nvim_create_augroup('lsp-detach', { clear = true }),
callback = function(event2)
vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds { group = 'lsp-highlight', buffer = event2.buf }
end,
})
end
if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then
map('<leader>th', function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf })
end, '[T]oggle Inlay [H]ints')
end
end,
})
-- Shader file associations
vim.filetype.add {
extension = {
vert = 'glsl',
frag = 'glsl',
geom = 'glsl',
comp = 'glsl',
tesc = 'glsl',
tese = 'glsl',
},
}
-- Highlight on yank
vim.api.nvim_create_autocmd('TextYankPost', {
@ -112,15 +20,29 @@ vim.api.nvim_create_autocmd('TextYankPost', {
})
-- Load project-local config
local uv = vim.uv or vim.loop
local function load_project_config()
local config_file = vim.fn.getcwd() .. '/.nvim.lua'
if vim.fn.filereadable(config_file) ~= 1 then
return
end
local stat = uv.fs_lstat(config_file)
if not (stat and stat.type == 'file') then
return
end
local ok, err = pcall(dofile, config_file)
if not ok then
vim.notify('Error loading project config: ' .. err, vim.log.levels.WARN)
end
end
vim.api.nvim_create_autocmd('VimEnter', {
desc = 'Load project-local .nvim.lua',
group = vim.api.nvim_create_augroup('project-local-config', { clear = true }),
callback = function()
local config_file = vim.fn.getcwd() .. '/.nvim.lua'
if vim.fn.filereadable(config_file) == 1 then
dofile(config_file)
end
end,
callback = load_project_config,
})
-- Restore cursor to file position in previous editing session

View File

@ -3,7 +3,7 @@ vim.g.maplocalleader = ' '
vim.g.have_nerd_font = true
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
vim.keymap.set('n', '<leader>q', vim.diagnostic.setqflist, { desc = 'Open diagnostic [Q]uickfix list' })
vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
-- Disables <Space> as a normal/visual key, so it only works as leader
@ -47,12 +47,14 @@ vim.keymap.set({ 'n', 'v' }, '<leader>d', [["_d]])
-- In insert mode, Ctrl+c acts as <Esc>.
vim.keymap.set('i', '<C-c>', '<Esc>')
-- Format file or selection using LSP with <leader>f.
vim.keymap.set('n', '<leader>f', vim.lsp.buf.format)
vim.keymap.set('v', '<leader>f', vim.lsp.buf.format)
-- Diagnostic navigation
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Next [D]iagnostic' })
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Previous [D]iagnostic' })
-- Replace word under cursor throughout file.
vim.keymap.set('n', '<leader>s', [[:%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]])
-- Buffer navigation
vim.keymap.set('n', ']b', '<cmd>bnext<CR>', { desc = 'Next [B]uffer' })
vim.keymap.set('n', '[b', '<cmd>bprev<CR>', { desc = 'Previous [B]uffer' })
-- Open terminal in vertical split.
vim.keymap.set('n', '<leader>tn', ':vs term://bash<CR>')
-- Quickfix navigation
vim.keymap.set('n', ']q', '<cmd>cnext<CR>', { desc = 'Next [Q]uickfix' })
vim.keymap.set('n', '[q', '<cmd>cprev<CR>', { desc = 'Previous [Q]uickfix' })

View File

@ -11,7 +11,14 @@ vim.opt.rtp:prepend(lazypath)
require('lazy').setup({
-- Git related plugins
'sindrets/diffview.nvim',
{
'sindrets/diffview.nvim',
cmd = { 'DiffviewOpen', 'DiffviewFileHistory', 'DiffviewClose' },
keys = {
{ '<leader>gv', '<cmd>DiffviewOpen<CR>', desc = '[G]it Diff[V]iew' },
{ '<leader>gh', '<cmd>DiffviewFileHistory %<CR>', desc = '[G]it File [H]istory' },
},
},
-- Detect tabstop and shiftwidth automatically
'tpope/vim-sleuth',

View File

@ -3,7 +3,7 @@ vim.lsp.enable {
'basedpyright',
'clangd',
-- 'typos_lsp',
'ty',
-- 'ty', -- removed: redundant with basedpyright, adds diagnostic noise
'ts_ls',
'cssls',
'html',
@ -12,17 +12,18 @@ vim.lsp.enable {
vim.lsp.inlay_hint.enable(true)
local virtual_text_mode = nil
local base_virtual_text = {
source = 'if_many',
spacing = 2,
format = function(diagnostic)
return diagnostic.message
end,
}
local diagnostic_underline = { severity = vim.diagnostic.severity.ERROR }
vim.diagnostic.config {
virtual_text = {
source = 'if_many',
spacing = 2,
format = function(diagnostic)
return diagnostic.message
end,
current_line = virtual_text_mode,
},
underline = { severity = vim.diagnostic.severity.ERROR },
virtual_text = base_virtual_text,
underline = diagnostic_underline,
update_in_insert = false,
severity_sort = true,
float = {
@ -55,10 +56,8 @@ vim.api.nvim_create_user_command('LspToggleDiagnostic', function()
else
virtual_text_mode = nil
vim.diagnostic.config {
virtual_text = {
current_line = virtual_text_mode,
},
underline = true,
virtual_text = base_virtual_text,
underline = diagnostic_underline,
}
end
end, {})
@ -79,14 +78,14 @@ local function restart_lsp(client_name)
-- 1) Collect buffers that had this client and the client configs to reuse
local target = {} -- [bufnr] = client.config
local to_stop = {} -- [client_id] = true
local to_stop = {} -- [client_id] = client
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(bufnr) then
for _, c in ipairs(vim.lsp.get_clients { bufnr = bufnr }) do
if c.name == client_name then
target[bufnr] = c.config
to_stop[c.id] = true
to_stop[c.id] = c
end
end
end
@ -97,9 +96,9 @@ local function restart_lsp(client_name)
return
end
-- 2) Stop all those clients (force=true to avoid waiting handshake)
for id in pairs(to_stop) do
vim.lsp.stop_client(id)
-- 2) Stop all those clients (force=true)
for _, client in pairs(to_stop) do
client:stop(true)
end
-- 3) For each buffer, (re)start using the original config.

View File

@ -1,4 +1,4 @@
vim.g.nofsync = true
vim.opt.fsync = false
-- System Clipboard Integration
vim.schedule(function()
@ -10,7 +10,7 @@ vim.opt.nu = true
vim.opt.relativenumber = true
-- Default terminal to pwsh
vim.opt.shell = vim.fn.executable 'pwsh' and 'pwsh' or 'powershell'
vim.opt.shell = vim.fn.executable('pwsh') == 1 and 'pwsh' or 'powershell'
vim.opt.shellcmdflag =
'-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;'
vim.opt.shellredir = '-RedirectStandardOutput %s -NoNewWindow -Wait'
@ -27,6 +27,7 @@ vim.cmd 'command! Qw wq'
vim.cmd 'command! Q q'
-- Save undo history
vim.fn.mkdir(vim.fn.stdpath('data') .. '/undodir', 'p')
vim.opt.undodir = vim.fn.stdpath 'data' .. '/undodir'
vim.opt.undofile = true
@ -59,7 +60,7 @@ vim.opt.expandtab = true
vim.opt.smartindent = true
vim.o.autoindent = true
vim.opt.wrap = true
vim.opt.wrap = false
-- Disable swap and backup files
vim.opt.swapfile = false

6
machine.json Normal file
View File

@ -0,0 +1,6 @@
{
"_comment": "Machine-specific paths — DO NOT COMMIT. See machine.json.template for the template.",
"basedpyright": "D:\\language-servers\\basedpyright\\Scripts\\basedpyright-langserver.exe",
"clangd": "D:\\language-servers\\clangd\\bin\\clangd.exe",
"ue_python": "C:\\Program Files\\Epic Games\\UE_5.7\\Engine\\Binaries\\ThirdParty\\Python3\\Win64\\python.exe"
}

6
machine.json.template Normal file
View File

@ -0,0 +1,6 @@
{
"_comment": "Copy this file to machine.json and fill in the paths for this machine. machine.json is gitignored.",
"basedpyright": "D:\\language-servers\\basedpyright\\Scripts\\basedpyright-langserver.exe",
"clangd": "D:\\language-servers\\clangd\\bin\\clangd.exe",
"ue_python": "C:\\Program Files\\Epic Games\\UE_5.7\\Engine\\Binaries\\ThirdParty\\Python3\\Win64\\python.exe"
}

387
requirements.md Normal file
View File

@ -0,0 +1,387 @@
# Neovim Configuration Requirements
## Plugin Manager
| Plugin | GitHub |
|--------|--------|
| lazy.nvim | https://github.com/folke/lazy.nvim |
---
## Completion
| Plugin | GitHub |
|--------|--------|
| blink.cmp | https://github.com/saghen/blink.cmp |
| LuaSnip | https://github.com/L3MON4D3/LuaSnip |
| friendly-snippets | https://github.com/rafamadriz/friendly-snippets |
| nvim-autopairs | https://github.com/windwp/nvim-autopairs |
---
## LSP
| Plugin | GitHub |
|--------|--------|
| nvim-lspconfig | https://github.com/neovim/nvim-lspconfig |
| mason.nvim | https://github.com/mason-org/mason.nvim |
| mason-lspconfig.nvim | https://github.com/mason-org/mason-lspconfig.nvim |
| mason-tool-installer.nvim | https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim |
| lazydev.nvim | https://github.com/folke/lazydev.nvim |
| fidget.nvim | https://github.com/j-hui/fidget.nvim |
| lua-language-server | https://github.com/LuaLS/lua-language-server |
| basedpyright | https://github.com/DetachHead/basedpyright |
| clangd | https://github.com/clangd/clangd |
| typescript-language-server | https://github.com/typescript-language-server/typescript-language-server |
| vscode-langservers-extracted (css-lsp + html-lsp) | https://github.com/hrsh7th/vscode-langservers-extracted |
---
## Formatting & Linting
| Plugin | GitHub |
|--------|--------|
| conform.nvim | https://github.com/stevearc/conform.nvim |
| nvim-lint | https://github.com/mfussenegger/nvim-lint |
| stylua | https://github.com/JohnnyMorganz/StyLua |
| prettier | https://github.com/prettier/prettier |
| ruff | https://github.com/astral-sh/ruff |
| clang-format | https://github.com/llvm/llvm-project |
| markdownlint | https://github.com/DavidAnson/markdownlint-cli |
---
## Treesitter
| Plugin | GitHub |
|--------|--------|
| nvim-treesitter | https://github.com/nvim-treesitter/nvim-treesitter |
| nvim-treesitter-context | https://github.com/nvim-treesitter/nvim-treesitter-context |
| nvim-treesitter-textobjects | https://github.com/nvim-treesitter/nvim-treesitter-textobjects |
---
## UI
| Plugin | GitHub |
|--------|--------|
| gruvbox.nvim | https://github.com/ellisonleao/gruvbox.nvim |
| lualine.nvim | https://github.com/nvim-lualine/lualine.nvim |
| snacks.nvim | https://github.com/folke/snacks.nvim |
| noice.nvim | https://github.com/folke/noice.nvim |
| nvim-notify | https://github.com/rcarriga/nvim-notify |
| nui.nvim | https://github.com/MunifTanjim/nui.nvim |
| neo-tree.nvim | https://github.com/nvim-neo-tree/neo-tree.nvim |
| which-key.nvim | https://github.com/folke/which-key.nvim |
| indent-blankline.nvim | https://github.com/lukas-reineke/indent-blankline.nvim |
| render-markdown.nvim | https://github.com/MeanderingProgrammer/render-markdown.nvim |
| nvim-highlight-colors | https://github.com/brenoprata10/nvim-highlight-colors |
| todo-comments.nvim | https://github.com/folke/todo-comments.nvim |
| log-highlight.nvim | https://github.com/fei6409/log-highlight.nvim |
| nvim-web-devicons | https://github.com/nvim-tree/nvim-web-devicons |
---
## Navigation
| Plugin | GitHub |
|--------|--------|
| telescope.nvim | https://github.com/nvim-telescope/telescope.nvim |
| telescope-fzf-native.nvim | https://github.com/nvim-telescope/telescope-fzf-native.nvim |
| telescope-ui-select.nvim | https://github.com/nvim-telescope/telescope-ui-select.nvim |
| smart-splits.nvim | https://github.com/mrjones2014/smart-splits.nvim |
| treesj | https://github.com/Wansmer/treesj |
---
## Git
| Plugin | GitHub |
|--------|--------|
| vim-fugitive | https://github.com/tpope/vim-fugitive |
| gitsigns.nvim | https://github.com/lewis6991/gitsigns.nvim |
| diffview.nvim | https://github.com/sindrets/diffview.nvim |
---
## Editing
| Plugin | GitHub |
|--------|--------|
| nvim-surround | https://github.com/kylechui/nvim-surround |
| mini.ai | https://github.com/echasnovski/mini.ai |
| vim-sleuth | https://github.com/tpope/vim-sleuth |
---
## Terminal
| Plugin | GitHub |
|--------|--------|
| toggleterm.nvim | https://github.com/akinsho/toggleterm.nvim |
---
## AI
| Plugin | GitHub |
|--------|--------|
| copilot.lua | https://github.com/zbirenbaum/copilot.lua |
| blink-cmp-copilot | https://github.com/giuxtaposition/blink-cmp-copilot |
| CopilotChat.nvim | https://github.com/CopilotC-Nvim/CopilotChat.nvim |
| codecompanion.nvim | https://github.com/olimorris/codecompanion.nvim |
---
## Debugging (DAP)
| Plugin | GitHub |
|--------|--------|
| nvim-dap | https://github.com/mfussenegger/nvim-dap |
| nvim-dap-ui | https://github.com/rcarriga/nvim-dap-ui |
| nvim-nio | https://github.com/nvim-neotest/nvim-nio |
| mason-nvim-dap.nvim | https://github.com/jay-babu/mason-nvim-dap.nvim |
| nvim-dap-python | https://github.com/mfussenegger/nvim-dap-python |
| nvim-dap-virtual-text | https://github.com/theHamsta/nvim-dap-virtual-text |
| codelldb | https://github.com/vadimcn/codelldb |
| debugpy | https://github.com/microsoft/debugpy |
---
## Language Specific
| Plugin | GitHub |
|--------|--------|
| cmake-tools.nvim | https://github.com/Civitasv/cmake-tools.nvim |
| Unreal-Nvim | https://github.com/PlayKigai/Unreal-Nvim |
---
## Shared Dependencies
| Plugin | GitHub |
|--------|--------|
| plenary.nvim | https://github.com/nvim-lua/plenary.nvim |
## Completion
| Plugin | GitHub |
|--------|--------|
| blink.cmp | https://github.com/saghen/blink.cmp |
| LuaSnip | https://github.com/L3MON4D3/LuaSnip |
| friendly-snippets | https://github.com/rafamadriz/friendly-snippets |
| nvim-autopairs | https://github.com/windwp/nvim-autopairs |
---
## LSP
| Plugin | GitHub |
|--------|--------|
| nvim-lspconfig | https://github.com/neovim/nvim-lspconfig |
| mason.nvim | https://github.com/mason-org/mason.nvim |
| mason-lspconfig.nvim | https://github.com/mason-org/mason-lspconfig.nvim |
| mason-tool-installer.nvim | https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim |
| lazydev.nvim | https://github.com/folke/lazydev.nvim |
| fidget.nvim | https://github.com/j-hui/fidget.nvim |
### LSP Servers (installed via Mason)
| Server | Language |
|--------|----------|
| lua-language-server | Lua |
| basedpyright | Python |
| clangd | C / C++ |
| typescript-language-server (ts_ls) | TypeScript / JavaScript |
| css-lsp | CSS |
| html-lsp | HTML |
### LSP Servers — Manual Install (No Mason)
> Clone or download releases directly from GitHub, build/install per each repo's README, then either put the binary on your `PATH` or set the machine-specific path in `machine.json` for servers that use `lua/machine.lua` (`basedpyright` and `clangd` in the current config).
| Server | GitHub | Notes |
|--------|--------|-------|
| lua-language-server | https://github.com/LuaLS/lua-language-server | Pre-built releases available; add `bin/` to PATH |
| basedpyright | https://github.com/DetachHead/basedpyright | Install via `pip install basedpyright`; `lsp/basedpyright.lua` can also read the binary path from `machine.json` key `basedpyright` |
| clangd | https://github.com/clangd/clangd | Pre-built releases available; part of LLVM toolchain; `lsp/clangd.lua` can also read the binary path from `machine.json` key `clangd` |
| typescript-language-server | https://github.com/typescript-language-server/typescript-language-server | Requires Node.js; build from source with `npm install` |
| css-lsp + html-lsp | https://github.com/hrsh7th/vscode-langservers-extracted | Both servers come from this single repo; requires Node.js |
> `:LspRestart` currently does a stop-then-deferred-start cycle and may hit timing issues on some buffers or roots. If a restart looks incomplete, use `:LspStop` and then `:LspStart` separately.
> `:LspToggleDiagnostic` switches `virtual_text.current_line` and underline state, but custom `virtual_text` settings may need to be re-applied manually after toggling.
### Formatters & Linters (installed via Mason)
| Tool | Purpose |
|------|---------|
| stylua | Lua formatter |
| prettier | JS / TS / CSS / HTML formatter |
| ruff | Python formatter / import sorter |
| clang-format | C / C++ formatter |
### Formatters & Linters — Manual Install (No Mason)
> Same rule: build from source or grab a release binary, put it on `PATH`. `conform.nvim` and `nvim-lint` will pick it up automatically.
| Tool | GitHub | Notes |
|------|--------|-------|
| stylua | https://github.com/JohnnyMorganz/StyLua | Pre-built releases available for all platforms |
| prettier | https://github.com/prettier/prettier | Requires Node.js; build from source with `npm install` |
| ruff | https://github.com/astral-sh/ruff | Requires Python; install with `pip install ruff` from source or release |
| clang-format | https://github.com/llvm/llvm-project | Pre-built releases available; part of LLVM toolchain |
| markdownlint | https://github.com/DavidAnson/markdownlint-cli | Requires Node.js; install with `npm install` so `nvim-lint` can lint Markdown |
### DAP Adapters (installed via Mason)
| Adapter | GitHub |
|---------|--------|
| codelldb | https://github.com/vadimcn/codelldb |
| debugpy | https://github.com/microsoft/debugpy |
### DAP Adapters — Manual Install (No Mason)
> `lua/plugins/debug.lua` configures `mason-nvim-dap.nvim` to install both `codelldb` and `debugpy`. Without Mason, install from GitHub and point `nvim-dap`'s adapter config at the binary.
| Adapter | GitHub | Notes |
|---------|--------|-------|
| codelldb | https://github.com/vadimcn/codelldb | Pre-built releases available; point `nvim-dap` at the adapter executable if needed |
| debugpy (Python) | https://github.com/microsoft/debugpy | Install with `pip install debugpy`; with Mason, `nvim-dap-python` uses the Mason `debugpy` virtualenv first and falls back to the system Python if the Mason package is missing |
> Verify that the Python interpreter selected for debugging matches the current workspace, especially when Mason is installed but the project expects a different virtualenv.
---
## Treesitter
| Plugin | GitHub |
|--------|--------|
| nvim-treesitter | https://github.com/nvim-treesitter/nvim-treesitter |
| nvim-treesitter-context | https://github.com/nvim-treesitter/nvim-treesitter-context |
| nvim-treesitter-textobjects | https://github.com/nvim-treesitter/nvim-treesitter-textobjects |
---
## Formatting & Linting
| Plugin | GitHub |
|--------|--------|
| conform.nvim | https://github.com/stevearc/conform.nvim |
| nvim-lint | https://github.com/mfussenegger/nvim-lint |
### Formatters / Linters (installed via Mason)
| Tool | Purpose |
|------|---------|
| stylua | Lua formatter |
| prettier | JS / TS / CSS / HTML formatter |
| ruff | Python formatter / import sorter |
| clang-format | C / C++ formatter |
---
## UI
| Plugin | GitHub |
|--------|--------|
| gruvbox.nvim | https://github.com/ellisonleao/gruvbox.nvim |
| lualine.nvim | https://github.com/nvim-lualine/lualine.nvim |
| snacks.nvim | https://github.com/folke/snacks.nvim |
| noice.nvim | https://github.com/folke/noice.nvim |
| nvim-notify | https://github.com/rcarriga/nvim-notify |
| nui.nvim | https://github.com/MunifTanjim/nui.nvim |
| neo-tree.nvim | https://github.com/nvim-neo-tree/neo-tree.nvim |
| which-key.nvim | https://github.com/folke/which-key.nvim |
| indent-blankline.nvim | https://github.com/lukas-reineke/indent-blankline.nvim |
| render-markdown.nvim | https://github.com/MeanderingProgrammer/render-markdown.nvim |
| nvim-highlight-colors | https://github.com/brenoprata10/nvim-highlight-colors |
| todo-comments.nvim | https://github.com/folke/todo-comments.nvim |
| log-highlight.nvim | https://github.com/fei6409/log-highlight.nvim |
| nvim-web-devicons | https://github.com/nvim-tree/nvim-web-devicons |
---
## Navigation
| Plugin | GitHub |
|--------|--------|
| telescope.nvim | https://github.com/nvim-telescope/telescope.nvim |
| telescope-fzf-native.nvim | https://github.com/nvim-telescope/telescope-fzf-native.nvim |
| telescope-ui-select.nvim | https://github.com/nvim-telescope/telescope-ui-select.nvim |
| smart-splits.nvim | https://github.com/mrjones2014/smart-splits.nvim |
| treesj | https://github.com/Wansmer/treesj |
---
## Git
| Plugin | GitHub |
|--------|--------|
| vim-fugitive | https://github.com/tpope/vim-fugitive |
| gitsigns.nvim | https://github.com/lewis6991/gitsigns.nvim |
| diffview.nvim | https://github.com/sindrets/diffview.nvim |
---
## Editing
| Plugin | GitHub |
|--------|--------|
| nvim-surround | https://github.com/kylechui/nvim-surround |
| mini.ai | https://github.com/echasnovski/mini.ai |
| vim-sleuth | https://github.com/tpope/vim-sleuth |
---
## Terminal
| Plugin | GitHub |
|--------|--------|
| toggleterm.nvim | https://github.com/akinsho/toggleterm.nvim |
---
## AI
| Plugin | GitHub |
|--------|--------|
| copilot.lua | https://github.com/zbirenbaum/copilot.lua |
| blink-cmp-copilot | https://github.com/giuxtaposition/blink-cmp-copilot |
| CopilotChat.nvim | https://github.com/CopilotC-Nvim/CopilotChat.nvim |
| codecompanion.nvim | https://github.com/olimorris/codecompanion.nvim |
---
## Debugging (DAP)
| Plugin | GitHub |
|--------|--------|
| nvim-dap | https://github.com/mfussenegger/nvim-dap |
| nvim-dap-ui | https://github.com/rcarriga/nvim-dap-ui |
| nvim-nio | https://github.com/nvim-neotest/nvim-nio |
| mason-nvim-dap.nvim | https://github.com/jay-babu/mason-nvim-dap.nvim |
| nvim-dap-python | https://github.com/mfussenegger/nvim-dap-python |
| nvim-dap-virtual-text | https://github.com/theHamsta/nvim-dap-virtual-text |
> Current DAP setup auto-installs `codelldb` and `debugpy` through Mason; Python debugging is wired through `nvim-dap-python`, which prefers Mason's `debugpy` environment and falls back to the system Python when the Mason package is unavailable.
---
## Language Specific
| Plugin | GitHub |
|--------|--------|
| cmake-tools.nvim | https://github.com/Civitasv/cmake-tools.nvim |
| Unreal-Nvim | https://github.com/PlayKigai/Unreal-Nvim |
> `lua/plugins/unreal.lua` now auto-initializes `Unreal-Nvim` when opening `*.uproject`, `*.uplugin`, `*.Build.cs`, or `*.Target.cs` files, and also when opening C/C++ files inside a working directory that contains a `.uproject`. This covers the common Unreal entry points, but edge cases may still need a manual `:Unreal` command.
---
## Shared Dependencies
| Plugin | GitHub |
|--------|--------|
| plenary.nvim | https://github.com/nvim-lua/plenary.nvim |

9
tmp/diag_test.lua Normal file
View File

@ -0,0 +1,9 @@
vim.diagnostic.config({
virtual_text = { source = 'if_many', spacing = 2, format = function(d) return d.message end, current_line = nil },
underline = { severity = vim.diagnostic.severity.ERROR },
})
vim.diagnostic.config({ virtual_text = { current_line = true }, underline = false })
local cfg = vim.diagnostic.config()
print(vim.inspect(cfg.virtual_text))
print(vim.inspect(cfg.underline))
vim.cmd('qa!')