This commit is contained in:
Walter Jenkins 2025-11-22 13:48:29 -06:00 committed by GitHub
commit 6fdee2513b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 2669 additions and 1285 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ nvim
spell/ spell/
lazy-lock.json lazy-lock.json
.github/.DS_Store

13
.prettierrc.json Normal file
View File

@ -0,0 +1,13 @@
{
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"quoteProps": "as-needed",
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "avoid",
"plugins": ["prettier-plugin-go-template"]
}

View File

@ -4,3 +4,4 @@ indent_type = "Spaces"
indent_width = 2 indent_width = 2
quote_style = "AutoPreferSingle" quote_style = "AutoPreferSingle"
call_parentheses = "None" call_parentheses = "None"
virtualedit = onemore

1065
init.lua

File diff suppressed because it is too large Load Diff

9
lazyvim.json Normal file
View File

@ -0,0 +1,9 @@
{
"extras": [
],
"news": {
"NEWS.md": "10960"
},
"version": 8
}

193
lua/core/keymaps.lua Normal file
View File

@ -0,0 +1,193 @@
-- Keymaps for better default experience
-- Set leader key
vim.g.mapleader = ' '
vim.g.maplocalleader = ' '
-- For conciseness
local opts = { noremap = true, silent = true }
-- Disable the spacebar key's default behavior in Normal and Visual modes
vim.keymap.set({ 'n', 'v' }, '<Space>', '<Nop>', { silent = true })
-- Allow moving the cursor through wrapped lines with j, k
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 })
-- clear highlights
vim.keymap.set('n', '<Esc>', ':noh<CR>', opts)
-- save file
vim.keymap.set('n', '<C-s>', '<cmd> w <CR>', opts)
-- save file without auto-formatting
vim.keymap.set('n', '<leader>sn', '<cmd>noautocmd w <CR>', opts)
-- quit file
vim.keymap.set('n', '<C-q>', '<cmd> q <CR>', opts)
-- delete single character without copying into register
vim.keymap.set('n', 'x', '"_x', opts)
-- Vertical scroll and center
vim.keymap.set('n', '<C-d>', '<C-d>zz', opts)
vim.keymap.set('n', '<C-u>', '<C-u>zz', opts)
-- Find and center
vim.keymap.set('n', 'n', 'nzzzv')
vim.keymap.set('n', 'N', 'Nzzzv')
-- Resize with arrows
vim.keymap.set('n', '<Up>', ':resize -2<CR>', opts)
vim.keymap.set('n', '<Down>', ':resize +2<CR>', opts)
vim.keymap.set('n', '<Left>', ':vertical resize -2<CR>', opts)
vim.keymap.set('n', '<Right>', ':vertical resize +2<CR>', opts)
-- Buffers
vim.keymap.set('n', '<S-l>', ':bnext<CR>', opts)
vim.keymap.set('n', '<S-h>', ':bprevious<CR>', opts)
vim.keymap.set('n', '<leader>x', ':Bdelete!<CR>', opts) -- close buffer
vim.keymap.set('n', '<leader>b', '<cmd> enew <CR>', opts) -- new buffer
-- Increment/decrement numbers
vim.keymap.set('n', '<leader>+', '<C-a>', opts) -- increment
vim.keymap.set('n', '<leader>-', '<C-x>', opts) -- decrement
-- Window management
vim.keymap.set('n', '<leader>v', '<C-w>v', opts) -- split window vertically
vim.keymap.set('n', '<leader>h', '<C-w>s', opts) -- split window horizontally
vim.keymap.set('n', '<leader>se', '<C-w>=', opts) -- make split windows equal width & height
vim.keymap.set('n', '<leader>xs', ':close<CR>', opts) -- close current split window
-- Navigate between splits - DISABLED: Using Zellij navigation
-- vim.keymap.set('n', '<C-k>', ':wincmd k<CR>', opts)
-- vim.keymap.set('n', '<C-j>', ':wincmd j<CR>', opts)
-- vim.keymap.set('n', '<C-h>', ':wincmd h<CR>', opts)
-- vim.keymap.set('n', '<C-l>', ':wincmd l<CR>', opts)
-- Tabs
vim.keymap.set('n', '<leader>to', ':tabnew<CR>', opts) -- open new tab
vim.keymap.set('n', '<leader>tx', ':tabclose<CR>', opts) -- close current tab
vim.keymap.set('n', '<leader>tn', ':tabn<CR>', opts) -- go to next tab
vim.keymap.set('n', '<leader>tp', ':tabp<CR>', opts) -- go to previous tab
-- Toggle line wrapping
vim.keymap.set('n', '<leader>lw', '<cmd>set wrap!<CR>', opts)
-- Press jk fast to exit insert mode
vim.keymap.set('i', 'jk', '<ESC>', opts)
vim.keymap.set('i', 'kj', '<ESC>', opts)
-- Stay in indent mode
vim.keymap.set('v', '<', '<gv', opts)
vim.keymap.set('v', '>', '>gv', opts)
-- Move text up and down
vim.keymap.set('v', '<A-j>', ':m .+1<CR>==', opts)
vim.keymap.set('v', '<A-k>', ':m .-2<CR>==', opts)
-- Keep last yanked when pasting
vim.keymap.set('v', 'p', '"_dP', opts)
-- Replace word under cursor
vim.keymap.set('n', '<leader>j', '*``cgn', opts)
-- Explicitly yank to system clipboard (highlighted and entire row)
vim.keymap.set({ 'n', 'v' }, '<leader>y', [["+y]])
vim.keymap.set('n', '<leader>Y', [["+Y]])
-- Toggle diagnostics
local diagnostics_active = true
vim.keymap.set('n', '<leader>do', function()
diagnostics_active = not diagnostics_active
if diagnostics_active then
vim.diagnostic.enable(0)
else
vim.diagnostic.disable(0)
end
end)
-- Diagnostic keymaps
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous diagnostic message' })
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next diagnostic message' })
vim.keymap.set('n', '<leader>d', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' })
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostics list' })
-- Save and load session
vim.keymap.set('n', '<leader>ss', ':mksession! .session.vim<CR>', { noremap = true, silent = false })
vim.keymap.set('n', '<leader>sl', ':source .session.vim<CR>', { noremap = true, silent = false })
-- exit insrrt mode with jk
vim.keymap.set('i', 'jk', '<ESC>', { noremap = true, silent = true, desc = '<ESC>' })
-- -- option + a to select all text in a file
vim.keymap.set('n', '<M-a>', 'ggVG', { noremap = true, silent = true, desc = 'Select all' })
--
-- Map the function to a key combination
vim.keymap.set('n', '<leader>te', 'oif err != nil {<CR>}<Esc>Oreturn err<Esc>')
--
-- -- Remap <Leader>x to close the current buffer
vim.api.nvim_set_keymap('n', '<Leader>x', ':bd<CR>', { noremap = true, silent = true })
-- vim.api.nvim_del_keymap('n', '<Leader>l')
-- Function to restart LSP
vim.api.nvim_set_keymap('n', '<leader>L', ':LspRestart<CR>', { noremap = true, silent = true })
-- -- Remap <Leader>l to restart LSP
vim.api.nvim_set_keymap('n', '<Leader>l', '<cmd>lua restart_lsp()<CR>', { noremap = true, silent = true })
-- Remap leader+f to leader+F
vim.api.nvim_set_keymap('n', '<leader><leader>', '<leader>fF', { noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<leader>ff', '<leader>fF', { noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<leader>ft', '<leader>fT', { noremap = true, silent = true })
vim.keymap.set('n', '<Tab>', '20j', { noremap = true, silent = true })
vim.keymap.set('n', '<S-Tab>', '20k', { noremap = true, silent = true })
-- diagnostic
local diagnostic_goto = function(next, severity)
local go = next and vim.diagnostic.goto_next or vim.diagnostic.goto_prev
severity = severity and vim.diagnostic.severity[severity] or nil
return function()
go { severity = severity }
end
end
vim.keymap.set('n', '<leader>cd', vim.diagnostic.open_float, { desc = 'Line Diagnostics' })
vim.keymap.set('n', ']d', diagnostic_goto(true), { desc = 'Next Diagnostic' })
vim.keymap.set('n', '[d', diagnostic_goto(false), { desc = 'Prev Diagnostic' })
vim.keymap.set('n', ']e', diagnostic_goto(true, 'ERROR'), { desc = 'Next Error' })
vim.keymap.set('n', '[e', diagnostic_goto(false, 'ERROR'), { desc = 'Prev Error' })
vim.keymap.set('n', ']w', diagnostic_goto(true, 'WARN'), { desc = 'Next Warning' })
vim.keymap.set('n', '[w', diagnostic_goto(false, 'WARN'), { desc = 'Prev Warning' })
vim.api.nvim_set_hl(0, '@lsp.type.unused', { link = 'Comment' })
-- jumping lines
-- vim.keymap.del("n", "<S-[>")
-- vim.keymap.del("n", "<S-]>")
vim.keymap.set("n", "<S-[>", "{", { noremap = true, silent = true }) -- Jump up to previous empty line
vim.keymap.set("n", "<S-]>", "}", { noremap = true, silent = true }) -- Jump down to next empty line
vim.keymap.set('n', '<leader>st', function()
require('telescope.builtin').live_grep({ default_text = "// TODO:" })
end, { desc = "Search for TODO comments" })
vim.keymap.set('n', '<leader>sx', function()
require('telescope.builtin').live_grep({ default_text = "// FUTURE:" })
end, { desc = "Search for FUTURE comments" })
vim.keymap.set('n', '<leader>si', function()
require('telescope.builtin').live_grep({ default_text = "// IMPORTANT:" })
end, { desc = "Search for IMPORTANT comments" })
-- Define highlight groups for comment tags
vim.api.nvim_set_hl(0, "FutureHighlight", { bg = "#3b4252", fg = "#81a1c1", bold = true }) -- Light blue
vim.api.nvim_set_hl(0, "FixmeHighlight", { bg = "#3b4252", fg = "#bf616a", bold = true }) -- Red
vim.api.nvim_set_hl(0, "NoteHighlight", { bg = "#3b4252", fg = "#ebcb8b", bold = true }) -- Yellow
vim.api.nvim_set_hl(0, "QuestionHighlight", { bg = "#3b4252", fg = "#b48ead", bold = true }) -- Purple
vim.api.nvim_set_hl(0, "ImportantHighlight", { bg = "#3b4252", fg = "#a3be8c", bold = true }) -- Green

81
lua/core/options.lua Normal file
View File

@ -0,0 +1,81 @@
vim.o.hlsearch = false -- Set highlight on search
vim.wo.number = true -- Make line numbers default
vim.o.mouse = 'a' -- Enable mouse mode
vim.o.clipboard = 'unnamedplus' -- Sync clipboard between OS and Neovim.
vim.o.breakindent = true -- Enable break indent
vim.o.undofile = true -- Save undo history
vim.o.ignorecase = true -- Case-insensitive searching UNLESS \C or capital in search
vim.o.smartcase = true -- smart case
vim.wo.signcolumn = 'yes' -- Keep signcolumn on by default
vim.o.updatetime = 250 -- Decrease update time
vim.o.timeoutlen = 300 -- time to wait for a mapped sequence to complete (in milliseconds)
vim.o.backup = false -- creates a backup file
vim.o.writebackup = false -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited
vim.o.completeopt = 'menuone,noselect' -- Set completeopt to have a better completion experience
vim.opt.termguicolors = true -- set termguicolors to enable highlight groups
vim.o.whichwrap = 'bs<>[]hl' -- which "horizontal" keys are allowed to travel to prev/next line
vim.o.wrap = false -- display lines as one long line
vim.o.linebreak = true -- companion to wrap don't split words
vim.o.scrolloff = 0 -- minimal number of screen lines to keep above and below the cursor
vim.o.sidescrolloff = 8 -- minimal number of screen columns either side of cursor if wrap is `false`
vim.o.relativenumber = true -- set relative numbered lines
vim.o.numberwidth = 4 -- set number column width to 2 {default 4}
vim.o.shiftwidth = 4 -- the number of spaces inserted for each indentation
vim.o.tabstop = 2 -- insert n spaces for a tab
vim.o.softtabstop = 4 -- Number of spaces that a tab counts for while performing editing operations
vim.o.expandtab = true -- convert tabs to spaces
vim.o.cursorline = true -- highlight the current line
vim.o.splitbelow = true -- force all horizontal splits to go below current window
vim.o.splitright = true -- force all vertical splits to go to the right of current window
vim.o.swapfile = false -- creates a swapfile
vim.o.smartindent = true -- make indenting smarter again
vim.o.showmode = false -- we don't need to see things like -- INSERT -- anymore
vim.o.showtabline = 2 -- always show tabs
vim.o.backspace = 'indent,eol,start' -- allow backspace on
vim.o.pumheight = 10 -- pop up menu height
vim.o.conceallevel = 0 -- so that `` is visible in markdown files
vim.o.fileencoding = 'utf-8' -- the encoding written to a file
vim.o.cmdheight = 1 -- more space in the neovim command line for displaying messages
vim.o.autoindent = true -- copy indent from current line when starting new one
vim.opt.shortmess:append 'c' -- don't give |ins-completion-menu| messages
vim.opt.iskeyword:append '-' -- hyphenated words recognized by searches
vim.opt.formatoptions:remove { 'c', 'r', 'o' } -- don't insert the current comment leader automatically for auto-wrapping comments using 'textwidth', hitting <Enter> in insert mode, or hitting 'o' or 'O' in normal mode.
vim.opt.runtimepath:remove '/usr/share/vim/vimfiles' -- separate vim plugins from neovim in case vim still in use
-- -- Ensure fold method is set (syntax-based folding is great for Nim)
-- vim.o.foldmethod = "syntax"
-- vim.o.foldenable = true -- Enable folding at startup
-- vim.o.foldlevel = 99 -- Open all folds by default
-- Use Treesitter for better folding (Recommended)
vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"
-- Set fold level
vim.opt.foldenable = true
vim.opt.foldlevel = 99 -- Keep folds open by default
vim.api.nvim_create_autocmd("FileType", {
pattern = "templ",
callback = function()
vim.bo.tabstop = 2
vim.bo.shiftwidth = 2
vim.bo.softtabstop = 2
vim.bo.expandtab = true
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = { "typescript", "typescriptreact", "javascript", "javascriptreact" },
callback = function()
vim.bo.tabstop = 2
vim.bo.shiftwidth = 2
vim.bo.softtabstop = 2
vim.bo.expandtab = true
end,
})

45
lua/core/snippets.lua Normal file
View File

@ -0,0 +1,45 @@
-- Custom code snippets for different purposes
-- Prevent LSP from overwriting treesitter color settings
-- https://github.com/NvChad/NvChad/issues/1907
vim.highlight.priorities.semantic_tokens = 95 -- Or any number lower than 100, treesitter's priority level
-- Appearance of diagnostics
vim.diagnostic.config {
virtual_text = {
prefix = '',
-- Add a custom format function to show error codes
format = function(diagnostic)
local code = diagnostic.code and string.format('[%s]', diagnostic.code) or ''
return string.format('%s %s', code, diagnostic.message)
end,
},
underline = false,
update_in_insert = true,
float = {
source = 'always', -- Or "if_many"
},
-- Make diagnostic background transparent
on_ready = function()
vim.cmd 'highlight DiagnosticVirtualText guibg=NONE'
end,
}
-- Highlight on yank
local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true })
vim.api.nvim_create_autocmd('TextYankPost', {
callback = function()
vim.highlight.on_yank()
end,
group = highlight_group,
pattern = '*',
})
-- Set kitty terminal padding to 0 when in nvim
vim.cmd [[
augroup kitty_mp
autocmd!
au VimLeave * :silent !kitty @ set-spacing padding=default margin=default
au VimEnter * :silent !kitty @ set-spacing padding=0 margin=0 3 0 3
augroup END
]]

58
lua/core/ui.lua Normal file
View File

@ -0,0 +1,58 @@
return {
{
'folke/noice.nvim',
opts = function(_, opts)
-- 🔥 Ensure `opts.presets` is initialized before modifying
opts.presets = opts.presets or {}
opts.presets.lsp_doc_border = true
-- 🔥 Ensure `opts.routes` is a table before inserting
opts.routes = opts.routes or {}
table.insert(opts.routes, {
filter = {
event = 'notify',
find = 'No information available',
},
opts = { skip = true },
})
end,
},
{
'akinsho/bufferline.nvim',
event = 'VeryLazy',
opts = {
options = {
show_buffer_close_icons = false,
show_close_icon = false,
},
},
},
{
'nvimdev/dashboard-nvim',
event = 'VimEnter',
opts = function(_, opts)
local logo = [[
]]
logo = string.rep('\n', 8) .. logo .. '\n\n'
opts.config = opts.config or {}
opts.config.header = vim.split(logo, '\n')
-- ✅ Disable project module to avoid error
opts.config.project = { enable = false }
end,
},
}

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,
}

View File

@ -1,148 +0,0 @@
-- debug.lua
--
-- Shows how to use the DAP plugin to debug your code.
--
-- Primarily focused on configuring the debugger for Go, but can
-- be extended to other languages as well. That's why it's called
-- kickstart.nvim and not kitchen-sink.nvim ;)
return {
-- NOTE: Yes, you can install new plugins here!
'mfussenegger/nvim-dap',
-- NOTE: And you can specify dependencies as well
dependencies = {
-- Creates a beautiful debugger UI
'rcarriga/nvim-dap-ui',
-- Required dependency for nvim-dap-ui
'nvim-neotest/nvim-nio',
-- Installs the debug adapters for you
'mason-org/mason.nvim',
'jay-babu/mason-nvim-dap.nvim',
-- Add your own debuggers here
'leoluz/nvim-dap-go',
},
keys = {
-- Basic debugging keymaps, feel free to change to your liking!
{
'<F5>',
function()
require('dap').continue()
end,
desc = 'Debug: Start/Continue',
},
{
'<F1>',
function()
require('dap').step_into()
end,
desc = 'Debug: Step Into',
},
{
'<F2>',
function()
require('dap').step_over()
end,
desc = 'Debug: Step Over',
},
{
'<F3>',
function()
require('dap').step_out()
end,
desc = 'Debug: Step Out',
},
{
'<leader>b',
function()
require('dap').toggle_breakpoint()
end,
desc = 'Debug: Toggle Breakpoint',
},
{
'<leader>B',
function()
require('dap').set_breakpoint(vim.fn.input 'Breakpoint condition: ')
end,
desc = 'Debug: Set Breakpoint',
},
-- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception.
{
'<F7>',
function()
require('dapui').toggle()
end,
desc = 'Debug: See last session result.',
},
},
config = function()
local dap = require 'dap'
local dapui = require 'dapui'
require('mason-nvim-dap').setup {
-- Makes a best effort to setup the various debuggers with
-- reasonable debug configurations
automatic_installation = true,
-- You can provide additional configuration to the handlers,
-- see mason-nvim-dap README for more information
handlers = {},
-- You'll need to check that you have the required things installed
-- 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',
},
}
-- Dap UI setup
-- For more information, see |:help nvim-dap-ui|
dapui.setup {
-- Set icons to characters that are more likely to work in every terminal.
-- Feel free to remove or use ones that you like more! :)
-- Don't feel like these are good choices.
icons = { expanded = '', collapsed = '', current_frame = '*' },
controls = {
icons = {
pause = '',
play = '',
step_into = '',
step_over = '',
step_out = '',
step_back = 'b',
run_last = '▶▶',
terminate = '',
disconnect = '',
},
},
}
-- Change breakpoint icons
-- vim.api.nvim_set_hl(0, 'DapBreak', { fg = '#e51400' })
-- vim.api.nvim_set_hl(0, 'DapStop', { fg = '#ffcc00' })
-- local breakpoint_icons = vim.g.have_nerd_font
-- and { Breakpoint = '', BreakpointCondition = '', BreakpointRejected = '', LogPoint = '', Stopped = '' }
-- or { Breakpoint = '●', BreakpointCondition = '⊜', BreakpointRejected = '⊘', LogPoint = '◆', Stopped = '⭔' }
-- for type, icon in pairs(breakpoint_icons) do
-- local tp = 'Dap' .. type
-- local hl = (type == 'Stopped') and 'DapStop' or 'DapBreak'
-- vim.fn.sign_define(tp, { text = icon, texthl = hl, numhl = hl })
-- end
dap.listeners.after.event_initialized['dapui_config'] = dapui.open
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

@ -1,9 +0,0 @@
return {
{ -- Add indentation guides even on blank lines
'lukas-reineke/indent-blankline.nvim',
-- Enable `lukas-reineke/indent-blankline.nvim`
-- See `:help ibl`
main = 'ibl',
opts = {},
},
}

View File

@ -1,60 +0,0 @@
return {
{ -- Linting
'mfussenegger/nvim-lint',
event = { 'BufReadPre', 'BufNewFile' },
config = function()
local lint = require 'lint'
lint.linters_by_ft = {
markdown = { 'markdownlint' },
}
-- To allow other plugins to add linters to require('lint').linters_by_ft,
-- instead set linters_by_ft like this:
-- lint.linters_by_ft = lint.linters_by_ft or {}
-- lint.linters_by_ft['markdown'] = { 'markdownlint' }
--
-- However, note that this will enable a set of default linters,
-- which will cause errors unless these tools are available:
-- {
-- clojure = { "clj-kondo" },
-- dockerfile = { "hadolint" },
-- inko = { "inko" },
-- janet = { "janet" },
-- json = { "jsonlint" },
-- markdown = { "vale" },
-- rst = { "vale" },
-- ruby = { "ruby" },
-- terraform = { "tflint" },
-- text = { "vale" }
-- }
--
-- You can disable the default linters by setting their filetypes to nil:
-- lint.linters_by_ft['clojure'] = nil
-- lint.linters_by_ft['dockerfile'] = nil
-- lint.linters_by_ft['inko'] = nil
-- lint.linters_by_ft['janet'] = nil
-- lint.linters_by_ft['json'] = nil
-- lint.linters_by_ft['markdown'] = nil
-- lint.linters_by_ft['rst'] = nil
-- lint.linters_by_ft['ruby'] = nil
-- lint.linters_by_ft['terraform'] = nil
-- lint.linters_by_ft['text'] = nil
-- Create autocommand which carries out the actual linting
-- on the specified events.
local lint_augroup = vim.api.nvim_create_augroup('lint', { clear = true })
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, {
group = lint_augroup,
callback = function()
-- Only run the linter in buffers that you can modify in order to
-- avoid superfluous noise, notably within the handy LSP pop-ups that
-- describe the hovered symbol using Markdown.
if vim.bo.modifiable then
lint.try_lint()
end
end,
})
end,
},
}

View File

@ -1,25 +0,0 @@
-- Neo-tree is a Neovim plugin to browse the file system
-- https://github.com/nvim-neo-tree/neo-tree.nvim
return {
'nvim-neo-tree/neo-tree.nvim',
version = '*',
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-tree/nvim-web-devicons', -- not strictly required, but recommended
'MunifTanjim/nui.nvim',
},
lazy = false,
keys = {
{ '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
},
opts = {
filesystem = {
window = {
mappings = {
['\\'] = 'close_window',
},
},
},
},
}

26
lua/plugins/aerial.lua Normal file
View File

@ -0,0 +1,26 @@
return {
'stevearc/aerial.nvim',
lazy_load = true,
opts = {},
-- Optional dependencies
dependencies = {
'nvim-treesitter/nvim-treesitter',
'nvim-tree/nvim-web-devicons',
},
config = function()
require('aerial').setup {
-- optionally use on_attach to set keymaps when aerial has attached to a buffer
on_attach = function(bufnr)
-- Jump forwards/backwards with '{' and '}'
-- vim.keymap.set('n', '{', '<cmd>AerialPrev<CR>', { buffer = bufnr })
-- vim.keymap.set('n', '}', '<cmd>AerialNext<CR>', { buffer = bufnr })
end,
layout = {
min_width = 30,
},
}
-- You probably also want to set a keymap to toggle aerial
vim.keymap.set('n', '<leader>o', '<cmd>AerialToggle!<CR>')
vim.keymap.set('n', '<leader>on', '<cmd>AerialNavToggle<CR>')
end,
}

View File

@ -0,0 +1,143 @@
return { -- Autocompletion
'hrsh7th/nvim-cmp',
-- event = 'InsertEnter',
dependencies = {
-- Snippet Engine & its associated nvim-cmp source
{
'L3MON4D3/LuaSnip',
build = (function()
-- Build Step is needed for regex support in snippets
-- This step is not supported in many windows environments
-- Remove the below condition to re-enable on windows
if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then
return
end
return 'make install_jsregexp'
end)(),
},
'saadparwaiz1/cmp_luasnip',
-- Adds other completion capabilities.
-- nvim-cmp does not ship with all sources by default. They are split
-- into multiple repos for maintenance purposes.
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-buffer',
'hrsh7th/cmp-path',
-- Adds a number of user-friendly snippets
'rafamadriz/friendly-snippets',
},
config = function()
local cmp = require 'cmp'
require('luasnip.loaders.from_vscode').lazy_load()
local luasnip = require 'luasnip'
luasnip.config.setup {}
local kind_icons = {
Text = '󰉿',
Method = 'm',
Function = '󰊕',
Constructor = '',
Field = '',
Variable = '󰆧',
Class = '󰌗',
Interface = '',
Module = '',
Property = '',
Unit = '',
Value = '󰎠',
Enum = '',
Keyword = '󰌋',
Snippet = '',
Color = '󰏘',
File = '󰈙',
Reference = '',
Folder = '󰉋',
EnumMember = '',
Constant = '󰇽',
Struct = '',
Event = '',
Operator = '󰆕',
TypeParameter = '󰊄',
}
cmp.setup {
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
completion = { completeopt = 'menu,menuone,noinsert' },
-- window = {
-- completion = cmp.config.window.bordered(),
-- documentation = cmp.config.window.bordered(),
-- },
mapping = cmp.mapping.preset.insert {
['<C-j>'] = cmp.mapping.select_next_item(), -- Select the [n]ext item
['<C-k>'] = cmp.mapping.select_prev_item(), -- Select the [p]revious item
['<CR>'] = cmp.mapping.confirm { select = true }, -- Accept the completion with Enter.
['<C-c>'] = cmp.mapping.complete {}, -- Manually trigger a completion from nvim-cmp.
-- Think of <c-l> as moving to the right of your snippet expansion.
-- So if you have a snippet that's like:
-- function $name($args)
-- $body
-- end
--
-- <c-l> will move you to the right of each of the expansion locations.
-- <c-h> is similar, except moving you backwards.
['<C-l>'] = cmp.mapping(function()
if luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
end
end, { 'i', 's' }),
['<C-h>'] = cmp.mapping(function()
if luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
end
end, { 'i', 's' }),
-- Select next/previous item with Tab / Shift + Tab
['<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { 'i', 's' }),
['<S-Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { 'i', 's' }),
},
sources = {
{ name = 'nvim_lsp' },
{ name = 'luasnip' },
{ name = 'buffer' },
{ name = 'path' },
},
formatting = {
fields = { 'kind', 'abbr', 'menu' },
format = function(entry, vim_item)
-- Kind icons
vim_item.kind = string.format('%s', kind_icons[vim_item.kind])
-- vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind) -- This concatonates the icons with the name of the item kind
vim_item.menu = ({
nvim_lsp = '[LSP]',
luasnip = '[Snippet]',
buffer = '[Buffer]',
path = '[Path]',
})[entry.source.name]
return vim_item
end,
},
}
end,
}

View File

@ -0,0 +1,72 @@
-- lua/plugins/autoformat.lua
-- Automatically format Go code on save and when idle after changes
return {
"neovim/nvim-lspconfig",
event = { "BufReadPre", "BufNewFile" },
config = function()
---------------------------------------------------------------------------
-- 🧹 Format on save
---------------------------------------------------------------------------
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.go",
callback = function()
-- Runs both gopls and none-ls formatters in order
vim.lsp.buf.format({ async = false })
end,
})
---------------------------------------------------------------------------
-- ⚡ Auto-format when idle (after you stop typing)
---------------------------------------------------------------------------
local format_timer = vim.loop.new_timer()
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
pattern = "*.go",
callback = function()
-- Cancel previous pending format
format_timer:stop()
-- Wait 1.5 seconds after the last change before formatting
format_timer:start(1500, 0, vim.schedule_wrap(function()
-- Only format if the buffer still exists and is listed
local bufnr = vim.api.nvim_get_current_buf()
if vim.api.nvim_buf_is_valid(bufnr) and vim.bo[bufnr].modifiable then
vim.lsp.buf.format({ async = true })
end
end))
end,
})
---------------------------------------------------------------------------
-- 🧪 Optional: run `goimports` and quick test on save
---------------------------------------------------------------------------
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = "*.go",
callback = function()
-- Automatically fix imports using goimports if available
vim.fn.jobstart({ "goimports", "-w", vim.fn.expand("%:p") }, {
on_exit = function()
-- Optionally, trigger a quick test run for feedback
vim.fn.jobstart({ "go", "test", "./..." }, {
cwd = vim.fn.getcwd(),
stdout_buffered = true,
stderr_buffered = true,
on_stdout = function(_, data)
if data then
vim.notify(table.concat(data, "\n"), vim.log.levels.INFO, { title = "go test" })
end
end,
on_stderr = function(_, data)
if data then
vim.notify(table.concat(data, "\n"), vim.log.levels.ERROR, { title = "go test" })
end
end,
})
end,
})
end,
})
end,
}

