Refactoring my nvim setup

This commit is contained in:
Arthur Gonze Machado 2026-03-31 18:30:44 -04:00
parent 9114daae4a
commit 7477a55439
48 changed files with 5238 additions and 1075 deletions

1021
init.lua

File diff suppressed because it is too large Load Diff

57
lazy-lock.json Normal file
View File

@ -0,0 +1,57 @@
{
"CopilotChat.nvim": { "branch": "main", "commit": "9fec6c3c2a4069b1f649e116c10e6fbcf1463764" },
"LuaSnip": { "branch": "master", "commit": "5a1e39223db9a0498024a77b8441169d260c8c25" },
"Unreal-Nvim": { "branch": "main", "commit": "b0991bbd83645717cc0b3c98dd1fbf6ee7684c25" },
"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" },
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
"fidget.nvim": { "branch": "main", "commit": "7fa433a83118a70fe24c1ce88d5f0bd3453c0970" },
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
"gitsigns.nvim": { "branch": "main", "commit": "50c205548d8b037b7ff6378fca6d21146f0b6161" },
"gruvbox.nvim": { "branch": "main", "commit": "334d5fd49fc8033f26408425366c66c6390c57bb" },
"indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
"lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" },
"log-highlight.nvim": { "branch": "main", "commit": "ca88628f6dd3b9bb46f9a7401669e24cf7de47a4" },
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "38499e0bda64bc0f3ec6e7f03f8e13dd11c0fa00" },
"mason-nvim-dap.nvim": { "branch": "main", "commit": "9a10e096703966335bd5c46c8c875d5b0690dade" },
"mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" },
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
"mini.ai": { "branch": "main", "commit": "4b0a6207341d895b6cfe9bcb1e4d3e8607bfe4f4" },
"neo-tree.nvim": { "branch": "main", "commit": "84c75e7a7e443586f60508d12fc50f90d9aee14e" },
"noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" },
"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" },
"nvim-highlight-colors": { "branch": "main", "commit": "e2cb22089cc2358b2b995c09578224f142de6039" },
"nvim-lint": { "branch": "master", "commit": "4b03656c09c1561f89b6aa0665c15d292ba9499d" },
"nvim-lspconfig": { "branch": "master", "commit": "16812abf0e8d8175155f26143a8504e8253e92b0" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-notify": { "branch": "master", "commit": "8701bece920b38ea289b457f902e2ad184131a5d" },
"nvim-surround": { "branch": "main", "commit": "61319d4bd1c5e336e197defa15bd104c51f0fb29" },
"nvim-treesitter": { "branch": "main", "commit": "7caec274fd19c12b55902a5b795100d21531391f" },
"nvim-treesitter-context": { "branch": "master", "commit": "adf4b6b0420b7be6c717ef0ac7993183d6c201b1" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "93d60a475f0b08a8eceb99255863977d3a25f310" },
"nvim-web-devicons": { "branch": "master", "commit": "d7462543c9e366c0d196c7f67a945eaaf5d99414" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"render-markdown.nvim": { "branch": "main", "commit": "e3c18ddd27a853f85a6f513a864cf4f2982b9f26" },
"smart-splits.nvim": { "branch": "master", "commit": "12426763591f06b865c20990d8423345ea96d44f" },
"snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" },
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
"telescope.nvim": { "branch": "master", "commit": "5255aa27c422de944791318024167ad5d40aad20" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" },
"treesj": { "branch": "main", "commit": "26bc2a8432ba3ea79ed6aa346fba780a3d372570" },
"vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" },
"vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" },
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
}

118
lsp/basedpyright.lua Normal file
View File

@ -0,0 +1,118 @@
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
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 })
end
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'
end
local function get_current_ue_python_stub()
local ok, unreal_nvim = pcall(require, 'unreal-nvim')
if not ok then return '' end
local ue_project = unreal_nvim.find_uproject()
if ue_project then
local ue_folder = ue_project:match '^(.*[\\/])'
return ue_folder .. 'Intermediate\\PythonStub'
end
return ''
end
local function get_ue_python_plugins()
local ok, unreal_nvim = pcall(require, 'unreal-nvim')
if not ok then return {} end
local folders = {}
local ue_project = unreal_nvim.find_uproject()
if ue_project then
local ue_folder = ue_project:match '^(.*[\\/])'
local ue_plugins = ue_folder .. 'Plugins\\'
local handle = vim.loop.fs_scandir(ue_plugins)
while true do
local name, t = vim.loop.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)
if stat ~= nil and stat.type == 'directory' then
table.insert(folders, plugin_folder)
end
end
end
end
return folders
end
-- Called lazily at server start, not at file load time
local function get_extra_paths()
local paths = {
get_current_ue_python_stub(),
'C:/venvs/python_extras/Lib/site-packages',
}
vim.list_extend(paths, get_ue_python_plugins())
return paths
end
return {
cmd = { 'D:\\language-servers\\basedpyright\\Scripts\\basedpyright-langserver.exe', '--stdio' },
filetypes = { 'python' },
root_markers = {
'pyproject.toml',
'setup.py',
'setup.cfg',
'requirements.txt',
'Pipfile',
'pyrightconfig.json',
'.git',
},
before_init = function(_, config)
-- Settings are computed here, after plugins are loaded
config.settings = vim.tbl_deep_extend('force', config.settings or {}, {
python = {
pythonPath = get_python_path(),
},
basedpyright = {
disableOrganizeImports = true,
analysis = {
diagnosticSeverityOverrides = {
reportUnannotatedClassAttribute = false,
reportUnusedCallResult = false,
reportAny = false,
},
autoImportCompletions = true,
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'workspace',
extraPaths = get_extra_paths(),
},
},
})
end,
on_attach = function(client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightOrganizeImports', function()
client:exec_cmd {
command = 'basedpyright.organizeimports',
arguments = { vim.uri_from_bufnr(bufnr) },
}
end, { desc = 'Organize Imports' })
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightSetPythonPath', set_python_path, {
desc = 'Reconfigure basedpyright with the provided python path',
nargs = 1,
complete = 'file',
})
end,
}

