update nvim
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
-- ============================================================================
|
||||
-- Modern Neovim Configuration (lazy.nvim)
|
||||
-- ============================================================================
|
||||
|
||||
-- Bootstrap lazy.nvim
|
||||
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
||||
if not vim.loop.fs_stat(lazypath) then
|
||||
vim.fn.system({
|
||||
"git",
|
||||
"clone",
|
||||
"--filter=blob:none",
|
||||
"https://github.com/folke/lazy.nvim.git",
|
||||
"--branch=stable",
|
||||
lazypath,
|
||||
})
|
||||
end
|
||||
vim.opt.rtp:prepend(lazypath)
|
||||
|
||||
-- ============================================================================
|
||||
-- Plugin Specifications
|
||||
-- ============================================================================
|
||||
require("lazy").setup({
|
||||
-- File tree
|
||||
{
|
||||
'scrooloose/nerdtree',
|
||||
cmd = 'NERDTreeToggle',
|
||||
},
|
||||
|
||||
-- Build/async tools
|
||||
'tpope/vim-dispatch',
|
||||
|
||||
-- Git integration
|
||||
'tpope/vim-fugitive',
|
||||
|
||||
-- Text manipulation
|
||||
'tpope/vim-abolish',
|
||||
|
||||
-- Large file handling
|
||||
{
|
||||
'LunarVim/bigfile.nvim',
|
||||
config = function()
|
||||
require('bigfile').setup()
|
||||
end,
|
||||
},
|
||||
|
||||
-- FZF
|
||||
{ 'junegunn/fzf' },
|
||||
{
|
||||
'ibhagwan/fzf-lua',
|
||||
branch = 'main',
|
||||
config = function()
|
||||
require('fzf-lua').setup({
|
||||
winopts = {
|
||||
height = 0.95,
|
||||
width = 0.95
|
||||
}
|
||||
})
|
||||
end,
|
||||
},
|
||||
'nvim-tree/nvim-web-devicons',
|
||||
|
||||
-- Alignment
|
||||
{
|
||||
'junegunn/vim-easy-align',
|
||||
init = function()
|
||||
vim.g.easy_align_delimiters = {
|
||||
['>'] = { pattern = '>>\\|=>\\|>' },
|
||||
['/'] = {
|
||||
pattern = '//\\+\\|/\\*\\|\\*/',
|
||||
delimiter_align = 'l',
|
||||
ignore_groups = {'!Comment'}
|
||||
},
|
||||
[']'] = {
|
||||
pattern = '[[\\]]',
|
||||
left_margin = 0,
|
||||
right_margin = 0,
|
||||
stick_to_left = 0
|
||||
},
|
||||
[')'] = {
|
||||
pattern = '[)]',
|
||||
left_margin = 0,
|
||||
right_margin = 0,
|
||||
stick_to_left = 0
|
||||
},
|
||||
['('] = {
|
||||
pattern = '[(]',
|
||||
left_margin = 0,
|
||||
right_margin = 0,
|
||||
stick_to_left = 0
|
||||
},
|
||||
}
|
||||
end,
|
||||
},
|
||||
|
||||
-- File picker
|
||||
{
|
||||
'dmtrKovalenko/fff.nvim',
|
||||
build = function()
|
||||
-- this will download prebuild binary or try to use existing rustup toolchain to build from source
|
||||
-- (if you are using lazy you can use gb for rebuilding a plugin if needed)
|
||||
require("fff.download").download_or_build_binary()
|
||||
end,
|
||||
-- No need to lazy-load with lazy.nvim.
|
||||
-- This plugin initializes itself lazily.
|
||||
lazy = false,
|
||||
keys = {
|
||||
{
|
||||
"<leader>f",
|
||||
function() require('fff').find_files() end,
|
||||
desc = 'FFFind files',
|
||||
},
|
||||
{
|
||||
"<leader>r",
|
||||
function() require('fff').live_grep() end,
|
||||
desc = 'LiFFFe grep',
|
||||
},
|
||||
{
|
||||
"fz",
|
||||
function() require('fff').live_grep({
|
||||
grep = {
|
||||
modes = { 'fuzzy', 'plain' }
|
||||
}
|
||||
}) end,
|
||||
desc = 'Live fffuzy grep',
|
||||
},
|
||||
{
|
||||
"<leader>R",
|
||||
function() require('fff').live_grep({ query = vim.fn.expand("<cword>") }) end,
|
||||
desc = 'Search current word',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
-- C++ syntax highlighting
|
||||
{
|
||||
'bfrg/vim-cpp-modern',
|
||||
init = function()
|
||||
vim.g.cpp_function_highlight = 1
|
||||
vim.g.cpp_attributes_highlight = 1
|
||||
vim.g.cpp_member_highlight = 0
|
||||
vim.g.cpp_simple_highlight = 1
|
||||
end,
|
||||
},
|
||||
|
||||
-- Motion
|
||||
{
|
||||
url = 'https://codeberg.org/andyg/leap.nvim',
|
||||
lazy = false,
|
||||
config = function()
|
||||
vim.keymap.set({'n', 'x', 'o'}, '<tab>', '<Plug>(leap)')
|
||||
vim.keymap.set({'n', 'x', 'o'}, '<S-tab>', '<Plug>(leap-from-window)')
|
||||
-- Highly recommended: define a preview filter to reduce visual noise
|
||||
-- and the blinking effect after the first keypress
|
||||
-- (see `:h leap.opts.preview`).
|
||||
-- For example, skip preview if the first character of the match is
|
||||
-- whitespace or is in the middle of an alphabetic word:
|
||||
require('leap').opts.preview = function(ch0, ch1, ch2)
|
||||
return not (
|
||||
ch1:match('%s')
|
||||
or (ch0:match('%a') and ch1:match('%a') and ch2:match('%a'))
|
||||
)
|
||||
end
|
||||
|
||||
-- Define equivalence classes for brackets and quotes, in addition to
|
||||
-- the default whitespace group:
|
||||
require('leap').opts.equivalence_classes = { ' \t\r\n', '([{', ')]}', '\'"`' }
|
||||
|
||||
-- Use the traversal keys to repeat the previous motion without
|
||||
-- explicitly invoking Leap:
|
||||
require('leap.user').set_repeat_keys('<enter>', '<backspace>')
|
||||
|
||||
-- Automatic paste after remote yank operations:
|
||||
vim.api.nvim_create_autocmd('User', {
|
||||
pattern = 'RemoteOperationDone',
|
||||
group = vim.api.nvim_create_augroup('LeapRemote', {}),
|
||||
callback = function(event)
|
||||
if vim.v.operator == 'y' and event.data.register == '"' then
|
||||
vim.cmd('normal! p')
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
},
|
||||
|
||||
-- Theme
|
||||
{
|
||||
'sainnhe/gruvbox-material',
|
||||
priority = 1000,
|
||||
init = function()
|
||||
vim.g.gruvbox_material_background = 'hard'
|
||||
vim.g.gruvbox_material_foreground = 'mix'
|
||||
vim.g.gruvbox_material_disable_italic_comment = 1
|
||||
vim.g.gruvbox_material_enable_italic = 0
|
||||
vim.g.gruvbox_material_enable_bold = 0
|
||||
vim.g.gruvbox_material_diagnostic_virtual_text = 'colored'
|
||||
vim.g.gruvbox_material_better_performance = 1
|
||||
end,
|
||||
config = function()
|
||||
vim.cmd('colorscheme gruvbox-material')
|
||||
end,
|
||||
},
|
||||
|
||||
-- Odin syntax
|
||||
'Tetralux/odin.vim',
|
||||
|
||||
-- Treesitter
|
||||
{
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
build = ':TSUpdate',
|
||||
},
|
||||
|
||||
-- LSP
|
||||
{
|
||||
'williamboman/mason.nvim',
|
||||
config = function()
|
||||
require('mason').setup({})
|
||||
end,
|
||||
},
|
||||
{
|
||||
'williamboman/mason-lspconfig.nvim',
|
||||
config = function()
|
||||
require('mason-lspconfig').setup({
|
||||
ensure_installed = { "clangd" },
|
||||
automatic_enable = true,
|
||||
})
|
||||
end,
|
||||
},
|
||||
'neovim/nvim-lspconfig',
|
||||
|
||||
-- Completion
|
||||
{
|
||||
'hrsh7th/nvim-cmp',
|
||||
dependencies = {
|
||||
'hrsh7th/cmp-nvim-lsp',
|
||||
'hrsh7th/cmp-buffer',
|
||||
'hrsh7th/cmp-path',
|
||||
'L3MON4D3/LuaSnip',
|
||||
},
|
||||
config = function()
|
||||
local cmp = require('cmp')
|
||||
cmp.setup({
|
||||
sources = {
|
||||
{ name = 'nvim_lsp' },
|
||||
{ name = 'buffer' },
|
||||
{ name = 'path' },
|
||||
},
|
||||
mapping = cmp.mapping.preset.insert({
|
||||
['<CR>'] = cmp.mapping.confirm({ select = false }),
|
||||
['<Tab>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
|
||||
['<S-Tab>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
|
||||
}),
|
||||
snippet = {
|
||||
expand = function(args)
|
||||
require('luasnip').lsp_expand(args.body)
|
||||
end,
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
'hrsh7th/cmp-nvim-lsp',
|
||||
'hrsh7th/cmp-buffer',
|
||||
'hrsh7th/cmp-path',
|
||||
'L3MON4D3/LuaSnip',
|
||||
|
||||
-- Utilities
|
||||
'nvim-lua/plenary.nvim',
|
||||
{
|
||||
"ThePrimeagen/99",
|
||||
config = function()
|
||||
local _99 = require("99")
|
||||
_99.setup({
|
||||
-- When setting this to something that is not inside the CWD tools
|
||||
-- such as claude code or opencode will have permission issues
|
||||
-- and generation will fail refer to tool documentation to resolve
|
||||
-- https://opencode.ai/docs/permissions/#external-directories
|
||||
-- https://code.claude.com/docs/en/permissions#read-and-edit
|
||||
tmp_dir = "./tmp",
|
||||
provider = _99.Providers.OpenCodeProvider,
|
||||
model = "kimi-k2.5",
|
||||
})
|
||||
|
||||
-- take extra note that i have visual selection only in v mode
|
||||
-- technically whatever your last visual selection is, will be used
|
||||
-- so i have this set to visual mode so i dont screw up and use an
|
||||
-- old visual selection
|
||||
--
|
||||
-- likely ill add a mode check and assert on required visual mode
|
||||
-- so just prepare for it now
|
||||
vim.keymap.set("v", "<leader>9v", function() _99.visual() end)
|
||||
|
||||
--- if you have a request you dont want to make any changes, just cancel it
|
||||
vim.keymap.set("n", "<leader>9x", function() _99.stop_all_requests() end)
|
||||
vim.keymap.set("n", "<leader>9s", function() _99.search() end)
|
||||
end,
|
||||
},
|
||||
}, {
|
||||
install = {
|
||||
colorscheme = { "gruvbox-material" },
|
||||
},
|
||||
checker = {
|
||||
enabled = false,
|
||||
},
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- Options
|
||||
-- ============================================================================
|
||||
vim.opt.autowrite = true
|
||||
vim.opt.colorcolumn = { 80, 100 }
|
||||
vim.opt.completeopt = { 'menu', 'menuone', 'noselect' }
|
||||
vim.opt.cpoptions:append('$')
|
||||
vim.opt.cursorline = true
|
||||
vim.opt.expandtab = true
|
||||
vim.opt.guifont = { 'JetBrains_Mono:h9', 'Consolas:h9', 'InputMonoCondensed:h9' }
|
||||
vim.opt.hlsearch = false
|
||||
vim.opt.ignorecase = true
|
||||
vim.opt.linebreak = true
|
||||
vim.opt.list = true
|
||||
vim.opt.listchars:append('tab:>-,trail:■,extends:»,precedes:«')
|
||||
vim.opt.number = true
|
||||
vim.opt.relativenumber = true
|
||||
vim.opt.shiftwidth = 4
|
||||
vim.opt.splitright = true
|
||||
vim.opt.swapfile = false
|
||||
vim.opt.textwidth = 80
|
||||
vim.opt.visualbell = true
|
||||
vim.opt.wrap = false
|
||||
vim.opt.signcolumn = 'no'
|
||||
|
||||
-- Setup undo and backup directories
|
||||
vim.opt.undofile = true
|
||||
vim.opt.undodir = vim.fn.stdpath('config') .. '/undo'
|
||||
vim.opt.backupdir = vim.fn.stdpath('config') .. '/backup'
|
||||
|
||||
-- Status line
|
||||
vim.opt.statusline = '%<%F%h%m%r [%{&ff}] (%{strftime("%H:%M %d/%m/%Y",getftime(expand("%:p")))})%=%l,%c%V %P'
|
||||
|
||||
-- Wild ignore
|
||||
vim.opt.wildignore:append('*.class,*.o,*\\tmp\\*,*.swp,*.zip,*.exe,*.obj,*.vcxproj,*.pdb,*.idb')
|
||||
|
||||
-- Mouse support
|
||||
vim.opt.mouse = 'a'
|
||||
|
||||
-- Spelling
|
||||
vim.opt.spell = true
|
||||
|
||||
-- ============================================================================
|
||||
-- LSP Configuration
|
||||
-- ============================================================================
|
||||
local opts = { noremap = true, silent = true }
|
||||
vim.keymap.set("n", "<F2>", vim.lsp.buf.rename, opts)
|
||||
vim.keymap.set("n", "<F4>", vim.lsp.buf.code_action, opts)
|
||||
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
|
||||
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
|
||||
|
||||
-- Diagnostic configuration
|
||||
vim.diagnostic.config({
|
||||
signs = false,
|
||||
virtual_text = true,
|
||||
})
|
||||
|
||||
-- Spelling highlight
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
callback = function()
|
||||
vim.cmd("highlight SpellBad gui=underline guifg=#d3869b")
|
||||
end,
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- Vim Dispatch Configuration
|
||||
-- ============================================================================
|
||||
if vim.fn.has('win64') == 1 or vim.fn.has('win32') == 1 or vim.fn.has('win16') == 1 then
|
||||
if os.getenv('SHELL') ~= nil then
|
||||
vim.o.shellcmdflag = '-c'
|
||||
vim.o.makeprg = "./build.sh"
|
||||
else
|
||||
vim.o.makeprg = "build.bat"
|
||||
end
|
||||
else
|
||||
vim.o.makeprg = "./build.sh"
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- Autocommands
|
||||
-- ============================================================================
|
||||
|
||||
-- Automatically scroll to bottom of quickfix window when opened
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = "qf",
|
||||
callback = function()
|
||||
vim.cmd('normal! G')
|
||||
end,
|
||||
})
|
||||
|
||||
-- Per-Project Bindings - load project file on buffer enter
|
||||
vim.api.nvim_create_autocmd("BufEnter", {
|
||||
callback = function()
|
||||
local project_file = vim.fn.getcwd() .. '/project_nvim.lua'
|
||||
if vim.fn.filereadable(project_file) == 1 then
|
||||
vim.cmd('luafile ' .. vim.fn.fnameescape(project_file))
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Formatting options
|
||||
vim.api.nvim_create_augroup("persistent_settings", { clear = true })
|
||||
vim.api.nvim_create_autocmd("BufEnter", {
|
||||
group = "persistent_settings",
|
||||
pattern = "*",
|
||||
command = "set formatoptions=q1j",
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- Functions
|
||||
-- ============================================================================
|
||||
local function raddbg_open_file()
|
||||
local filepath = vim.fn.expand("%:p"):gsub('\\', '/')
|
||||
vim.fn.system("dev raddbg --ipc open " .. filepath)
|
||||
vim.fn.system("dev raddbg --ipc goto_line " .. vim.fn.line("."))
|
||||
vim.fn.system("powershell -Command Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.Interaction]::AppActivate('The RAD Debugger')")
|
||||
end
|
||||
|
||||
local function raddbg_start_debugging()
|
||||
vim.fn.system("dev raddbg --ipc run")
|
||||
end
|
||||
|
||||
local function raddbg_stop_debugging()
|
||||
vim.fn.system("dev raddbg --ipc kill_all")
|
||||
end
|
||||
|
||||
local function raddbg_run_to_cursor()
|
||||
local filepath = vim.fn.expand("%:p"):gsub('\\', '/')
|
||||
vim.fn.system("dev raddbg --ipc open " .. filepath)
|
||||
vim.fn.system("dev raddbg --ipc goto_line " .. vim.fn.line("."))
|
||||
vim.fn.system("dev raddbg --ipc run_to_cursor " .. filepath .. ":" .. vim.fn.line("."))
|
||||
vim.fn.system("powershell -Command Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.Interaction]::AppActivate('The RAD Debugger')")
|
||||
end
|
||||
|
||||
local function raddbg_add_breakpoint()
|
||||
local filepath = vim.fn.expand("%:p"):gsub('\\', '/')
|
||||
vim.fn.system("dev raddbg --ipc open " .. filepath)
|
||||
vim.fn.system("dev raddbg --ipc goto_line " .. vim.fn.line("."))
|
||||
vim.fn.system("dev raddbg --ipc toggle_breakpoint " .. filepath .. ":" .. vim.fn.line("."))
|
||||
vim.fn.system("powershell -Command Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.Interaction]::AppActivate('The RAD Debugger')")
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- Keymaps
|
||||
-- ============================================================================
|
||||
|
||||
-- Font size adjustment (GUI only)
|
||||
vim.keymap.set('n', '<C-Up>', function()
|
||||
vim.opt.guifont = vim.fn.substitute(vim.opt.guifont:get()[1] or '', ':h\\zs\\d\\+', function(m)
|
||||
return tostring(tonumber(m) + 1)
|
||||
end, 'g')
|
||||
end, { silent = true })
|
||||
|
||||
vim.keymap.set('n', '<C-Down>', function()
|
||||
vim.opt.guifont = vim.fn.substitute(vim.opt.guifont:get()[1] or '', ':h\\zs\\d\\+', function(m)
|
||||
return tostring(tonumber(m) - 1)
|
||||
end, 'g')
|
||||
end, { silent = true })
|
||||
|
||||
-- FZF Bindings
|
||||
vim.keymap.set('n', '<leader>h', '<cmd>FzfLua oldfiles<cr>')
|
||||
vim.keymap.set('n', '<leader>t', '<cmd>FzfLua lsp_live_workspace_symbols<cr>')
|
||||
vim.keymap.set('n', '<leader>T', '<cmd>FzfLua lsp_finder<cr>')
|
||||
vim.keymap.set('n', '<leader>b', '<cmd>FzfLua buffers<cr>')
|
||||
vim.keymap.set('n', '<leader><leader>', '<cmd>FzfLua<cr>')
|
||||
|
||||
-- Window navigation
|
||||
vim.keymap.set('n', '<C-h>', '<C-w>h', { silent = true })
|
||||
vim.keymap.set('n', '<C-j>', '<C-w>j', { silent = true })
|
||||
vim.keymap.set('n', '<C-k>', '<C-w>k', { silent = true })
|
||||
vim.keymap.set('n', '<C-l>', '<C-w>l', { silent = true })
|
||||
|
||||
-- Move by wrapped lines
|
||||
vim.keymap.set('n', 'j', 'gj')
|
||||
vim.keymap.set('n', 'k', 'gk')
|
||||
vim.keymap.set('n', 'gj', 'j')
|
||||
vim.keymap.set('n', 'gk', 'k')
|
||||
|
||||
-- NERDTree
|
||||
vim.keymap.set('n', '<C-n>', ':NERDTreeToggle<CR>')
|
||||
|
||||
-- Change to current buffer's directory
|
||||
vim.keymap.set('n', 'cd', function()
|
||||
vim.cmd('cd ' .. vim.fn.expand('%:p:h'))
|
||||
end)
|
||||
|
||||
-- Buffer splitting
|
||||
vim.keymap.set('n', '<leader>s', ':vs<CR>')
|
||||
|
||||
-- Quickfix navigation
|
||||
vim.keymap.set('n', '<A-j>', ':cn<CR>')
|
||||
vim.keymap.set('n', '<A-k>', ':cp<CR>')
|
||||
|
||||
-- Terminal escape
|
||||
vim.keymap.set('t', '<Esc>', '<C-\\><C-n>')
|
||||
|
||||
-- Make (Vim Dispatch)
|
||||
vim.keymap.set('n', '<C-b>', ':Make<CR>', { noremap = true })
|
||||
|
||||
-- Easy-Align
|
||||
vim.keymap.set('x', '<leader>a', '<Plug>(LiveEasyAlign)')
|
||||
|
||||
-- RAD Debugger
|
||||
vim.keymap.set('n', '<F6>', function() raddbg_open_file() end, { silent = true })
|
||||
vim.keymap.set('n', '<F5>', function() raddbg_start_debugging() end, { silent = true })
|
||||
vim.keymap.set('n', '<S-F5>', function() raddbg_stop_debugging() end, { silent = true })
|
||||
vim.keymap.set('n', '<F9>', function() raddbg_add_breakpoint() end, { silent = true })
|
||||
vim.keymap.set('n', '<C-F10>', function() raddbg_run_to_cursor() end, { silent = true })
|
||||
Reference in New Issue
Block a user