28
lua/plugins/avante.lua Normal file
View File

@ -0,0 +1,28 @@
return {
'yetone/avante.nvim',
event = 'VeryLazy',
build = 'make',
opts = {
provider = 'claude',
claude = {
endpoint = os.getenv 'AVANTE_ANTHROPIC_ENDPOINT' or 'https://api.anthropic.com',
model = 'claude-3-5-sonnet-20240620',
timeout = 30000, -- Timeout in milliseconds
temperature = 0,
max_tokens = 4096,
},
openai = {
endpoint = os.getenv 'AVANTE_OPENAI_ENDPOINT' or 'https://api.openai.com/v1',
model = 'gpt-4o',
timeout = 30000, -- Timeout in milliseconds
temperature = 0,
max_tokens = 4096,
},
},
dependencies = {
'nvim-tree/nvim-web-devicons',
'stevearc/dressing.nvim',
'nvim-lua/plenary.nvim',
'MunifTanjim/nui.nvim',
},
}

View File

@ -0,0 +1,140 @@
-- TODO: don't having to resave to remove extmark
-- TODO: see the others TODO
local M = {}
local api = vim.api
local cmd = vim.api.nvim_create_autocmd
local treesitter = vim.treesitter
local opts = {
tags = {
{
name = "TODO",
fg = "white",
bg = "#0a7aca",
bold = true,
},
{
name = "FIX",
fg = "white",
bg = "#f44747",
bold = true,
},
{
name = "WARNING",
fg = "#FFA500",
bold = false,
},
{
name = "FUTURE",
fg = "#f44747",
bold = true,
}
},
}
M.Setup = function(config)
if config and config.default==false then
opts.tags = {}
end
if config and config.tags then
opts.tags = vim.tbl_deep_extend("force", opts.tags, config.tags or {})
end
local augroup = vim.api.nvim_create_augroup("better-comments", {clear = true})
cmd({ 'BufWinEnter', 'BufFilePost', 'BufWritePost', 'TextChanged', 'TextChangedI' }, {
group = augroup,
callback = function()
local current_buffer = api.nvim_get_current_buf()
local current_buffer_name = api.nvim_buf_get_name(current_buffer)
if current_buffer_name == '' then
return
end
local fileType = api.nvim_buf_get_option(current_buffer, "filetype")
local success, parsed_query = pcall(function()
return treesitter.query.parse(fileType, [[(comment) @all]])
end)
if not success then
return
end
local commentsTree = treesitter.query.parse(fileType, [[(comment) @all]])
-- FIX: Check if file has treesitter
local root = Get_root(current_buffer, fileType)
local comments = {}
for _, node in commentsTree:iter_captures(root, current_buffer, 0, -1) do
local range = { node:range() }
table.insert(comments, {
line = range[1],
col_start = range[2],
finish = range[4],
text = vim.treesitter.get_node_text(node, current_buffer)
})
end
if comments == {} then
return
end
Create_hl(opts.tags)
for id, comment in ipairs(comments) do
for hl_id, hl in ipairs(opts.tags) do
if string.find(comment.text, hl.name) then
local ns_id = vim.api.nvim_create_namespace(hl.name)
if hl.virtual_text and hl.virtual_text ~= "" then
local v_opts = {
id = id,
virt_text = { { hl.virtual_text, "" } },
virt_text_pos = 'overlay',
virt_text_win_col = comment.finish + 2,
}
-- FIX: comment.line -> 0 in col
api.nvim_buf_set_extmark(current_buffer, ns_id, comment.line, 0, v_opts)
end
-- FIX: using for ns_id ns_id instead of 0
-- so that when we clear the namespace the color also clear
vim.api.nvim_buf_add_highlight(current_buffer, ns_id, tostring(hl_id), comment.line,
comment.col_start,
comment.finish)
else
-- FIX: added else to delted extmark
-- TODO: THIS PART IS CALLED A LOT FIND A WAY TO NOT CHECK EVERY TIME
if hl.virtual_text ~= "" then
local ns_id = vim.api.nvim_create_namespace(hl.name)
-- FIX: clearing the namespace to delete the extmark and the color
api.nvim_buf_clear_namespace(current_buffer, ns_id, comment.line, comment.line+1)
end
end
end
end
end
})
end
Get_root = function(bufnr, filetype)
local parser = vim.treesitter.get_parser(bufnr, filetype, {})
local tree = parser:parse()[1]
return tree:root()
end
function Create_hl(list)
for id, hl in ipairs(list) do
vim.api.nvim_set_hl(0, tostring(id), {
fg = hl.fg,
bg = hl.bg,
bold = hl.bold,
underline = hl.underline,
})
end
end
return M