85
lsp/clangd.lua Normal file
View File

@ -0,0 +1,85 @@
local function switch_source_header(bufnr)
local method_name = 'textDocument/switchSourceHeader'
local client = vim.lsp.get_clients({ bufnr = bufnr, name = 'clangd' })[1]
if not client then
return vim.notify(('method %s is not supported by any servers active on the current buffer'):format(method_name))
end
local params = vim.lsp.util.make_text_document_params(bufnr)
client.request(method_name, params, function(err, result)
if err then
error(tostring(err))
end
if not result then
vim.notify 'corresponding file cannot be determined'
return
end
vim.cmd.edit(vim.uri_to_fname(result))
end, bufnr)
end
local function symbol_info()
local bufnr = vim.api.nvim_get_current_buf()
local clangd_client = vim.lsp.get_clients({ bufnr = bufnr, name = 'clangd' })[1]
if not clangd_client or not clangd_client.supports_method 'textDocument/symbolInfo' then
return vim.notify('Clangd client not found', vim.log.levels.ERROR)
end
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
-- Clangd always returns an error, there is not reason to parse it
return
end
local container = string.format('container: %s', res[1].containerName) ---@type string
local name = string.format('name: %s', res[1].name) ---@type string
vim.lsp.util.open_floating_preview({ name, container }, '', {
height = 2,
width = math.max(string.len(name), string.len(container)),
focusable = false,
focus = false,
border = 'single',
title = 'Symbol Info',
})
end, bufnr)
end
---@class ClangdInitializeResult: lsp.InitializeResult
---@field offsetEncoding? string
return {
cmd = { 'D:\\language-servers\\clangd\\bin\\clangd.exe' },
filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' },
root_markers = {
'.clangd',
'.clang-tidy',
'.clang-format',
'compile_commands.json',
'compile_flags.txt',
'configure.ac', -- AutoTools
'.git',
},
capabilities = {
textDocument = {
completion = {
editsNearCursor = true,
},
},
offsetEncoding = { 'utf-8', 'utf-16' },
},
---@param client vim.lsp.Client
---@param init_result ClangdInitializeResult
on_init = function(client, init_result)
if init_result.offsetEncoding then
client.offset_encoding = init_result.offsetEncoding
end
end,
on_attach = function(_, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdSwitchSourceHeader', function()
switch_source_header(bufnr)
end, { desc = 'Switch between source/header' })
vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdShowSymbolInfo', function()
symbol_info()
end, { desc = 'Show symbol info' })
end,
}

14
lsp/lua_ls.lua Normal file
View File

@ -0,0 +1,14 @@
return {
cmd = { 'lua-language-server' },
filetypes = { 'lua' },
root_markers = {
'.luarc.json',
'.luarc.jsonc',
'.luacheckrc',
'.stylua.toml',
'stylua.toml',
'selene.toml',
'selene.yml',
'.git',
},
}

17
lsp/ty.lua Normal file
View File

@ -0,0 +1,17 @@
-- 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(),
},
}

5
lsp/typos_lsp.lua Normal file
View File

@ -0,0 +1,5 @@
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' },
}

View File

@ -1,5 +0,0 @@
-- You can add your own plugins here or in other files in this directory!
-- I promise not to create any merge conflicts in this directory :)
--
-- See the kickstart.nvim README for more information
return {}

View File

@ -1,52 +0,0 @@
--[[
--
-- This file is not required for your own configuration,
-- but helps people determine if their system is setup correctly.
--
--]]
local check_version = function()
local verstr = tostring(vim.version())
if not vim.version.ge then
vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr))
return
end
if vim.version.ge(vim.version(), '0.10-dev') then
vim.health.ok(string.format("Neovim version is: '%s'", verstr))
else
vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr))
end
end
local check_external_reqs = function()
-- Basic utils: `git`, `make`, `unzip`
for _, exe in ipairs { 'git', 'make', 'unzip', 'rg' } do
local is_executable = vim.fn.executable(exe) == 1
if is_executable then
vim.health.ok(string.format("Found executable: '%s'", exe))
else
vim.health.warn(string.format("Could not find executable: '%s'", exe))
end
end
return true
end
return {
check = function()
vim.health.start 'kickstart.nvim'
vim.health.info [[NOTE: Not every warning is a 'must-fix' in `:checkhealth`
Fix only warnings for plugins and languages you intend to use.
Mason will give warnings for languages that are not installed.
You do not need to install, unless you want to use those languages!]]
local uv = vim.uv or vim.loop
vim.health.info('System Information: ' .. vim.inspect(uv.os_uname()))
check_version()
check_external_reqs()
end,
}

53
lua/plugins/blink.lua Normal file
View File

@ -0,0 +1,53 @@
return {
'saghen/blink.cmp',
event = 'InsertEnter',
version = '1.*',
dependencies = {
{
'L3MON4D3/LuaSnip',
version = '2.*',
build = (function()
if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then
return
end
return 'make install_jsregexp'
end)(),
dependencies = {
{
'rafamadriz/friendly-snippets',
config = function()
require('luasnip.loaders.from_vscode').lazy_load()
end,
},
},
opts = {},
},
'folke/lazydev.nvim',
},
opts = {
-- 'default' (recommended) for mappings similar to built-in completions (C-y to accept)
-- 'super-tab' for mappings similar to vscode (tab to accept)
-- 'enter' for enter to accept
-- 'none' for no mappings
keymap = { preset = 'default' },
-- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font'
-- Adjusts spacing to ensure icons are aligned
appearance = { nerd_font_variant = 'mono' },
completion = {
documentation = { auto_show = false, auto_show_delay_ms = 200 },
},
sources = {
default = { 'lsp', 'path', 'snippets', 'lazydev', 'buffer' },
providers = {
lazydev = { module = 'lazydev.integrations.blink', score_offset = 100 },
},
},
snippets = { preset = 'luasnip' },
-- (Default) Rust fuzzy matcher for typo resistance and significantly better performance
-- You may use a lua implementation instead by using `implementation = "lua"` or fallback to the lua implementation,
-- when the Rust fuzzy matcher is not available, by using `implementation = "prefer_rust"`
fuzzy = { implementation = 'prefer_rust_with_warning' },
signature = { enabled = true },
},
}

View File

@ -0,0 +1,6 @@
return {
'Civitasv/cmake-tools.nvim',
dependencies = { 'nvim-lua/plenary.nvim' },
ft = { 'c', 'cpp' },
opts = {},
}

View File

@ -0,0 +1,51 @@
return {
'olimorris/codecompanion.nvim',
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-treesitter/nvim-treesitter',
},
config = function()
require('codecompanion').setup {
adapters = {
ollama = function()
return require('codecompanion.adapters').extend('ollama', {
schema = {
model = {
default = 'deepseek-coder-v2:16b',
},
},
})
end,
},
strategies = {
chat = { adapter = 'ollama' },
inline = { adapter = 'ollama' },
},
prompt_library = {
['Generate Docstring'] = {
interaction = 'inline',
description = 'Generate a docstring for the selected code',
opts = {
alias = 'doc',
placement = 'before',
modes = { 'v' },
},
prompts = {
{
role = 'user',
content = function(context)
return 'Write only the docstring comment for the following code, no explanation, no markdown, just the comment:\n\n' .. context.code
end,
},
},
},
},
}
end,
keys = {
{ '<leader>cc', '<cmd>CodeCompanionChat Toggle<cr>', desc = '[C]ode [C]ompanion Chat' },
{ '<leader>ca', '<cmd>CodeCompanionActions<cr>', mode = { 'n', 'v' }, desc = '[C]ode [A]ctions' },
{ '<leader>cd', '<cmd>CodeCompanion /doc<cr>', mode = 'v', desc = '[C]ode [D]ocstring' },
},
}

View File

@ -0,0 +1,11 @@
-- Colorscheme
return {
'ellisonleao/gruvbox.nvim',
priority = 1000,
config = function()
require('gruvbox').setup {
contrast = 'hard',
}
vim.cmd.colorscheme 'gruvbox'
end,
}

42
lua/plugins/conform.lua Normal file
View File

@ -0,0 +1,42 @@
return {
'stevearc/conform.nvim',
event = { 'BufWritePre' },
cmd = { 'ConformInfo' },
keys = {
{
'<leader>f',
function()
require('conform').format { async = true, lsp_format = 'fallback' }
end,
mode = '',
desc = '[F]ormat buffer',
},
},
opts = {
notify_on_error = false,
format_on_save = function(bufnr)
local disable_filetypes = {}
if disable_filetypes[vim.bo[bufnr].filetype] then
return nil
else
return {
timeout_ms = 500,
lsp_format = 'fallback',
}
end
end,
formatters_by_ft = {
lua = { 'stylua' },
c = { 'clang_format' },
cpp = { 'clang_format' },
python = { 'isort', 'black' },
javascript = { 'prettier' },
typescript = { 'prettier' },
javascriptreact = { 'prettier' },
typescriptreact = { 'prettier' },
json = { 'prettier' },
html = { 'prettier' },
css = { 'prettier' },
},
},
}

View File

@ -0,0 +1,12 @@
return {
'CopilotC-Nvim/CopilotChat.nvim',
dependencies = {
'github/copilot.vim',
'nvim-lua/plenary.nvim',
},
opts = {
window = {
layout = 'vertical',
},
},
}

4
lua/plugins/copilot.lua Normal file
View File

@ -0,0 +1,4 @@
return {
'github/copilot.vim',
event = 'InsertEnter',
}

View File

@ -23,6 +23,8 @@ return {
-- Add your own debuggers here -- Add your own debuggers here
'leoluz/nvim-dap-go', 'leoluz/nvim-dap-go',
'theHamsta/nvim-dap-virtual-text',
'mfussenegger/nvim-dap-python',
}, },
keys = { keys = {
-- Basic debugging keymaps, feel free to change to your liking! -- Basic debugging keymaps, feel free to change to your liking!

11
lua/plugins/fugitive.lua Normal file
View File

@ -0,0 +1,11 @@
return {
'tpope/vim-fugitive',
cmd = { 'Git', 'G' },
keys = {
{ '<leader>gs', '<cmd>Git<CR>', desc = '[G]it [S]tatus' },
{ '<leader>gd', '<cmd>Gdiffsplit<CR>', desc = '[G]it [D]iff' },
{ '<leader>gb', '<cmd>Git blame<CR>', desc = '[G]it [B]lame' },
{ '<leader>gl', '<cmd>Git log<CR>', desc = '[G]it [L]og' },
{ '<leader>gp', '<cmd>Git push<CR>', desc = '[G]it [P]ush' },
},
}

View File

@ -0,0 +1,9 @@
return {
'brenoprata10/nvim-highlight-colors',
event = 'BufReadPre',
opts = {
render = 'background', -- or 'foreground' or 'first_column'
enable_named_colors = true,
enable_tailwind = false, -- set true if you ever use Tailwind
},
}

View File

@ -4,6 +4,8 @@ return {
-- Enable `lukas-reineke/indent-blankline.nvim` -- Enable `lukas-reineke/indent-blankline.nvim`
-- See `:help ibl` -- See `:help ibl`
main = 'ibl', main = 'ibl',
opts = {}, opts = {
scope = { enabled = false },
},
}, },
} }

9
lua/plugins/lazy-dev.lua Normal file
View File

@ -0,0 +1,9 @@
return {
'folke/lazydev.nvim',
ft = 'lua',
opts = {
library = {
{ path = '${3rd}/luv/library', words = { 'vim%.uv' } },
},
},
}

View File

@ -0,0 +1,4 @@
return {
'fei6409/log-highlight.nvim',
opts = {},
}

72
lua/plugins/lsp.lua Normal file
View File