131
lua/plugins/bufferline.lua Normal file
View File

@ -0,0 +1,131 @@
return {
'akinsho/bufferline.nvim',
dependencies = {
'moll/vim-bbye',
'nvim-tree/nvim-web-devicons',
},
config = function()
-- vim.opt.linespace = 8
require('bufferline').setup {
options = {
mode = 'buffers', -- 'buffers', -- set to "tabs" to only show tabpages instead
themable = true, -- allows highlight groups to be overriden i.e. sets highlights as default
numbers = 'none', -- | "ordinal" | "buffer_id" | "both" | function({ ordinal, id, lower, raise }): string,
close_command = 'Bdelete! %d', -- can be a string | function, see "Mouse actions"
right_mouse_command = 'Bdelete! %d', -- can be a string | function, see "Mouse actions"
left_mouse_command = 'buffer %d', -- can be a string | function, see "Mouse actions"
middle_mouse_command = nil, -- can be a string | function, see "Mouse actions"
-- buffer_close_icon = '󰅖',
buffer_close_icon = '',
-- buffer_close_icon = '✕',
close_icon = '',
path_components = 1, -- Show only the file name without the directory
modified_icon = '',
left_trunc_marker = '',
right_trunc_marker = '',
max_name_length = 30,
max_prefix_length = 30, -- prefix used when a buffer is de-duplicated
tab_size = 21,
diagnostics = "nvim_lsp",
diagnostics_update_in_insert = false,
diagnostics_indicator = function(count, level, diagnostics_dict, context)
local icon = level:match("error") and "󰅚 " or "󰀪 "
return " " .. icon .. count
end,
color_icons = true,
show_buffer_icons = true,
show_buffer_close_icons = true,
show_close_icon = true,
persist_buffer_sort = true, -- whether or not custom sorted buffers should persist
separator_style = { '', '' }, -- | "thick" | "thin" | { 'any', 'any' },
enforce_regular_tabs = true,
always_show_bufferline = true,
show_tab_indicators = false,
indicator = {
-- icon = '▎', -- this should be omitted if indicator style is not 'icon'
style = 'none', -- Options: 'icon', 'underline', 'none'
},
icon_pinned = '󰐃',
minimum_padding = 1,
maximum_padding = 5,
maximum_length = 15,
sort_by = 'insert_at_end',
},
highlights = {
separator = {
fg = '#434C5E',
},
buffer_selected = {
bold = true,
italic = false,
},
-- separator_selected = {},
-- tab_selected = {},
-- background = {},
-- indicator_selected = {},
-- fill = {},
--
-- Error highlighting (pink theme)
error = {
fg = '#ff69b4', -- Hot pink
bg = '#2d2d2d',
},
error_selected = {
fg = '#ff1493', -- Deep pink for active tab
bg = '#3d3d3d',
bold = true,
},
error_visible = {
fg = '#ff69b4',
bg = '#2d2d2d',
},
-- Warning highlighting (optional)
warning = {
fg = '#ffb86c',
bg = '#2d2d2d',
},
warning_selected = {
fg = '#ff8c00',
bg = '#3d3d3d',
bold = true,
},
-- Normal tab highlighting
tab = {
fg = '#6272a4',
bg = '#282a36',
},
tab_selected = {
fg = '#f8f8f2',
bg = '#44475a',
bold = true,
},
-- Background
fill = {
bg = '#282a36',
},
},
}
-- Keymaps
local opts = { noremap = true, silent = true, desc = 'Go to Buffer' }
-- vim.keymap.set("n", "<Tab>", "<Cmd>BufferLineCycleNext<CR>", {})
-- vim.keymap.set("n", "<S-Tab>", "<Cmd>BufferLineCyclePrev<CR>", {})
-- vim.keymap.set('n', '<leader>1', "<cmd>lua require('bufferline').go_to_buffer(1)<CR>", opts)
-- vim.keymap.set('n', '<leader>2', "<cmd>lua require('bufferline').go_to_buffer(2)<CR>", opts)
-- vim.keymap.set('n', '<leader>3', "<cmd>lua require('bufferline').go_to_buffer(3)<CR>", opts)
-- vim.keymap.set('n', '<leader>4', "<cmd>lua require('bufferline').go_to_buffer(4)<CR>", opts)
-- vim.keymap.set('n', '<leader>5', "<cmd>lua require('bufferline').go_to_buffer(5)<CR>", opts)
-- vim.keymap.set('n', '<leader>6', "<cmd>lua require('bufferline').go_to_buffer(6)<CR>", opts)
-- vim.keymap.set('n', '<leader>7', "<cmd>lua require('bufferline').go_to_buffer(7)<CR>", opts)
-- vim.keymap.set('n', '<leader>8', "<cmd>lua require('bufferline').go_to_buffer(8)<CR>", opts)
-- vim.keymap.set('n', '<leader>9', "<cmd>lua require('bufferline').go_to_buffer(9)<CR>", opts)
end,
}