@ -0,0 +1,72 @@
return {
'neovim/nvim-lspconfig', -- still needed for default server configs
dependencies = {
'saghen/blink.cmp',
{ 'j-hui/fidget.nvim', opts = {} },
},
config = function()
-- Inject blink.cmp capabilities into ALL servers globally.
-- This replaces what the old mason-lspconfig handler was doing per-server.
vim.lsp.config('*', {
capabilities = require('blink.cmp').get_lsp_capabilities(),
})
-- 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 }),
callback = function(event)
local map = function(keys, func, desc, mode)
mode = mode or 'n'
vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
end
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('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')
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 hl_group = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false })
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
buffer = event.buf,
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('LspDetach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }),
callback = function(event2)
vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds { group = 'kickstart-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,
})
end,
}

13
lua/plugins/lualine.lua Normal file
View File

@ -0,0 +1,13 @@
-- Set lualine as statusline
return {
'nvim-lualine/lualine.nvim',
-- See `:help lualine.txt`
opts = {
options = {
icons_enabled = false,
theme = 'gruvbox',
component_separators = '|',
section_separators = '',
},
},
}

37
lua/plugins/mason.lua Normal file
View File

@ -0,0 +1,37 @@
return {
{
'mason-org/mason.nvim',
opts = {},
},
{
'WhoIsSethDaniel/mason-tool-installer.nvim',
dependencies = {
'mason-org/mason.nvim',
'mason-org/mason-lspconfig.nvim',
},
config = function()
-- mason-lspconfig only for name-mapping / install bridging, NOT for server setup
require('mason-lspconfig').setup {
ensure_installed = {},
automatic_installation = false,
}
require('mason-tool-installer').setup {
ensure_installed = {
-- LSP servers (mason package names)
'lua-language-server',
'basedpyright',
'clangd',
'typescript-language-server',
'css-lsp',
'html-lsp',
-- Formatters / linters
'stylua',
'prettier',
'black',
'isort',
},
}
end,
},
}

5
lua/plugins/mini-ai.lua Normal file
View File

@ -0,0 +1,5 @@
return {
'echasnovski/mini.ai',
event = 'VeryLazy',
opts = { n_lines = 500 },
}

View File

@ -9,7 +9,7 @@ return {
'nvim-tree/nvim-web-devicons', -- not strictly required, but recommended 'nvim-tree/nvim-web-devicons', -- not strictly required, but recommended
'MunifTanjim/nui.nvim', 'MunifTanjim/nui.nvim',
}, },
lazy = false, lazy = true,
keys = { keys = {
{ '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true }, { '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
}, },

33
lua/plugins/noice.lua Normal file
View File

@ -0,0 +1,33 @@
return {
'folke/noice.nvim',
event = 'VeryLazy',
dependencies = {
'MunifTanjim/nui.nvim',
'rcarriga/nvim-notify',
},
opts = {
lsp = {
override = {
['vim.lsp.util.convert_input_to_markdown_lines'] = true,
['vim.lsp.util.stylize_markdown'] = true,
['cmp.entry.get_documentation'] = true,
},
signature = {
enabled = false,
},
},
presets = {
-- bottom_search = true, -- classic search bar at bottom
-- command_palette = true, -- command line + popupmenu together
long_message_to_split = true,
lsp_doc_border = true,
},
routes = {
-- suppress annoying "written" message on save
{
filter = { event = 'msg_show', kind = '', find = 'written' },
opts = { skip = true },
},
},
},
}

View File

@ -0,0 +1,6 @@
-- Beautiful markdown
return {
'MeanderingProgrammer/render-markdown.nvim',
ft = { 'markdown', 'md' },
opts = {},
}

View File

@ -0,0 +1,28 @@
return {
'mrjones2014/smart-splits.nvim',
keys = {
{ '<C-h>', mode = 'n', desc = 'Move focus to the left window' },
{ '<C-j>', mode = 'n', desc = 'Move focus to the lower window' },
{ '<C-k>', mode = 'n', desc = 'Move focus to the upper window' },
{ '<C-l>', mode = 'n', desc = 'Move focus to the right window' },
{ '<A-h>', mode = 'n', desc = 'Resize split left' },
{ '<A-j>', mode = 'n', desc = 'Resize split down' },
{ '<A-k>', mode = 'n', desc = 'Resize split up' },
{ '<A-l>', mode = 'n', desc = 'Resize split right' },
},
config = function()
local ss = require 'smart-splits'
-- Moving between splits
vim.keymap.set('n', '<C-h>', ss.move_cursor_left, { desc = 'Move focus to the left window' })
vim.keymap.set('n', '<C-j>', ss.move_cursor_down, { desc = 'Move focus to the lower window' })
vim.keymap.set('n', '<C-k>', ss.move_cursor_up, { desc = 'Move focus to the upper window' })
vim.keymap.set('n', '<C-l>', ss.move_cursor_right, { desc = 'Move focus to the right window' })
-- Resizing splits
vim.keymap.set('n', '<A-h>', ss.resize_left, { desc = 'Resize split left' })
vim.keymap.set('n', '<A-j>', ss.resize_down, { desc = 'Resize split down' })
vim.keymap.set('n', '<A-k>', ss.resize_up, { desc = 'Resize split up' })
vim.keymap.set('n', '<A-l>', ss.resize_right, { desc = 'Resize split right' })
end,
}

32
lua/plugins/snacks.lua Normal file
View File

@ -0,0 +1,32 @@
-- Folk Snacks
return {
'folke/snacks.nvim',
priority = 1000,
lazy = false,
opts = {
bigfile = { enabled = true },
dashboard = { enabled = true },
indent = { enabled = true },
input = { enabled = true },
styles = {
input = {
relative = 'editor',
row = 20,
},
},
picker = { enabled = true },
quickfile = { enabled = true },
scope = { enabled = true },
-- scroll = { enabled = true },
words = { enabled = false },
-- image = {
-- enabled = true,
-- resolve = function(path, src)
-- local api = require 'obsidian.api'
-- if api.path_is_note(path) then
-- return api.resolve_attachment_path(src)
-- end
-- end,
-- },
},
}

9
lua/plugins/surround.lua Normal file
View File

@ -0,0 +1,9 @@
-- Surround
return {
'kylechui/nvim-surround',
-- version = '*', -- Use for stability; omit to use `main` branch for the latest features
event = 'VeryLazy',
config = function()
require('nvim-surround').setup {}
end,
}

View File

@ -0,0 +1,58 @@
return {
'nvim-telescope/telescope.nvim',
-- event = 'VimEnter',
dependencies = {
'nvim-lua/plenary.nvim',
{
'nvim-telescope/telescope-fzf-native.nvim',
build = 'make',
cond = function()
return vim.fn.executable 'make' == 1
end,
},
{ 'nvim-telescope/telescope-ui-select.nvim' },
{ 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font },
},
config = function()
require('telescope').setup {
extensions = {
['ui-select'] = {
require('telescope.themes').get_dropdown(),
},
},
}
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

@ -0,0 +1,6 @@
return {
'folke/todo-comments.nvim',
event = 'VimEnter',
dependencies = { 'nvim-lua/plenary.nvim' },
opts = { signs = false },
}

View File

@ -0,0 +1,41 @@
return {
'akinsho/toggleterm.nvim',
version = '*',
keys = {
{ '<C-\\>', desc = 'Toggle terminal' },
{ '<leader>tf', desc = 'Toggle floating terminal' },
{ '<leader>th', desc = 'Toggle horizontal terminal' },
},
opts = {
size = function(term)
if term.direction == 'horizontal' then
return 15
elseif term.direction == 'vertical' then
return vim.o.columns * 0.4
end
end,
open_mapping = [[<C-\>]],
direction = 'float',
float_opts = {
border = 'curved',
},
shade_terminals = true,
},
config = function(_, opts)
require('toggleterm').setup(opts)
local Terminal = require('toggleterm.terminal').Terminal
-- Floating terminal shortcut
local float_term = Terminal:new { direction = 'float' }
vim.keymap.set('n', '<leader>tf', function()
float_term:toggle()
end, { desc = '[T]oggle [F]loating terminal' })
-- Horizontal terminal shortcut
local h_term = Terminal:new { direction = 'horizontal' }
vim.keymap.set('n', '<leader>th', function()
h_term:toggle()
end, { desc = '[T]oggle [H]orizontal terminal' })
end,
}

View File

@ -0,0 +1,44 @@
return {
{
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
dependencies = {
'nvim-treesitter/nvim-treesitter-textobjects',
},
opts = {
ensure_installed = {
'bash',
'c',
'cpp',
'diff',
'html',
'lua',
'luadoc',
'markdown',
'markdown_inline',
'query',
'vim',
'vimdoc',
'python',
'javascript',
'typescript',
'tsx',
'json',
'css',
},
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = { 'ruby' },
},
indent = { enable = true, disable = { 'ruby' } },
fold = {
enable = false,
},
},
},
{
'nvim-treesitter/nvim-treesitter-context',
opts = { max_lines = 2 },
},
}

8
lua/plugins/treesj.lua Normal file
View File

@ -0,0 +1,8 @@
return {
'Wansmer/treesj',
keys = { '<space>m', '<space>j', '<space>s' },
dependencies = { 'nvim-treesitter/nvim-treesitter' }, -- if you install parsers with `nvim-treesitter`
config = function()
require('treesj').setup()
end,
}

15
lua/plugins/unreal.lua Normal file
View File

@ -0,0 +1,15 @@
-- Unreal
return {
'PlayKigai/Unreal-Nvim',
-- ft = { 'cpp', 'c', 'h', 'hpp', 'cs', 'ini', 'uproject', 'uplugin' },
cmd = { 'Unreal' },
config = function()
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)
-- }
end,
}