158
lua/plugins/chatgpt.lua Normal file
View File

@ -0,0 +1,158 @@
return {
'jackMort/ChatGPT.nvim',
event = 'VeryLazy',
config = function()
vim.api.nvim_set_hl(0, 'ChatGPTNormalFloat', { bg = 'NONE', fg = 'NONE' })
vim.api.nvim_set_hl(0, 'ChatGPTFloatBorder', { bg = 'NONE', fg = 'NONE' })
require('chatgpt').setup {
api_key_cmd = nil,
yank_register = '+',
edit_with_instructions = {
diff = false,
keymaps = {
close = '<C-c>',
accept = '<C-y>',
toggle_diff = '<C-d>',
toggle_settings = '<C-o>',
cycle_windows = '<Tab>',
use_output_as_input = '<C-i>',
},
},
chat = {
loading_text = 'Loading, please wait ...',
question_sign = '', -- 🙂
-- answer_sign = '', -- 🤖
answer_sign = '🤖',
max_line_length = 120,
sessions_window = {
border = {
style = 'rounded',
text = {
top = ' Sessions ',
},
},
win_options = {
winhighlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
},
},
},
keymaps = {
close = { '<C-c>' },
yank_last = '<C-y>',
yank_last_code = '<C-k>',
scroll_up = '<C-u>',
scroll_down = '<C-d>',
new_session = '<C-n>',
cycle_windows = '<Tab>',
cycle_modes = '<C-f>',
next_message = '<C-j>',
prev_message = '<C-k>',
select_session = '<Space>',
rename_session = 'r',
delete_session = 'd',
draft_message = '<C-d>',
edit_message = 'e',
delete_message = 'd',
toggle_settings = '<C-o>',
toggle_message_role = '<C-r>',
toggle_system_role_open = '<C-s>',
stop_generating = '<C-x>',
},
popup_layout = {
default = 'center',
center = {
width = '60%',
height = '80%',
},
right = {
width = '30%',
width_settings_open = '50%',
},
},
popup_window = {
border = {
highlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
style = 'rounded',
text = {
top = ' ChatGPT ',
},
},
win_options = {
wrap = true,
linebreak = true,
foldcolumn = '1',
winhighlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
},
buf_options = {
filetype = 'markdown',
},
},
system_window = {
border = {
highlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
style = 'rounded',
text = {
top = ' SYSTEM ',
},
},
win_options = {
wrap = true,
linebreak = true,
foldcolumn = '2',
winhighlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
},
},
popup_input = {
prompt = '',
border = {
highlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
style = 'rounded',
text = {
top_align = 'center',
top = ' Prompt ',
},
},
win_options = {
winhighlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
},
submit = '<C-Enter>',
submit_n = '<Enter>',
max_visible_lines = 20,
},
settings_window = {
border = {
style = 'rounded',
text = {
top = ' Settings ',
},
},
win_options = {
winhighlight = 'Normal:ChatGPTNormalFloat,FloatBorder:ChatGPTFloatBorder',
},
},
-- this config assumes you have OPENAI_API_KEY environment variable set
openai_params = {
model = 'gpt-4o-mini',
frequency_penalty = 0,
presence_penalty = 0,
max_tokens = 4095,
temperature = 0.2,
top_p = 0.1,
n = 1,
},
openai_edit_params = {
model = 'gpt-3.5-turbo',
frequency_penalty = 0,
presence_penalty = 0,
temperature = 0,
top_p = 1,
n = 1,
},
}
end,
dependencies = {
'MunifTanjim/nui.nvim',
'nvim-lua/plenary.nvim',
'nvim-telescope/telescope.nvim',
},
}

67
lua/plugins/comment.lua Normal file
View File

@ -0,0 +1,67 @@
return {
{
"folke/ts-comments.nvim",
opts = {
lang = {
astro = "<!-- %s -->",
axaml = "<!-- %s -->",
blueprint = "// %s",
c = "// %s",
c_sharp = "// %s",
clojure = { ";; %s", "; %s" },
cpp = "// %s",
cs_project = "<!-- %s -->",
css = "/* %s */",
cue = "// %s",
fsharp = "// %s",
fsharp_project = "<!-- %s -->",
gleam = "// %s",
glimmer = "{{! %s }}",
handlebars = "{{! %s }}",
hcl = "# %s",
html = "<!-- %s -->",
ini = "; %s",
javascript = {
"// %s", -- default commentstring when no treesitter node matches
"/* %s */",
call_expression = "// %s", -- specific commentstring for call_expression
jsx_attribute = "// %s",
jsx_element = "{/* %s */}",
jsx_fragment = "{/* %s */}",
spread_element = "// %s",
statement_block = "// %s",
},
kdl = "// %s",
lua = { "-- %s", "--- %s" }, -- langs can have multiple commentstrings
ocaml = "(* %s *)",
php = "// %s",
rego = "# %s",
rescript = "// %s",
rust = { "// %s", "/* %s */", "/// %s" },
sql = "-- %s",
svelte = "<!-- %s -->",
templ = "// %s",
terraform = "# %s",
tsx = {
"// %s", -- default commentstring when no treesitter node matches
"/* %s */",
call_expression = "// %s", -- specific commentstring for call_expression
jsx_attribute = "// %s",
jsx_element = "{/* %s */}",
jsx_fragment = "{/* %s */}",
spread_element = "// %s",
statement_block = "// %s",
},
twig = "{# %s #}",
typescript = "// %s",
vim = '" %s',
vue = "<!-- %s -->",
xaml = "<!-- %s -->",
xml = "<!-- %s -->",
},
},
event = "VeryLazy",
enabled = vim.fn.has("nvim-0.10.0") == 1,
},
}

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