46
lua/plugins/which-key.lua Normal file
View File

@ -0,0 +1,46 @@
return {
'folke/which-key.nvim',
event = 'VimEnter',
opts = {
delay = 0,
icons = {
mappings = vim.g.have_nerd_font,
keys = vim.g.have_nerd_font and {} or {
Up = '<Up> ',
Down = '<Down> ',
Left = '<Left> ',
Right = '<Right> ',
C = '<C-…> ',
M = '<M-…> ',
D = '<D-…> ',
S = '<S-…> ',
CR = '<CR> ',
Esc = '<Esc> ',
ScrollWheelDown = '<ScrollWheelDown> ',
ScrollWheelUp = '<ScrollWheelUp> ',
NL = '<NL> ',
BS = '<BS> ',
Space = '<Space> ',
Tab = '<Tab> ',
F1 = '<F1>',
F2 = '<F2>',
F3 = '<F3>',
F4 = '<F4>',
F5 = '<F5>',
F6 = '<F6>',
F7 = '<F7>',
F8 = '<F8>',
F9 = '<F9>',
F10 = '<F10>',
F11 = '<F11>',
F12 = '<F12>',
},
},
spec = {
{ '<leader>s', group = '[S]earch' },
{ '<leader>t', group = '[T]oggle' },
{ '<leader>h', group = 'Git [H]unk', mode = { 'n', 'v' } },
{ '<leader>b', group = '[B]uild ' },
},
},
}

174
lua/setup/autocmds.lua Normal file
View File

@ -0,0 +1,174 @@
-- 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,
})
-- Highlight on yank
vim.api.nvim_create_autocmd('TextYankPost', {
desc = 'Highlight when yanking text',
group = vim.api.nvim_create_augroup('highlight-yank', { clear = true }),
callback = function()
vim.hl.on_yank()
end,
})
-- Load project-local config
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,
})
-- Restore cursor to file position in previous editing session
vim.api.nvim_create_autocmd('BufReadPost', {
callback = function(args)
local mark = vim.api.nvim_buf_get_mark(args.buf, '"')
local line_count = vim.api.nvim_buf_line_count(args.buf)
if mark[1] > 0 and mark[1] <= line_count then
vim.api.nvim_win_set_cursor(0, mark)
vim.schedule(function()
vim.cmd 'normal! zz'
end)
end
end,
})
-- Open help in vertical split
vim.api.nvim_create_autocmd('FileType', {
pattern = 'help',
command = 'wincmd L',
})
-- Auto resize splits when the terminal's window is resized
vim.api.nvim_create_autocmd('VimResized', {
command = 'wincmd =',
})
-- No auto continue comments on new line
vim.api.nvim_create_autocmd('FileType', {
group = vim.api.nvim_create_augroup('no_auto_comment', { clear = true }),
callback = function()
vim.opt_local.formatoptions:remove { 'c', 'r', 'o' }
end,
})
-- Show cursorline only in active window (enable)
local cursorline_group = vim.api.nvim_create_augroup('active_cursorline', { clear = true })
vim.api.nvim_create_autocmd({ 'WinEnter', 'BufEnter' }, {
group = cursorline_group,
callback = function()
vim.opt_local.cursorline = true
end,
})
-- Show cursorline only in active window (disable)
vim.api.nvim_create_autocmd({ 'WinLeave', 'BufLeave' }, {
group = cursorline_group,
callback = function()
vim.opt_local.cursorline = false
end,
})