@ -0,0 +1,54 @@
-- lua/plugins/conform.lua
return {
{
"stevearc/conform.nvim",
event = { "BufReadPre", "BufNewFile" },
config = function()
-- Resolve templ binary (Mason first, else PATH)
local mason_templ = vim.fn.stdpath("data") .. "/mason/bin/templ"
local templ_cmd = (vim.fn.executable(mason_templ) == 1) and mason_templ
or ((vim.fn.executable("templ") == 1) and "templ" or nil)
if not templ_cmd then
vim.notify("[conform.nvim] Could not find `templ` binary. Install via Mason or PATH.", vim.log.levels.WARN)
end
require("conform").setup({
formatters = {
templ_fmt = {
command = templ_cmd or "templ",
-- Read source from stdin, tell templ the filename for correct rules,
-- and write formatted result to stdout (no in-place writes).
args = { "fmt", "-stdin-filepath", "$FILENAME", "-stdout" },
stdin = true,
},
goimports = {
command = "goimports",
args = {},
stdin = true,
},
},
formatters_by_ft = {
templ = { "templ_fmt" }, -- ✅ only templ fmt for .templ
javascript = { "prettier" },
typescript = { "prettier" },
jsx = { "prettier" },
tsx = { "prettier" },
json = { "prettier" },
yaml = { "prettier" },
markdown = { "prettier" },
html = { "prettier" },
css = { "prettier" },
lua = { "stylua" },
go = { "goimports", "gofmt" },
},
format_on_save = function(bufnr)
if vim.bo[bufnr].filetype == "templ" then
return { timeout_ms = 2000, lsp_fallback = false } -- no LSP/Prettier fallback
end
return { timeout_ms = 1000, lsp_fallback = true }
end,
})
end,
},
}

50
lua/plugins/database.lua Normal file
View File

@ -0,0 +1,50 @@
return {
--use nvim in browser
{ 'kristijanhusak/vim-dadbod-ui' },
{ 'kristijanhusak/vim-dadbod-completion' },
-- Database
{
'tpope/vim-dadbod',
-- lazy = true,
dependencies = {
'kristijanhusak/vim-dadbod-ui',
'kristijanhusak/vim-dadbod-completion',
},
-- event = 'VeryLazy',
config = function()
vim.g.db_ui_execute_on_save = 0 --do not execute on save
vim.g.db_ui_win_position = 'left'
vim.g.db_ui_use_nerd_fonts = 1
vim.g.db_ui_icons = {
expanded = {
db = '',
buffers = '',
saved_queries = '',
schemas = '',
schema = '',
tables = '',
table = '',
},
collapsed = {
db = '',
buffers = '',
saved_queries = '',
schemas = '',
schema = '',
tables = '',
table = '',
},
saved_query = '*',
new_query = '+',
tables = '~',
buffers = '»',
add_connection = '[+]',
connection_ok = '',
connection_error = '',
}
end,
},
}
-- {'add_connection': '[+]', 'expanded': {'schemas': '▾', 'saved_queries': '▾', 'db': '▾', 'schema': '▾', 'table': '▾', 'buffers': '▾', 'tables': '▾'}, 'connection_ok': '✓', 'connection_error': '✕', 'tables': '~', '
-- collapsed': {'schemas': '▸', 'saved_queries': '▸', 'db': '▸', 'schema': '▸', 'table': '▸', 'buffers': '▸', 'tables': '▸'}, 'saved_query': '*', 'buffers': '»', 'new_query': '+'}

82
lua/plugins/debug.lua Normal file
View File

@ -0,0 +1,82 @@
return {
'mfussenegger/nvim-dap',
dependencies = {
-- Creates a beautiful debugger UI
'rcarriga/nvim-dap-ui',
'nvim-neotest/nvim-nio',
-- Installs the debug adapters for you
'williamboman/mason.nvim',
'jay-babu/mason-nvim-dap.nvim',
-- Add your own debuggers here
'leoluz/nvim-dap-go',
'mfussenegger/nvim-dap-python',
},
config = function()
local dap = require 'dap'
local dapui = require 'dapui'
require('mason-nvim-dap').setup {
-- Makes a best effort to setup the various debuggers with
-- reasonable debug configurations
automatic_setup = true,
automatic_installation = true,
-- You can provide additional configuration to the handlers,
-- see mason-nvim-dap README for more information
handlers = {},
-- You'll need to check that you have the required things installed
-- 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',
'debugpy',
},
}
-- Basic debugging keymaps, feel free to change to your liking!
vim.keymap.set('n', '<F5>', dap.continue, { desc = 'Debug: Start/Continue' })
vim.keymap.set('n', '<F1>', dap.step_into, { desc = 'Debug: Step Into' })
vim.keymap.set('n', '<F2>', dap.step_over, { desc = 'Debug: Step Over' })
vim.keymap.set('n', '<F3>', dap.step_out, { desc = 'Debug: Step Out' })
vim.keymap.set('n', '<leader>b', dap.toggle_breakpoint, { desc = 'Debug: Toggle Breakpoint' })
vim.keymap.set('n', '<leader>B', function()
dap.set_breakpoint(vim.fn.input 'Breakpoint condition: ')
end, { desc = 'Debug: Set Breakpoint' })
-- Dap UI setup
-- For more information, see |:help nvim-dap-ui|
dapui.setup {
-- Set icons to characters that are more likely to work in every terminal.
-- Feel free to remove or use ones that you like more! :)
-- Don't feel like these are good choices.
icons = { expanded = '', collapsed = '', current_frame = '*' },
controls = {
icons = {
pause = '',
play = '',
step_into = '',
step_over = '',
step_out = '',
step_back = 'b',
run_last = '▶▶',
terminate = '',
disconnect = '',
},
},
}
-- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception.
vim.keymap.set('n', '<F7>', dapui.toggle, { desc = 'Debug: See last session result.' })
dap.listeners.after.event_initialized['dapui_config'] = dapui.open
dap.listeners.before.event_terminated['dapui_config'] = dapui.close
dap.listeners.before.event_exited['dapui_config'] = dapui.close
-- Install golang specific config
require('dap-python').setup()
require('dap-go').setup()
end,
}

16
lua/plugins/flash.lua Normal file
View File

@ -0,0 +1,16 @@
return {
{
"folke/flash.nvim",
event = "VeryLazy",
---@type Flash.Config
opts = {},
-- stylua: ignore
keys = {
{ "s", mode = { "n", "x", "o" }, function() require("flash").jump() end, desc = "Flash" },
{ "S", mode = { "n", "x", "o" }, function() require("flash").treesitter() end, desc = "Flash Treesitter" },
{ "r", mode = "o", function() require("flash").remote() end, desc = "Remote Flash" },
{ "R", mode = { "o", "x" }, function() require("flash").treesitter_search() end, desc = "Treesitter Search" },
{ "<c-s>", mode = { "c" }, function() require("flash").toggle() end, desc = "Toggle Flash Search" },
},
}
}

21
lua/plugins/gitsigns.lua Normal file
View File

@ -0,0 +1,21 @@
-- Adds git related signs to the gutter, as well as utilities for managing changes
return {
'lewis6991/gitsigns.nvim',
opts = {
-- See `:help gitsigns.txt`
signs = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '' },
changedelete = { text = '~' },
},
signs_staged = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '' },
changedelete = { text = '~' },
},
},
}

43
lua/plugins/harpoon.lua Normal file
View File

@ -0,0 +1,43 @@
return {
'ThePrimeagen/harpoon',
branch = 'harpoon2',
dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
local harpoon = require 'harpoon'
harpoon:setup {}
-- Default UI
vim.keymap.set('n', '<leader>H', function()
harpoon.ui:toggle_quick_menu(harpoon:list())
end)
vim.keymap.set('n', '<leader>h', function()
harpoon:list():add()
end)
vim.keymap.set('n', '<leader>1', function()
harpoon:list():select(1)
end)
vim.keymap.set('n', '<leader>2', function()
harpoon:list():select(2)
end)
vim.keymap.set('n', '<leader>3', function()
harpoon:list():select(3)
end)
vim.keymap.set('n', '<leader>4', function()
harpoon:list():select(4)
end)
-- Toggle previous & next buffers stored within Harpoon list
vim.keymap.set('n', '<leader>p', function()
harpoon:list():prev()
end)
vim.keymap.set('n', '<leader>n', function()
harpoon:list():next()
end)
end,
}

View File

@ -0,0 +1,25 @@
return {
'lukas-reineke/indent-blankline.nvim',
main = 'ibl',
opts = {
indent = {
char = '',
},
scope = {
show_start = false,
show_end = false,
show_exact_scope = false,
},
exclude = {
filetypes = {
'help',
'startify',
'dashboard',
'packer',
'neogitstatus',
'NvimTree',
'Trouble',
},
},
},
}

29
lua/plugins/lazygit.lua Normal file
View File

@ -0,0 +1,29 @@
return {
'kdheepak/lazygit.nvim',
cmd = {
'LazyGit',
'LazyGitConfig',
'LazyGitCurrentFile',
'LazyGitFilter',
'LazyGitFilterCurrentFile',
},
-- optional for floating window border decoration
dependencies = {
'nvim-lua/plenary.nvim',
},
-- setting the keybinding for LazyGit with 'keys' is recommended in
-- order to load the plugin when the command is run for the first time
keys = {
-- Run LazyGit command and set background to transparent
{ '<leader>gg', '<cmd>LazyGit<cr><cmd>hi LazyGitFloat guibg=NONE guifg=NONE<cr><cmd>setlocal winhl=NormalFloat:LazyGitFloat<cr>', desc = 'LazyGit' },
},
config = function()
vim.g.lazygit_floating_window_winblend = 0 -- transparency of floating window (0-100)
vim.g.lazygit_floating_window_scaling_factor = 0.9 -- scaling factor for floating window
vim.g.lazygit_floating_window_border_chars = { '', '', '', '', '', '', '', '' } -- customize lazygit popup window border characters
vim.g.lazygit_floating_window_use_plenary = 0 -- use plenary.nvim to manage floating window if available
vim.g.lazygit_use_neovim_remote = 1 -- fallback to 0 if neovim-remote is not installed
vim.g.lazygit_use_custom_config_file_path = 0 -- config file path is evaluated if this value is 1
vim.g.lazygit_config_file_path = {} -- table of custom config file paths
end,
}

208
lua/plugins/lsp-keymaps.lua Normal file
View File

@ -0,0 +1,208 @@
local M = {}
M._keys = nil
---@return table
function M.get()
if M._keys then
return M._keys
end
-- Standard LSP Keybindings (No LazyVim)
M._keys = {
{ '<leader>cl', '<cmd>LspInfo<cr>', desc = 'LSP Info' },
{ 'gd', vim.lsp.buf.definition, desc = 'Go to Definition' },
{ 'gr', vim.lsp.buf.references, desc = 'References' },
{ 'gI', vim.lsp.buf.implementation, desc = 'Go to Implementation' },
{ 'gy', vim.lsp.buf.type_definition, desc = 'Go to Type Definition' },
{ 'gD', vim.lsp.buf.declaration, desc = 'Go to Declaration' },
{ 'gK', vim.lsp.buf.signature_help, desc = 'Signature Help' },
{ '<C-k>', vim.lsp.buf.signature_help, mode = 'i', desc = 'Signature Help' },
{ '<leader>ca', vim.lsp.buf.code_action, desc = 'Code Action', mode = { 'n', 'v' } },
{ '<leader>cr', vim.lsp.buf.rename, desc = 'Rename' },
{
'<leader>cR',
function()
if require 'snacks.rename' then
require('snacks.rename').rename_file()
else
print 'Snacks rename not available'
end
end,
desc = 'Rename File',
mode = { 'n' },
has = { 'workspace/didRenameFiles', 'workspace/willRenameFiles' },
},
{ '<leader>cr', vim.lsp.buf.rename, desc = 'Rename', has = 'rename' },
}
return M._keys
end
---@param buffer number
function M.on_attach(_, buffer)
for _, key in pairs(M.get()) do
vim.keymap.set(key.mode or 'n', key[1], key[2], { buffer = buffer, desc = key.desc, silent = true })
end
end
return M
-- local M = {}
--
-- ---@type LazyKeysLspSpec[]|nil
-- M._keys = nil
--
-- ---@alias LazyKeysLspSpec LazyKeysSpec|{has?:string|string[], cond?:fun():boolean}
-- ---@alias LazyKeysLsp LazyKeys|{has?:string|string[], cond?:fun():boolean}
--
-- ---@return LazyKeysLspSpec[]
-- function M.get()
-- if M._keys then
-- return M._keys
-- end
-- -- stylua: ignore
-- M._keys = {
-- { "<leader>cl", "<cmd>LspInfo<cr>", desc = "LSP Info" },
-- { "gd", vim.lsp.buf.definition, desc = "Go to Definition", has = "definition" },
-- { "gr", vim.lsp.buf.references, desc = "References", nowait = true },
-- { "gI", vim.lsp.buf.implementation, desc = "Go to Implementation" },
-- { "gy", vim.lsp.buf.type_definition, desc = "Go to Type Definition" },
-- { "gD", vim.lsp.buf.declaration, desc = "Go to Declaration" },
-- { "K", function() return vim.lsp.buf.hover() end, desc = "Hover" },
-- { "gK", function() return vim.lsp.buf.signature_help() end, desc = "Signature Help", has = "signatureHelp" },
-- { "<C-k>", function() return vim.lsp.buf.signature_help() end, mode = "i", desc = "Signature Help", has = "signatureHelp" },
-- { "<leader>ca", vim.lsp.buf.code_action, desc = "Code Action", mode = { "n", "v" }, has = "codeAction" },
-- { "<leader>cc", vim.lsp.codelens.run, desc = "Run CodeLens", mode = { "n", "v" }, has = "codeLens" },
-- { "<leader>cC", vim.lsp.codelens.refresh, desc = "Refresh & Display CodeLens", mode = { "n" }, has = "codeLens" },
-- {
-- "<leader>cR",
-- function()
-- if require("snacks.rename") then
-- require("snacks.rename").rename_file()
-- else
-- print("Snacks rename not available")
-- end
-- end,
-- desc = "Rename File",
-- mode = { "n" },
-- has = { "workspace/didRenameFiles", "workspace/willRenameFiles" }
-- },
-- { "<leader>cr", vim.lsp.buf.rename, desc = "Rename", has = "rename" },
-- {
-- "<leader>cA",
-- function()
-- if require("lazyvim.lsp.action") then
-- require("lazyvim.lsp.action").source()
-- else
-- print("LazyVim LSP action not available")
-- end
-- end,
-- desc = "Source Action",
-- has = "codeAction"
-- },
-- {
-- "]]",
-- function()
-- if require("snacks.words") then
-- require("snacks.words").jump(vim.v.count1)
-- end
-- end,
-- has = "documentHighlight",
-- desc = "Next Reference",
-- cond = function() return require("snacks.words").is_enabled() end
-- },
-- {
-- "[[",
-- function()
-- if require("snacks.words") then
-- require("snacks.words").jump(-vim.v.count1)
-- end
-- end,
-- has = "documentHighlight",
-- desc = "Previous Reference",
-- cond = function() return require("snacks.words").is_enabled() end
-- },
-- {
-- "<A-n>",
-- function()
-- if require("snacks.words") then
-- require("snacks.words").jump(vim.v.count1, true)
-- end
-- end,
-- has = "documentHighlight",
-- desc = "Next Reference",
-- cond = function() return require("snacks.words").is_enabled() end
-- },
-- {
-- "<A-p>",
-- function()
-- if require("snacks.words") then
-- require("snacks.words").jump(-vim.v.count1, true)
-- end
-- end,
-- has = "documentHighlight",
-- desc = "Previous Reference",
-- cond = function() return require("snacks.words").is_enabled() end
-- },
-- }
--
-- return M._keys
-- end
--
-- ---@param buffer number
-- ---@param method string|string[]
-- function M.has(buffer, method)
-- if type(method) == 'table' then
-- for _, m in ipairs(method) do
-- if M.has(buffer, m) then
-- return true
-- end
-- end
-- return false
-- end
-- method = method:find '/' and method or 'textDocument/' .. method
-- local clients = vim.lsp.get_active_clients { bufnr = buffer }
-- for _, client in ipairs(clients) do
-- if client.supports_method(method) then
-- return true
-- end
-- end
-- return false
-- end
--
-- ---@return LazyKeysLsp[]
-- function M.resolve(buffer)
-- local Keys = require 'lazy.core.handler.keys'
-- if not Keys.resolve then
-- return {}
-- end
-- local spec = vim.tbl_extend('force', {}, M.get())
-- local opts = require 'nvim-lspconfig'
-- local clients = vim.lsp.get_active_clients { bufnr = buffer }
-- for _, client in ipairs(clients) do
-- local maps = opts.servers and opts.servers[client.name] and opts.servers[client.name].keys or {}
-- vim.list_extend(spec, maps)
-- end
-- return Keys.resolve(spec)
-- end
--
-- function M.on_attach(_, buffer)
-- local Keys = require 'lazy.core.handler.keys'
-- local keymaps = M.resolve(buffer)
--
-- for _, keys in pairs(keymaps) do
-- local has = not keys.has or M.has(buffer, keys.has)
-- local cond = not (keys.cond == false or ((type(keys.cond) == 'function') and not keys.cond()))
--
-- if has and cond then
-- local opts = Keys.opts(keys)
-- opts.cond = nil
-- opts.has = nil
-- opts.silent = opts.silent ~= false
-- opts.buffer = buffer
-- vim.keymap.set(keys.mode or 'n', keys.lhs, keys.rhs, opts)
-- end
-- end
-- end
--
-- return M

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

@ -0,0 +1,107 @@
-- lua/plugins/lsp.lua
return {
{
"neovim/nvim-lspconfig",
config = function()
---------------------------------------------------------------------------
-- LSP client utilities
---------------------------------------------------------------------------
vim.api.nvim_create_user_command("LspClients", function()
-- new API: vim.lsp.get_clients
local clients = vim.lsp.get_clients()
local client_counts = {}
for _, client in ipairs(clients) do
client_counts[client.name] = (client_counts[client.name] or 0) + 1
end
print("=== Active LSP Clients ===")
for name, count in pairs(client_counts) do
local status = count > 1 and " ⚠️ DUPLICATE" or ""
print(string.format("%s: %d client(s)%s", name, count, status))
end
if next(client_counts) == nil then
print("No active LSP clients")
end
end, { desc = "Show active LSP clients and detect duplicates" })
vim.api.nvim_create_user_command("LspKillDuplicates", function()
-- only worry about duplicate gopls, since thats your main concern
local gopls_clients = vim.lsp.get_clients({ name = "gopls" })
if #gopls_clients <= 1 then
print("No duplicate gopls clients found")
return
end
local client_to_keep = nil
local clients_to_kill = {}
for _, client in ipairs(gopls_clients) do
local settings_count = 0
if client.config.settings and client.config.settings.gopls then
for _ in pairs(client.config.settings.gopls) do
settings_count = settings_count + 1
end
end
if settings_count > 0 and not client_to_keep then
client_to_keep = client
else
table.insert(clients_to_kill, client)
end
end
for _, client in ipairs(clients_to_kill) do
print(string.format("Killing duplicate gopls client (id: %d)", client.id))
client.stop(true)
end
if client_to_keep then
print(string.format("Kept gopls client (id: %d) with settings", client_to_keep.id))
end
end, { desc = "Kill duplicate gopls clients" })
---------------------------------------------------------------------------
-- Hover safety + keymaps
---------------------------------------------------------------------------
local function has_hover(bufnr)
local clients = vim.lsp.get_clients({ bufnr = bufnr })
for _, c in pairs(clients) do
if c.server_capabilities and c.server_capabilities.hoverProvider then
return true
end
end
return false
end
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local bufnr = args.buf
local lsp_keymaps = require("plugins.lsp-keymaps")
lsp_keymaps.on_attach(nil, bufnr)
local function buf_map(mode, lhs, rhs, desc)
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc })
end
-- K = hover (safe)
buf_map("n", "K", function()
if not has_hover(bufnr) then
return
end
local ok, saga_hover = pcall(require, "lspsaga.hover")
if ok and saga_hover and saga_hover.render_hover_doc then
pcall(function()
saga_hover:render_hover_doc()
end)
else
pcall(vim.lsp.buf.hover)
end
end, "LSP: Hover (safe)")
end,
})
end,
},
}

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