58
lua/setup/keymap.lua Normal file
View File

@ -0,0 +1,58 @@
vim.g.mapleader = ' '
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('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
-- Disables <Space> as a normal/visual key, so it only works as leader
vim.keymap.set({ 'n', 'v' }, '<Space>', '<Nop>', { silent = true })
-- Remap jk to esc
-- vim.keymap.set({ 'n', 'v', 'i' }, 'jk', '<Esc>')
-- vim.keymap.set('t', 'jk', '<C-\\><C-n>')
-- Quickly remove search highlight with <leader><space> (now <Space><Space>)
vim.keymap.set('n', '<space><space>', ':noh<cr>', { desc = 'Remove search highlight' })
-- Makes 'j'/'k' move by visual lines when no count is given
vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
-- Move cursor right/left in insert mode with Ctrl+l/h.
vim.keymap.set('i', '<c-l>', '<Right>', { desc = 'Move to right on insert mode' })
vim.keymap.set('i', '<c-h>', '<Left>', { desc = 'Move to left on insert mode' })
vim.keymap.set('i', '<c-j>', '<Down>', { desc = 'Move to down on insert mode' })
vim.keymap.set('i', '<c-k>', '<Up>', { desc = 'Move to Up on insert mode' })
-- Move selected lines up/down in visual mode with J/K.
vim.keymap.set('v', 'J', ":m '>+1<CR>gv=gv")
vim.keymap.set('v', 'K', ":m '<-2<CR>gv=gv")
-- Scroll half-page down/up and center cursor.
vim.keymap.set('n', '<C-d>', '<C-d>zz')
vim.keymap.set('n', '<C-u>', '<C-u>zz')
-- Next/previous search result and center cursor.
vim.keymap.set('n', 'n', 'nzzzv')
vim.keymap.set('n', 'N', 'Nzzzv')
-- Paste over selection without overwriting the default register.
vim.keymap.set('x', '<leader>p', [["_dP]])
-- Delete to black hole register (doesn't overwrite yank buffer).
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)
-- 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>]])
-- Open terminal in vertical split.
vim.keymap.set('n', '<leader>tn', ':vs term://bash<CR>')

96
lua/setup/lazy.lua Normal file
View File

@ -0,0 +1,96 @@
-- [[ Install lazy.nvim ]]
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }
if vim.v.shell_error ~= 0 then
error('Error cloning lazy.nvim:\n' .. out)
end
end
vim.opt.rtp:prepend(lazypath)
require('lazy').setup({
-- Git related plugins
'sindrets/diffview.nvim',
-- Detect tabstop and shiftwidth automatically
'tpope/vim-sleuth',
-- Completion
{ import = 'plugins.blink' },
{ import = 'plugins.autopairs' },
-- LSP
{ import = 'plugins.lsp' },
{ import = 'plugins.mason' },
-- Treesitter
{ import = 'plugins.treesitter' },
-- Formatting & Linting
{ import = 'plugins.conform' },
{ import = 'plugins.lint' },
-- UI
{ import = 'plugins.colorscheme' },
{ import = 'plugins.lualine' },
{ import = 'plugins.snacks' },
{ import = 'plugins.noice' },
{ import = 'plugins.neo-tree' },
{ import = 'plugins.which-key' },
{ import = 'plugins.indent_line' },
{ import = 'plugins.render-markdown' },
{ import = 'plugins.highlight-colors' },
{ import = 'plugins.todo-comments' },
{ import = 'plugins.log-highlight' },
-- Navigation
{ import = 'plugins.telescope-fuzzy-finder' },
{ import = 'plugins.smart-splits' },
{ import = 'plugins.treesj' },
-- Git
{ import = 'plugins.fugitive' },
{ import = 'plugins.gitsigns' },
-- Editing
{ import = 'plugins.surround' },
-- { import = 'plugins.mini-nvim' }, -- replaced by individual mini.ai below
{ import = 'plugins.mini-ai' },
-- Terminal
{ import = 'plugins.toggleterm' },
-- AI
{ import = 'plugins.copilot' },
{ import = 'plugins.copilot-chat' },
{ import = 'plugins.codecompanion' },
-- Debugging
{ import = 'plugins.debug' },
-- Language specific
{ import = 'plugins.cmake-tools' },
{ import = 'plugins.unreal' },
-- Misc
{ import = 'plugins.lazy-dev' },
}, {
ui = {
icons = vim.g.have_nerd_font and {} or {
cmd = '',
config = '🛠',
event = '📅',
ft = '📂',
init = '',
keys = '🗝',
plugin = '🔌',
runtime = '💻',
require = '🌙',
source = '📄',
start = '🚀',
task = '📌',
lazy = '💤 ',
},
},
})

354
lua/setup/lsp.lua Normal file
View File