@ -0,0 +1,116 @@
-- Set lualine as statusline
return {
'nvim-lualine/lualine.nvim',
config = function()
-- Adapted from: https://github.com/nvim-lualine/lualine.nvim/blob/master/lua/lualine/themes/onedark.lua
local colors = {
blue = '#61afef',
green = '#98c379',
purple = '#c678dd',
cyan = '#56b6c2',
red1 = '#e06c75',
red2 = '#be5046',
yellow = '#e5c07b',
fg = '#abb2bf',
bg = '#282c34',
gray1 = '#828997',
gray2 = '#2c323c',
gray3 = '#3e4452',
}
local onedark_theme = {
normal = {
a = { fg = colors.bg, bg = colors.green, gui = 'bold' },
b = { fg = colors.fg, bg = colors.gray3 },
c = { fg = colors.fg, bg = colors.gray2 },
},
command = { a = { fg = colors.bg, bg = colors.yellow, gui = 'bold' } },
insert = { a = { fg = colors.bg, bg = colors.blue, gui = 'bold' } },
visual = { a = { fg = colors.bg, bg = colors.purple, gui = 'bold' } },
terminal = { a = { fg = colors.bg, bg = colors.cyan, gui = 'bold' } },
replace = { a = { fg = colors.bg, bg = colors.red1, gui = 'bold' } },
inactive = {
a = { fg = colors.gray1, bg = colors.bg, gui = 'bold' },
b = { fg = colors.gray1, bg = colors.bg },
c = { fg = colors.gray1, bg = colors.gray2 },
},
}
-- Import color theme based on environment variable NVIM_THEME
local env_var_nvim_theme = os.getenv 'NVIM_THEME' or 'nord'
-- Define a table of themes
local themes = {
onedark = onedark_theme,
nord = 'nord',
}
local mode = {
'mode',
fmt = function(str)
-- return ' ' .. str:sub(1, 1) -- displays only the first character of the mode
return '' .. str
end,
}
local filename = {
'filename',
file_status = true, -- displays file status (readonly status, modified status)
path = 1, -- 0 = just filename, 1 = relative path, 2 = absolute path
}
local hide_in_width = function()
return vim.fn.winwidth(0) > 100
end
local diagnostics = {
'diagnostics',
sources = { 'nvim_diagnostic' },
sections = { 'error', 'warn' },
symbols = { error = '', warn = '', info = '', hint = '' },
colored = false,
update_in_insert = false,
always_visible = false,
cond = hide_in_width,
}
local diff = {
'diff',
colored = false,
symbols = { added = '', modified = '', removed = '' }, -- changes diff symbols
cond = hide_in_width,
}
require('lualine').setup {
options = {
icons_enabled = true,
theme = themes[env_var_nvim_theme], -- Set theme based on environment variable
-- Some useful glyphs:
-- https://www.nerdfonts.com/cheat-sheet
--        
section_separators = { left = '', right = '' },
component_separators = { left = '', right = '' },
disabled_filetypes = { 'alpha', 'neo-tree', 'Avante' },
always_divide_middle = true,
},
sections = {
lualine_a = { mode },
lualine_b = { 'branch' },
lualine_c = { filename },
lualine_x = { diagnostics, diff, { 'encoding', cond = hide_in_width }, { 'filetype', cond = hide_in_width } },
lualine_y = { 'location' },
lualine_z = { 'progress' },
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { { 'filename', path = 1 } },
lualine_x = { { 'location', padding = 0 } },
lualine_y = {},
lualine_z = {},
},
tabline = {},
extensions = { 'fugitive' },
}
end,
}

View File

@ -0,0 +1,54 @@
-- lua/plugins/mason-lspconfig.lua
return {
-- "williamboman/mason-lspconfig.nvim",
-- dependencies = {
-- "williamboman/mason.nvim",
-- "neovim/nvim-lspconfig",
-- },
-- config = function()
-- local mason_lspconfig = require("mason-lspconfig")
-- local lspconfig = require("lspconfig")
--
-- mason_lspconfig.setup({
-- ensure_installed = {
-- "gopls",
-- "vtsls", -- use vtsls
-- "astro",
-- "templ",
-- "lua_ls",
-- "jsonls",
-- "tailwindcss",
-- },
-- automatic_installation = true,
-- })
--
-- mason_lspconfig.setup_handlers({
-- -- Default handler for most servers
-- function(server_name)
-- -- 🚫 dont start ts_ls at all
-- if server_name == "ts_ls" then
-- return
-- end
-- lspconfig[server_name].setup({})
-- end,
--
-- -- Optional: vtsls-specific config
-- ["vtsls"] = function()
-- lspconfig.vtsls.setup({
-- settings = {
-- vtsls = {
-- autoUseWorkspaceTsdk = true,
-- },
-- typescript = {
-- tsserver = {
-- maxTsServerMemory = 4096,
-- },
-- },
-- },
-- })
-- end,
-- })
-- end,
}

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

@ -0,0 +1,21 @@
-- lua/plugins/mason.lua
return {
{
"williamboman/mason.nvim",
lazy = false,
config = function()
require("mason").setup()
end,
},
{
"williamboman/mason-lspconfig.nvim",
lazy = false,
dependencies = { "williamboman/mason.nvim" },
opts = {
ensure_installed = { "gopls", "templ", "astro" },
automatic_installation = true,
automatic_setup = false, -- IMPORTANT: don't auto-setup servers
},
},
}

58
lua/plugins/misc.lua Normal file
View File

@ -0,0 +1,58 @@
-- Standalone plugins with less than 10 lines of config go here
return {
{
-- autoclose tags
'windwp/nvim-ts-autotag',
},
{
-- detect tabstop and shiftwidth automatically
'tpope/vim-sleuth',
},
{
-- Powerful Git integration for Vim
'tpope/vim-fugitive',
},
{
-- GitHub integration for vim-fugitive
'tpope/vim-rhubarb',
},
{
-- Hints keybinds
'folke/which-key.nvim',
opts = {
-- win = {
-- border = {
-- { '┌', 'FloatBorder' },
-- { '─', 'FloatBorder' },
-- { '┐', 'FloatBorder' },
-- { '│', 'FloatBorder' },
-- { '┘', 'FloatBorder' },
-- { '─', 'FloatBorder' },
-- { '└', 'FloatBorder' },
-- { '│', 'FloatBorder' },
-- },
-- },
},
},
{
-- Autoclose parentheses, brackets, quotes, etc.
'windwp/nvim-autopairs',
event = 'InsertEnter',
config = true,
opts = {},
},
{
-- Highlight todo, notes, etc in comments
'folke/todo-comments.nvim',
event = 'VimEnter',
dependencies = { 'nvim-lua/plenary.nvim' },
opts = { signs = false },
},
{
-- high-performance color highlighter
'norcalli/nvim-colorizer.lua',
config = function()
require('colorizer').setup()
end,
},
}

37
lua/plugins/neo-tree.lua Normal file
View File

@ -0,0 +1,37 @@
return {
{
'nvim-neo-tree/neo-tree.nvim',
opts = {
window = {
position = 'right', -- Ensure Neo-Tree opens on the right
},
filesystem = {
follow_current_file = true, -- Automatically reveal the current file
use_libuv_file_watcher = true, -- Auto-refresh when files change
filtered_items = {
visible = true,
show_hidden_count = true,
hide_dotfiles = false,
},
},
},
keys = {
{
'<leader>fe',
function()
vim.cmd 'Neotree toggle right' -- Open Neo-Tree on the right side
end,
desc = 'Toggle Neo-Tree (Right Side)',
},
{
'<leader>fE',
function()
vim.cmd 'Neotree focus' -- Focus on the Neo-Tree window
end,
desc = 'Focus Neo-Tree',
},
{ '<leader>e', '<leader>fe', desc = 'Toggle Neo-Tree', remap = true },
{ '<leader>E', '<leader>fE', desc = 'Focus Neo-Tree', remap = true },
},
},
}

52
lua/plugins/none-ls.lua Normal file
View File

@ -0,0 +1,52 @@
-- lua/plugins/none-ls.lua
return {
"nvimtools/none-ls.nvim",
enabled = false,
}
-- -- lua/plugins/none-ls.lua
-- return {
-- "nvimtools/none-ls.nvim",
-- event = { "BufReadPre", "BufNewFile" }, -- load early so it can attach
-- dependencies = {
-- "williamboman/mason.nvim",
-- "jay-babu/mason-null-ls.nvim",
-- "nvimtools/none-ls-extras.nvim", -- required for eslint_d now
-- },
-- config = function()
-- local null_ls = require("null-ls")
--
-- -- eslint_d now comes from none-ls-extras, NOT null_ls.builtins
-- local eslint_d = require("none-ls.diagnostics.eslint_d")
--
-- null_ls.setup({
-- sources = {
-- -- Go
-- null_ls.builtins.formatting.gofumpt,
-- null_ls.builtins.formatting.golines, -- optional
-- null_ls.builtins.diagnostics.golangci_lint, -- if installed
--
-- -- Web
-- null_ls.builtins.formatting.prettierd,
-- eslint_d,
-- },
-- })
--
-- require("mason-null-ls").setup({
-- ensure_installed = { "gofumpt", "golines", "golangci-lint", "prettierd", "eslint_d" },
-- automatic_installation = true,
-- -- leaving automatic_setup at default (false) so it doesn't double-register sources
-- })
--
-- -- (optional) format on save for Go
-- vim.api.nvim_create_autocmd("BufWritePre", {
-- pattern = "*.go",
-- callback = function()
-- vim.lsp.buf.format({ async = false })
-- end,
-- })
-- end,
-- }

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

@ -0,0 +1,32 @@
return {
{
'folke/snacks.nvim',
priority = 1000,
lazy = false,
---@type snacks.Config
opts = {
bigfile = { enabled = true },
explorer = { enabled = true },
indent = { enabled = true },
input = { enabled = true },
picker = { enabled = true },
notifier = { enabled = true },
quickfile = { enabled = true },
scope = { enabled = true },
-- scroll = { enabled = true },
statuscolumn = { enabled = true },
words = { enabled = true },
image = {
enabled = true, -- force enable even if terminal isn't fully supported
backend = "magick", -- fallback backend for images
diagnostics = true, -- keep this on so you can see setup issues
auto_preview = false, -- if you dont want inline previews on hover
view = "image", -- can be "image", "ascii", or "none"
max_height = 30, -- in rows
max_width = 50, -- in columns
use_dither = false, -- optional: enable dithered rendering
},
},
},
}

121
lua/plugins/telescope.lua Normal file
View File

@ -0,0 +1,121 @@
-- Fuzzy Finder (files, lsp, etc)
return {
'nvim-telescope/telescope.nvim',
branch = '0.1.x',
dependencies = {
'nvim-lua/plenary.nvim',
-- Fuzzy Finder Algorithm which requires local dependencies to be built.
-- Only load if `make` is available. Make sure you have the system
-- requirements installed.
{
'nvim-telescope/telescope-fzf-native.nvim',
build = 'make',
cond = function()
return vim.fn.executable 'make' == 1
end,
},
'nvim-telescope/telescope-ui-select.nvim',
-- Useful for getting pretty icons, but requires a Nerd Font.
'nvim-tree/nvim-web-devicons',
},
config = function()
local telescope = require 'telescope'
local actions = require 'telescope.actions'
local builtin = require 'telescope.builtin'
require('telescope').setup {
defaults = {
winblend = 0,
mappings = {
i = {
['<C-k>'] = actions.move_selection_previous, -- move to prev result
['<C-j>'] = actions.move_selection_next, -- move to next result
['<C-l>'] = actions.select_default, -- open file
-- Enable paste from system clipboard
['<C-r>'] = actions.paste_register,
},
n = {
['q'] = actions.close,
},
},
},
pickers = {
find_files = {
file_ignore_patterns = { 'node_modules', '.git', '.venv', 'query.sql.go', '*_templ.go' },
hidden = true,
},
buffers = {
initial_mode = 'normal',
sort_lastused = true,
-- sort_mru = true,
mappings = {
n = {
['d'] = actions.delete_buffer,
['l'] = actions.select_default,
},
},
},
},
live_grep = {
file_ignore_patterns = { 'node_modules', '.git', '.venv' },
additional_args = function(_)
return { '--hidden' }
end,
},
path_display = {
filename_first = {
reverse_directories = true,
},
},
extensions = {
['ui-select'] = {
require('telescope.themes').get_dropdown(),
},
},
git_files = {
previewer = false,
},
}
-- Enable telescope fzf native, if installed
pcall(require('telescope').load_extension, 'fzf')
pcall(require('telescope').load_extension, 'ui-select')
vim.keymap.set('n', '<leader>?', builtin.oldfiles, { desc = '[?] Find recently opened files' })
vim.keymap.set('n', '<leader>sb', builtin.buffers, { desc = '[S]earch existing [B]uffers' })
vim.keymap.set('n', '<leader>sm', builtin.marks, { desc = '[S]earch [M]arks' })
vim.keymap.set('n', '<leader>gf', builtin.git_files, { desc = 'Search [G]it [F]iles' })
vim.keymap.set('n', '<leader>gc', builtin.git_commits, { desc = 'Search [G]it [C]ommits' })
vim.keymap.set('n', '<leader>gcf', builtin.git_bcommits, { desc = 'Search [G]it [C]ommits for current [F]ile' })
vim.keymap.set('n', '<leader>gb', builtin.git_branches, { desc = 'Search [G]it [B]ranches' })
vim.keymap.set('n', '<leader>gs', builtin.git_status, { desc = 'Search [G]it [S]tatus (diff view)' })
vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = '[S]earch [F]iles' })
vim.keymap.set('n', '<leader>sh', builtin.help_tags, { desc = '[S]earch [H]elp' })
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]resume' })
vim.keymap.set('n', '<leader>s.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
vim.keymap.set('n', '<leader><leader>', require('telescope.builtin').find_files, { desc = '[ ] Search Files' })
vim.keymap.set('n', '<leader>sds', function()
builtin.lsp_document_symbols {
symbols = { 'Class', 'Function', 'Method', 'Constructor', 'Interface', 'Module', 'Property' },
}
end, { desc = '[S]each LSP document [S]ymbols' })
-- vim.keymap.set('n', '<leader><leader>', builtin.buffers, { desc = '[ ] Find existing buffers' })
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>/', function()
-- You can pass additional configuration to telescope to change theme, layout, etc.
builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
previewer = false,
})
end, { desc = '[/] Fuzzily search in current buffer' })
end,
}