@ -0,0 +1,354 @@
vim.lsp.enable {
'lua_ls',
'basedpyright',
'clangd',
-- 'typos_lsp',
'ty',
'ts_ls',
'cssls',
'html',
}
vim.lsp.inlay_hint.enable(true)
local virtual_text_mode = nil
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 },
update_in_insert = false,
severity_sort = true,
float = {
border = 'rounded',
source = 'if_many',
},
signs = vim.g.have_nerd_font and {
text = {
[vim.diagnostic.severity.ERROR] = '󰅚 ',
[vim.diagnostic.severity.WARN] = '󰀪 ',
[vim.diagnostic.severity.INFO] = '󰋽 ',
[vim.diagnostic.severity.HINT] = '󰌶 ',
},
numhl = {
[vim.diagnostic.severity.ERROR] = 'ErrorMsg',
[vim.diagnostic.severity.WARN] = 'WarningMsg',
} or {},
},
}
vim.api.nvim_create_user_command('LspToggleDiagnostic', function()
if virtual_text_mode == nil then
virtual_text_mode = true
vim.diagnostic.config {
virtual_text = {
current_line = virtual_text_mode,
},
underline = false,
}
else
virtual_text_mode = nil
vim.diagnostic.config {
virtual_text = {
current_line = virtual_text_mode,
},
underline = true,
}
end
end, {})
vim.api.nvim_create_user_command('LspToggleInlayHints', function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end, {})
vim.keymap.set('n', '<leader>ld', '<cmd>LspToggleDiagnostic<CR>', { desc = 'Toggle Lsp Diagnostic Mode' })
vim.keymap.set('n', '<leader>li', '<cmd>LspToggleInlayHints<CR>', { desc = 'Toggle Lsp Inlay Hints' })
-- Extras
local function restart_lsp(client_name)
if not client_name or client_name == '' then
vim.notify('restart_lsp: missing client_name', vim.log.levels.WARN)
return
end
-- 1) Collect buffers that had this client and the client configs to reuse
local target = {} -- [bufnr] = client.config
local to_stop = {} -- [client_id] = true
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
end
end
end
end
if vim.tbl_isempty(target) then
vim.notify(("restart_lsp: no buffers with client '%s'"):format(client_name), vim.log.levels.INFO)
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)
end
-- 3) For each buffer, (re)start using the original config.
-- vim.lsp.start() will *reuse* a running client with same name+root_dir
-- and will attach this buffer; otherwise it spawns a new one.
vim.defer_fn(function()
for bufnr, cfg in pairs(target) do
if vim.api.nvim_buf_is_valid(bufnr) and vim.api.nvim_buf_is_loaded(bufnr) then
local conf = vim.deepcopy(cfg) -- dont mutate the old config
vim.api.nvim_buf_call(bufnr, function()
vim.lsp.start(conf)
end)
end
end
end, 100)
end
vim.api.nvim_create_user_command('LspRestart', function(opts)
restart_lsp(unpack(opts.fargs))
end, {
nargs = '?',
})
local function lsp_status()
local bufnr = vim.api.nvim_get_current_buf()
local clients = vim.lsp.get_clients { bufnr = bufnr }
if #clients == 0 then
print '󰅚 No LSP clients attached'
return
end
print('󰒋 LSP Status for buffer ' .. bufnr .. ':')
print '─────────────────────────────────'
for i, client in ipairs(clients) do
print(string.format('󰌘 Client %d: %s (ID: %d)', i, client.name, client.id))
print(' Root: ' .. (client.config.root_dir or 'N/A'))
-- print(' Filetypes: ' .. table.concat(client.config.filetypes or {}, ', '))
-- Check capabilities
local caps = client.server_capabilities
local features = {}
if caps ~= nil then
if caps.completionProvider then
table.insert(features, 'completion')
end
if caps.hoverProvider then
table.insert(features, 'hover')
end
if caps.definitionProvider then
table.insert(features, 'definition')
end
if caps.referencesProvider then
table.insert(features, 'references')
end
if caps.renameProvider then
table.insert(features, 'rename')
end
if caps.codeActionProvider then
table.insert(features, 'code_action')
end
if caps.documentFormattingProvider then
table.insert(features, 'formatting')
end
end
print(' Features: ' .. table.concat(features, ', '))
print ''
end
end
vim.api.nvim_create_user_command('LspStatus', lsp_status, { desc = 'Show detailed LSP status' })
local function check_lsp_capabilities()
local bufnr = vim.api.nvim_get_current_buf()
local clients = vim.lsp.get_clients { bufnr = bufnr }
if #clients == 0 then
print 'No LSP clients attached'
return
end
for _, client in ipairs(clients) do
print('Capabilities for ' .. client.name .. ':')
local caps = client.server_capabilities
if caps ~= nil then
local capability_list = {
{ 'Completion', caps.completionProvider },
{ 'Hover', caps.hoverProvider },
{ 'Signature Help', caps.signatureHelpProvider },
{ 'Go to Definition', caps.definitionProvider },
{ 'Go to Declaration', caps.declarationProvider },
{ 'Go to Implementation', caps.implementationProvider },
{ 'Go to Type Definition', caps.typeDefinitionProvider },
{ 'Find References', caps.referencesProvider },
{ 'Document Highlight', caps.documentHighlightProvider },
{ 'Document Symbol', caps.documentSymbolProvider },
{ 'Workspace Symbol', caps.workspaceSymbolProvider },
{ 'Code Action', caps.codeActionProvider },
{ 'Code Lens', caps.codeLensProvider },
{ 'Document Formatting', caps.documentFormattingProvider },
{ 'Document Range Formatting', caps.documentRangeFormattingProvider },
{ 'Rename', caps.renameProvider },
{ 'Folding Range', caps.foldingRangeProvider },
{ 'Selection Range', caps.selectionRangeProvider },
}
for _, cap in ipairs(capability_list) do
local status = cap[2] and '' or ''
print(string.format(' %s %s', status, cap[1]))
end
end
print ''
end
end
vim.api.nvim_create_user_command('LspCapabilities', check_lsp_capabilities, { desc = 'Show LSP capabilities' })
local function lsp_diagnostics_info()
local bufnr = vim.api.nvim_get_current_buf()
local diagnostics = vim.diagnostic.get(bufnr)
local counts = { ERROR = 0, WARN = 0, INFO = 0, HINT = 0 }
for _, diagnostic in ipairs(diagnostics) do
local severity = vim.diagnostic.severity[diagnostic.severity]
counts[severity] = counts[severity] + 1
end
print '󰒡 Diagnostics for current buffer:'
print(' Errors: ' .. counts.ERROR)
print(' Warnings: ' .. counts.WARN)
print(' Info: ' .. counts.INFO)
print(' Hints: ' .. counts.HINT)
print(' Total: ' .. #diagnostics)
end
vim.api.nvim_create_user_command('LspDiagnostics', lsp_diagnostics_info, { desc = 'Show LSP diagnostics count' })
local function lsp_info()
local bufnr = vim.api.nvim_get_current_buf()
local clients = vim.lsp.get_clients { bufnr = bufnr }
print '═══════════════════════════════════'
print ' LSP INFORMATION '
print '═══════════════════════════════════'
print ''
-- Basic info
print('󰈙 Language client log: ' .. vim.lsp.get_log_path())
print('󰈔 Detected filetype: ' .. vim.bo.filetype)
print('󰈮 Buffer: ' .. bufnr)
print('󰈔 Root directory: ' .. (vim.fn.getcwd() or 'N/A'))
print ''
if #clients == 0 then
print('󰅚 No LSP clients attached to buffer ' .. bufnr)
print ''
print 'Possible reasons:'
print(' • No language server installed for ' .. vim.bo.filetype)
print ' • Language server not configured'
print ' • Not in a project root directory'
print ' • File type not recognized'
return
end
print('󰒋 LSP clients attached to buffer ' .. bufnr .. ':')
print '─────────────────────────────────'
for i, client in ipairs(clients) do
print(string.format('󰌘 Client %d: %s', i, client.name))
print(' ID: ' .. client.id)
print(' Root dir: ' .. (client.config.root_dir or 'Not set'))
-- print(' Command: ' .. table.concat(client.config.cmd or {}, ' '))
-- print(' Filetypes: ' .. table.concat(client.config.filetypes or {}, ', '))
-- Server status
if client:is_stopped() then
print ' Status: 󰅚 Stopped'
else
print ' Status: 󰄬 Running'
end
-- Workspace folders
if client.workspace_folders and #client.workspace_folders > 0 then
print ' Workspace folders:'
for _, folder in ipairs(client.workspace_folders) do
print('' .. folder.name)
end
end
-- Attached buffers count
local attached_buffers = {}
for buf, _ in pairs(client.attached_buffers or {}) do
table.insert(attached_buffers, buf)
end
print(' Attached buffers: ' .. #attached_buffers)
-- Key capabilities
local caps = client.server_capabilities
local key_features = {}
if caps ~= nil then
if caps.completionProvider then
table.insert(key_features, 'completion')
end
if caps.hoverProvider then
table.insert(key_features, 'hover')
end
if caps.definitionProvider then
table.insert(key_features, 'definition')
end
if caps.documentFormattingProvider then
table.insert(key_features, 'formatting')
end
if caps.codeActionProvider then
table.insert(key_features, 'code_action')
end
end
if #key_features > 0 then
print(' Key features: ' .. table.concat(key_features, ', '))
end
print ''
end
-- Diagnostics summary
local diagnostics = vim.diagnostic.get(bufnr)
if #diagnostics > 0 then
print '󰒡 Diagnostics Summary:'
local counts = { ERROR = 0, WARN = 0, INFO = 0, HINT = 0 }
for _, diagnostic in ipairs(diagnostics) do
local severity = vim.diagnostic.severity[diagnostic.severity]
counts[severity] = counts[severity] + 1
end
print(' 󰅚 Errors: ' .. counts.ERROR)
print(' 󰀪 Warnings: ' .. counts.WARN)
print(' 󰋽 Info: ' .. counts.INFO)
print(' 󰌶 Hints: ' .. counts.HINT)
print(' Total: ' .. #diagnostics)
else
print '󰄬 No diagnostics'
end
print ''
print 'Use :LspLog to view detailed logs'
print 'Use :LspCapabilities for full capability list'
end
-- Create command
vim.api.nvim_create_user_command('LspInfo', lsp_info, { desc = 'Show comprehensive LSP information' })

90
lua/setup/set.lua Normal file
View File

@ -0,0 +1,90 @@
vim.g.nofsync = true
-- System Clipboard Integration
vim.schedule(function()
vim.o.clipboard = 'unnamedplus'
end)
-- Make line numbers default
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.shellcmdflag =
'-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;'
vim.opt.shellredir = '-RedirectStandardOutput %s -NoNewWindow -Wait'
vim.opt.shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
vim.opt.shellquote = ''
vim.opt.shellxquote = ''
-- Enable break indent
vim.o.breakindent = true
-- Quality of life bindings for common/essential operations
vim.cmd 'command! W w'
vim.cmd 'command! Qw wq'
vim.cmd 'command! Q q'
-- Save undo history
vim.opt.undodir = vim.fn.stdpath 'data' .. '/undodir'
vim.opt.undofile = true
-- Case-insensitive searching UNLESS \C or capital in search
vim.o.ignorecase = true
vim.o.smartcase = true
-- Keep signcolumn on by default
vim.opt.scrolloff = 10
vim.opt.signcolumn = 'yes'
vim.opt.isfname:append '@-@'
vim.opt.colorcolumn = '80'
-- Decrease update time
vim.o.timeoutlen = 300
vim.opt.updatetime = 250
-- Set completeopt to have a better completion experience
vim.o.completeopt = 'menuone,noselect'
-- NOTE: You should make sure your terminal supports this
vim.o.termguicolors = true
vim.opt.guicursor = ''
-- Setup tab
vim.opt.tabstop = 4
vim.opt.softtabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.smartindent = true
vim.o.autoindent = true
vim.opt.wrap = true
-- Disable swap and backup files
vim.opt.swapfile = false
vim.opt.backup = false
-- Search Highlighting
vim.opt.hlsearch = true
vim.opt.incsearch = true
-- Cursos and window appearance
vim.opt.cursorline = true
-- Window splitting behavior
vim.opt.splitright = true
-- Disable netrw(built-in file explorer)
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- Window border style
vim.o.winborder = 'rounded'
-- Show invisible characters
vim.o.list = true
vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '' }
-- Live substitution preview
vim.o.inccommand = 'split'

3494
tmp/nvim-profile.log Normal file

File diff suppressed because it is too large Load Diff