View File

@ -0,0 +1,3 @@
return {
{ 'AvidDabbler/quantum.vim' },
}

View File

@ -0,0 +1,101 @@
return {
'navarasu/onedark.nvim',
commit = 'dd640f6',
priority = 1000,
config = function()
-- vim.cmd.colorscheme 'onedark'
local config = {
-- Main options --
style = 'dark', -- Default theme style. Choose between 'dark', 'darker', 'cool', 'deep', 'warm', 'warmer' and 'light'
transparent = true, -- Show/hide background
term_colors = true, -- Change terminal color as per the selected theme style
ending_tildes = false, -- Show the end-of-buffer tildes. By default they are hidden
cmp_itemkind_reverse = false, -- reverse item kind highlights in cmp menu
-- toggle theme style ---
toggle_style_key = '<leader>th', -- keybind to toggle theme style. Leave it nil to disable it, or set it to a string, for example "<leader>ts"
toggle_style_list = { 'dark', 'darker', 'cool', 'deep', 'warm', 'warmer', 'light' }, -- List of styles to toggle between
-- Change code style ---
-- Options are italic, bold, underline, none
-- You can configure multiple style with comma separated, For e.g., keywords = 'italic,bold'
code_style = {
comments = 'italic',
keywords = 'none',
functions = 'none',
strings = 'none',
variables = 'none',
},
-- Lualine options --
lualine = {
transparent = false, -- lualine center bar transparency
},
-- Custom Highlights --
colors = {
-- purple = '#56b6c2',
}, -- Override default colors
highlights = {}, -- Override highlight groups
-- Plugins Config --
diagnostics = {
darker = true, -- darker colors for diagnostic
undercurl = true, -- use undercurl instead of underline for diagnostics
background = true, -- use background color for virtual text
},
}
local onedark = require 'onedark'
onedark.setup(config)
onedark.load()
-- Make the background of diagnostics messages transparent
local set_diagnostics_bg_transparency = function()
vim.cmd [[highlight DiagnosticVirtualTextError guibg=none]]
vim.cmd [[highlight DiagnosticVirtualTextWarn guibg=none]]
vim.cmd [[highlight DiagnosticVirtualTextInfo guibg=none]]
vim.cmd [[highlight DiagnosticVirtualTextHint guibg=none]]
end
set_diagnostics_bg_transparency()
-- Toggle background transparency
local toggle_transparency = function()
config.transparent = not config.transparent
onedark.setup(config)
onedark.load()
set_diagnostics_bg_transparency()
end
vim.keymap.set('n', '<leader>bg', toggle_transparency, { noremap = true, silent = true })
end,
}
-- OneDark colors
-- black = "#181a1f",
-- bg0 = "#282c34",
-- bg1 = "#31353f",
-- bg2 = "#393f4a",
-- bg3 = "#3b3f4c",
-- bg_d = "#21252b",
-- bg_blue = "#73b8f1",
-- bg_yellow = "#ebd09c",
-- fg = "#abb2bf",
-- purple = "#c678dd",
-- green = "#98c379",
-- orange = "#d19a66",
-- blue = "#61afef",
-- yellow = "#e5c07b",
-- cyan = "#56b6c2",
-- red = "#e86671",
-- grey = "#5c6370",
-- light_grey = "#848b98",
-- dark_cyan = "#2b6f77",
-- dark_red = "#993939",
-- dark_yellow = "#93691d",
-- dark_purple = "#8a3fa0",
-- diff_add = "#31392b",
-- diff_delete = "#382b2c",
-- diff_change = "#1c3448",
-- diff_text = "#2c5372",

View File

@ -0,0 +1,10 @@
return {
{
'AvidDabbler/quantum.vim',
priority = 1000, -- Ensure it's loaded first
lazy = false, -- Load immediately
config = function()
vim.cmd 'colorscheme quantum' -- Explicitly set the colorscheme
end,
},
}

View File

@ -0,0 +1,13 @@
return {
'akinsho/toggleterm.nvim',
version = '*',
config = function()
require('toggleterm').setup {
direction = 'float', -- Opens a floating terminal
shell = vim.o.shell, -- Uses the default shell
}
-- Keymap to open terminal with Ctrl+/
vim.keymap.set('n', '<C-y>', '<Cmd>ToggleTerm direction=float<CR>', { noremap = true, silent = true })
vim.keymap.set('t', '<C-y>', '<Cmd>ToggleTerm<CR>', { noremap = true, silent = true })
end,
}

107
lua/plugins/treesitter.lua Normal file
View File

@ -0,0 +1,107 @@
return {
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
dependencies = {
'nvim-treesitter/nvim-treesitter-textobjects',
},
config = function()
require('nvim-treesitter.configs').setup {
-- Add languages to be installed here that you want installed for treesitter
ensure_installed = {
"latex", "scss", "svelte", "vue", "norg", "typst",
'lua',
'python',
'javascript',
'typescript',
'vimdoc',
'vim',
'regex',
'terraform',
'sql',
'dockerfile',
'toml',
'json',
'java',
'groovy',
'go',
'gitignore',
'graphql',
'yaml',
'make',
'cmake',
'markdown',
'markdown_inline',
'bash',
'tsx',
'css',
'html',
},
fold = { enable = true }, -- Enable folding
-- Autoinstall languages that are not installed
auto_install = true,
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = '<c-space>',
node_incremental = '<c-space>',
scope_incremental = '<c-s>',
node_decremental = '<M-space>',
},
},
textobjects = {
select = {
enable = true,
lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim
keymaps = {
-- You can use the capture groups defined in textobjects.scm
['aa'] = '@parameter.outer',
['ia'] = '@parameter.inner',
['af'] = '@function.outer',
['if'] = '@function.inner',
['ac'] = '@class.outer',
['ic'] = '@class.inner',
},
},
move = {
enable = true,
set_jumps = true, -- whether to set jumps in the jumplist
goto_next_start = {
[']m'] = '@function.outer',
[']]'] = '@class.outer',
},
goto_next_end = {
[']M'] = '@function.outer',
[']['] = '@class.outer',
},
goto_previous_start = {
['[m'] = '@function.outer',
['[['] = '@class.outer',
},
goto_previous_end = {
['[M'] = '@function.outer',
['[]'] = '@class.outer',
},
},
swap = {
enable = true,
swap_next = {
['<leader>a'] = '@parameter.inner',
},
swap_previous = {
['<leader>A'] = '@parameter.inner',
},
},
},
}
-- Register additional file extensions
vim.filetype.add { extension = { tf = 'terraform' } }
vim.filetype.add { extension = { tfvars = 'terraform' } }
vim.filetype.add { extension = { pipeline = 'groovy' } }
vim.filetype.add { extension = { multibranch = 'groovy' } }
end,
}

18
lua/plugins/tscontext.lua Normal file
View File

@ -0,0 +1,18 @@
return {
'treesitter-context',
setup{
enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
multiwindow = false, -- Enable multiwindow support.
max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
line_numbers = true,
multiline_threshold = 20, -- Maximum number of lines to show for a single context
trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline'
-- Separator between context and content. Should be a single character string, like '-'.
-- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
separator = nil,
zindex = 20, -- The Z-index of the context window
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
}
}

View File

@ -0,0 +1,6 @@
return {
{
"tpope/vim-unimpaired",
lazy = false, -- Load immediately since it provides useful mappings
}
}

View File

@ -0,0 +1,19 @@
-- Copied config from https://github.com/christoomey/vim-tmux-navigator
-- DISABLED: Using Zellij navigation instead
return {
-- 'christoomey/vim-tmux-navigator',
-- cmd = {
-- 'TmuxNavigateLeft',
-- 'TmuxNavigateDown',
-- 'TmuxNavigateUp',
-- 'TmuxNavigateRight',
-- 'TmuxNavigatePrevious',
-- },
-- keys = {
-- { '<c-h>', '<cmd><C-U>TmuxNavigateLeft<cr>' },
-- { '<c-j>', '<cmd><C-U>TmuxNavigateDown<cr>' },
-- { '<c-k>', '<cmd><C-U>TmuxNavigateUp<cr>' },
-- { '<c-l>', '<cmd><C-U>TmuxNavigateRight<cr>' },
-- { '<c-\\>', '<cmd><C-U>TmuxNavigatePrevious<cr>' },
-- },
}

12
lua/plugins/zellij.lua Normal file
View File

@ -0,0 +1,12 @@
return {
"https://git.sr.ht/~swaits/zellij-nav.nvim",
lazy = true,
event = "VeryLazy",
keys = {
{ "<c-h>", "<cmd>ZellijNavigateLeft<cr>", { silent = true, desc = "navigate left" } },
{ "<c-j>", "<cmd>ZellijNavigateDown<cr>", { silent = true, desc = "navigate down" } },
{ "<c-k>", "<cmd>ZellijNavigateUp<cr>", { silent = true, desc = "navigate up" } },
{ "<c-l>", "<cmd>ZellijNavigateRight<cr>", { silent = true, desc = "navigate right" } },
},
opts = {},
}

9
nvim-troubleshooting.md Normal file
View File

@ -0,0 +1,9 @@
# Troubleshooting Notes for Neovim Setup
- Check generate health of Neovim setup. `:checkhealth`
- Update Treesitter. `:TSUpdate`
- Check LSP installation. `:Mason`
- Fix broken icons
- Download [nerdfix](https://github.com/loichyan/nerdfix) binary and unpack in home directory.
- Run `nerdfix check <path/to/file>` to check broken icons in a file
- Run `nerdfix fix <path/to/file>` to fix broken icons in a file