clean config

This commit is contained in:
Harivansh Rathi 2026-02-20 22:34:08 -05:00
parent 1db6db7f92
commit 25aded9685
19 changed files with 468 additions and 852 deletions

View file

@ -1,32 +1,32 @@
local lsp_config = require("config.lsp") local lsp = require('config.lsp')
vim.lsp.config("*", { vim.lsp.config('*', {
capabilities = lsp_config.capabilities(), capabilities = lsp.capabilities(),
}) })
vim.api.nvim_create_autocmd("LspAttach", { vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup("UserLspConfig", {}), group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev) callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id) local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client then if client then
lsp_config.on_attach(client, ev.buf) lsp.on_attach(client, ev.buf)
end end
end, end,
}) })
for _, server in ipairs({ for _, server in ipairs({
"lua_ls", 'lua_ls',
"pyright", 'pyright',
"ts_ls", 'ts_ls',
"rust_analyzer", 'rust_analyzer',
"gopls", 'gopls',
"clangd", 'clangd',
"bashls", 'bashls',
"jsonls", 'jsonls',
"html", 'html',
"cssls", 'cssls',
}) do }) do
local ok, config = pcall(require, "lsp." .. server) local ok, config = pcall(require, 'lsp.' .. server)
if ok then if ok then
vim.lsp.config(server, config) vim.lsp.config(server, config)
end end

View file

@ -1,49 +1,59 @@
-- Set leader keys before lazy vim.g.mapleader = ' '
vim.g.mapleader = " " vim.g.maplocalleader = ','
vim.g.maplocalleader = ","
-- Global mapping helpers function _G.map(mode, lhs, rhs, opts)
_G.map = function(mode, lhs, rhs, opts) vim.keymap.set(mode, lhs, rhs, vim.tbl_extend('keep', opts or {}, { silent = true }))
opts = opts or {}
opts.silent = opts.silent ~= false
vim.keymap.set(mode, lhs, rhs, opts)
end end
_G.bmap = function(buf, mode, lhs, rhs, opts) function _G.bmap(mode, lhs, rhs, opts)
opts = opts or {} _G.map(mode, lhs, rhs, vim.tbl_extend('force', opts or {}, { buffer = 0 }))
opts.buffer = buf
opts.silent = opts.silent ~= false
vim.keymap.set(mode, lhs, rhs, opts)
end end
-- Bootstrap lazy.nvim local disabled_plugins = {
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" '2html_plugin',
'bugreport',
'getscript',
'getscriptPlugin',
'gzip',
'logipat',
'matchit',
'matchparen',
'netrw',
'netrwFileHandlers',
'netrwPlugin',
'netrwSettings',
'optwin',
'rplugin',
'rrhelper',
'synmenu',
'tar',
'tarPlugin',
'tohtml',
'tutor',
'vimball',
'vimballPlugin',
'zip',
'zipPlugin',
}
for _, plugin in ipairs(disabled_plugins) do
vim.g['loaded_' .. plugin] = 1
end
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.uv.fs_stat(lazypath) then if not vim.uv.fs_stat(lazypath) then
vim.fn.system({ vim.fn.system({
"git", 'git',
"clone", 'clone',
"--filter=blob:none", '--filter=blob:none',
"https://github.com/folke/lazy.nvim.git", '--branch=stable',
"--branch=stable", 'https://github.com/folke/lazy.nvim.git',
lazypath, lazypath,
}) })
end end
vim.opt.rtp:prepend(lazypath) vim.opt.rtp:prepend(lazypath)
-- Load plugins require('lazy').setup('plugins', {
require("lazy").setup("plugins", { defaults = { lazy = false },
defaults = { lazy = true }, change_detection = { enabled = false },
performance = {
rtp = {
disabled_plugins = {
"gzip",
"matchit",
"matchparen",
"netrwPlugin",
"tarPlugin",
"tohtml",
"zipPlugin",
},
},
},
}) })

View file

@ -1,5 +1,4 @@
{ {
"dashboard-nvim": { "branch": "master", "commit": "0775e567b6c0be96d01a61795f7b64c1758262f6" },
"diffs.nvim": { "branch": "main", "commit": "b1abfe4f4a164ad776148ca36f852df4f1e4014e" }, "diffs.nvim": { "branch": "main", "commit": "b1abfe4f4a164ad776148ca36f852df4f1e4014e" },
"flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" }, "flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
"fzf-lua": { "branch": "main", "commit": "b2c0603216adb92c6bba81053bc996d7ae95b77a" }, "fzf-lua": { "branch": "main", "commit": "b2c0603216adb92c6bba81053bc996d7ae95b77a" },

View file

@ -1,31 +1,21 @@
-- Shared LSP utilities
local M = {} local M = {}
-- Set up buffer-local keymaps when LSP attaches function M.on_attach(_, bufnr)
function M.on_attach(client, bufnr) local function buf(mode, lhs, rhs)
local opts = { buffer = bufnr, silent = true } bmap(mode, lhs, rhs, { buffer = bufnr })
end
-- Navigation buf('n', 'gd', vim.lsp.buf.definition)
vim.keymap.set("n", "gd", vim.lsp.buf.definition, vim.tbl_extend("force", opts, { desc = "Go to definition" })) buf('n', 'gD', vim.lsp.buf.declaration)
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, vim.tbl_extend("force", opts, { desc = "Go to declaration" })) buf('n', '<C-]>', vim.lsp.buf.definition)
vim.keymap.set("n", "<C-]>", vim.lsp.buf.definition, vim.tbl_extend("force", opts, { desc = "Go to definition" })) buf('n', 'gi', vim.lsp.buf.implementation)
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, vim.tbl_extend("force", opts, { desc = "Go to implementation" })) buf('n', 'gr', vim.lsp.buf.references)
vim.keymap.set("n", "gr", vim.lsp.buf.references, vim.tbl_extend("force", opts, { desc = "Go to references" })) buf('n', 'K', vim.lsp.buf.hover)
buf('n', '<leader>rn', vim.lsp.buf.rename)
-- Documentation buf({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action)
vim.keymap.set("n", "K", vim.lsp.buf.hover, vim.tbl_extend("force", opts, { desc = "Hover documentation" })) buf('n', '<leader>f', function() vim.lsp.buf.format({ async = true }) end)
-- Refactoring
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, vim.tbl_extend("force", opts, { desc = "Rename symbol" }))
vim.keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, vim.tbl_extend("force", opts, { desc = "Code action" }))
-- Formatting
vim.keymap.set("n", "<leader>f", function()
vim.lsp.buf.format({ async = true })
end, vim.tbl_extend("force", opts, { desc = "Format buffer" }))
end end
-- Return default capabilities for LSP servers
function M.capabilities() function M.capabilities()
return vim.lsp.protocol.make_client_capabilities() return vim.lsp.protocol.make_client_capabilities()
end end

View file

@ -1,139 +0,0 @@
-- Minimal custom statusline
local M = {}
-- Mode mapping
local mode_map = {
n = "NORMAL",
no = "N-PENDING",
nov = "N-PENDING",
noV = "N-PENDING",
["no\22"] = "N-PENDING",
niI = "NORMAL",
niR = "NORMAL",
niV = "NORMAL",
nt = "NORMAL",
ntT = "NORMAL",
v = "VISUAL",
vs = "VISUAL",
V = "V-LINE",
Vs = "V-LINE",
["\22"] = "V-BLOCK",
["\22s"] = "V-BLOCK",
s = "SELECT",
S = "S-LINE",
["\19"] = "S-BLOCK",
i = "INSERT",
ic = "INSERT",
ix = "INSERT",
R = "REPLACE",
Rc = "REPLACE",
Rx = "REPLACE",
Rv = "V-REPLACE",
Rvc = "V-REPLACE",
Rvx = "V-REPLACE",
c = "COMMAND",
cv = "EX",
ce = "EX",
r = "REPLACE",
rm = "MORE",
["r?"] = "CONFIRM",
["!"] = "SHELL",
t = "TERMINAL",
}
-- Get current mode indicator
local function get_mode()
local mode = vim.api.nvim_get_mode().mode
return mode_map[mode] or mode
end
-- Get git branch from gitsigns
local function get_git_branch()
local branch = vim.b.gitsigns_head
if branch and branch ~= "" then
return " " .. branch
end
return ""
end
-- Get filename with modified indicator
local function get_filename()
local filename = vim.fn.expand("%:t")
if filename == "" then
filename = "[No Name]"
end
local modified = vim.bo.modified and " [+]" or ""
local readonly = vim.bo.readonly and " [RO]" or ""
return filename .. modified .. readonly
end
-- Get file path (relative to cwd)
local function get_filepath()
local filepath = vim.fn.expand("%:~:.")
if filepath == "" then
return ""
end
return filepath
end
-- Get current position
local function get_position()
local line = vim.fn.line(".")
local col = vim.fn.col(".")
local total = vim.fn.line("$")
return string.format("%d:%d/%d", line, col, total)
end
-- Get filetype
local function get_filetype()
local ft = vim.bo.filetype
if ft == "" then
return ""
end
return ft
end
-- Build the statusline
function M.statusline()
local parts = {}
-- Left side
table.insert(parts, " " .. get_mode() .. " ")
table.insert(parts, get_git_branch())
local filepath = get_filepath()
if filepath ~= "" then
table.insert(parts, " " .. filepath)
end
-- Modified indicator
if vim.bo.modified then
table.insert(parts, " [+]")
end
-- Separator
table.insert(parts, "%=")
-- Right side
local ft = get_filetype()
if ft ~= "" then
table.insert(parts, ft .. " ")
end
table.insert(parts, get_position() .. " ")
return table.concat(parts, "")
end
-- Setup function to configure the statusline
function M.setup()
-- Use the %!v:lua.require() pattern
vim.o.statusline = "%!v:lua.require('config.statusline').statusline()"
-- Ensure statusline is always shown
vim.o.laststatus = 2
end
return M

View file

@ -1,25 +1,14 @@
-- Lua language server configuration
return { return {
settings = { settings = {
Lua = { Lua = {
diagnostics = { diagnostics = { globals = { 'vim' } },
globals = { "vim" }, runtime = { version = 'LuaJIT' },
},
runtime = {
version = "LuaJIT",
},
workspace = { workspace = {
checkThirdParty = false, checkThirdParty = false,
library = { library = { vim.env.VIMRUNTIME },
vim.env.VIMRUNTIME,
},
},
telemetry = {
enable = false,
},
hint = {
enable = true,
}, },
telemetry = { enable = false },
hint = { enable = true },
}, },
}, },
} }

View file

@ -1,12 +1,11 @@
-- Pyright (Python) language server configuration
return { return {
settings = { settings = {
python = { python = {
analysis = { analysis = {
typeCheckingMode = "basic", typeCheckingMode = 'basic',
autoSearchPaths = true, autoSearchPaths = true,
useLibraryCodeForTypes = true, useLibraryCodeForTypes = true,
diagnosticMode = "workspace", diagnosticMode = 'workspace',
}, },
}, },
}, },

View file

@ -1,25 +1,16 @@
-- Rust Analyzer configuration with clippy integration
return { return {
settings = { settings = {
["rust-analyzer"] = { ['rust-analyzer'] = {
checkOnSave = { checkOnSave = { command = 'clippy' },
command = "clippy", cargo = { allFeatures = true },
}, procMacro = { enable = true },
cargo = { diagnostics = { enable = true },
allFeatures = true,
},
procMacro = {
enable = true,
},
diagnostics = {
enable = true,
},
inlayHints = { inlayHints = {
bindingModeHints = { enable = true }, bindingModeHints = { enable = true },
chainingHints = { enable = true }, chainingHints = { enable = true },
closingBraceHints = { enable = true }, closingBraceHints = { enable = true },
closureReturnTypeHints = { enable = "always" }, closureReturnTypeHints = { enable = 'always' },
lifetimeElisionHints = { enable = "always" }, lifetimeElisionHints = { enable = 'always' },
parameterHints = { enable = true }, parameterHints = { enable = true },
typeHints = { enable = true }, typeHints = { enable = true },
}, },

View file

@ -1,9 +1,8 @@
-- TypeScript language server configuration
return { return {
settings = { settings = {
typescript = { typescript = {
inlayHints = { inlayHints = {
includeInlayParameterNameHints = "all", includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false, includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true, includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true, includeInlayVariableTypeHints = true,
@ -14,7 +13,7 @@ return {
}, },
javascript = { javascript = {
inlayHints = { inlayHints = {
includeInlayParameterNameHints = "all", includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false, includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true, includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true, includeInlayVariableTypeHints = true,

View file

@ -1,78 +1,53 @@
return { return {
-- Autopairs
{ {
"windwp/nvim-autopairs", 'windwp/nvim-autopairs',
event = "InsertEnter", config = true,
config = function() },
require("nvim-autopairs").setup({}) {
'folke/flash.nvim',
opts = {
modes = { search = { enabled = true } },
},
config = function(_, opts)
require('flash').setup(opts)
map({ 'n', 'x', 'o' }, 's', function() require('flash').jump() end)
map({ 'n', 'x', 'o' }, 'S', function() require('flash').treesitter() end)
map('o', 'r', function() require('flash').remote() end)
map({ 'o', 'x' }, 'R', function() require('flash').treesitter_search() end)
map('c', '<c-s>', function() require('flash').toggle() end)
end, end,
}, },
-- Flash.nvim for navigation
{ {
"folke/flash.nvim", 'kylechui/nvim-surround',
event = "VeryLazy", config = true,
opts = {
modes = {
search = {
enabled = true,
}, },
},
},
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" },
},
},
-- Surround
{ {
"kylechui/nvim-surround", 'kevinhwang91/nvim-ufo',
version = "*", dependencies = { 'kevinhwang91/promise-async' },
event = "VeryLazy",
opts = {},
},
-- Folds
{
"kevinhwang91/nvim-ufo",
dependencies = { "kevinhwang91/promise-async" },
event = "BufReadPost",
opts = { opts = {
provider_selector = function() provider_selector = function()
return { "treesitter", "indent" } return { 'treesitter', 'indent' }
end, end,
}, },
keys = {
{ "zR", function() require("ufo").openAllFolds() end, desc = "Open all folds" },
{ "zM", function() require("ufo").closeAllFolds() end, desc = "Close all folds" },
},
},
-- Supermaven inline suggestions (accepted with Tab)
{
"supermaven-inc/supermaven-nvim",
event = "InsertEnter",
config = function(_, opts) config = function(_, opts)
require("supermaven-nvim").setup(opts) require('ufo').setup(opts)
map('n', 'zR', require('ufo').openAllFolds)
map('n', 'zM', require('ufo').closeAllFolds)
end, end,
},
{
'supermaven-inc/supermaven-nvim',
opts = { opts = {
keymaps = { keymaps = {
accept_suggestion = "<Tab>", accept_suggestion = '<Tab>',
clear_suggestion = "<C-]>", clear_suggestion = '<C-]>',
accept_word = "<C-j>", accept_word = '<C-j>',
}, },
disable_keymaps = false,
ignore_filetypes = { gitcommit = true }, ignore_filetypes = { gitcommit = true },
color = { color = {
suggestion_color = vim.api.nvim_get_hl(0, { name = "Comment" }).fg, suggestion_color = vim.api.nvim_get_hl(0, { name = 'Comment' }).fg,
cterm = 244, cterm = 244,
}, },
log_level = "info",
disable_inline_completion = false,
}, },
}, },
} }

View file

@ -1,23 +1,23 @@
---@param kind 'issue'|'pr' ---@param kind 'issue'|'pr'
---@param state 'all'|'open'|'closed' ---@param state 'all'|'open'|'closed'
local function gh_picker(kind, state) local function gh_picker(kind, state)
if vim.fn.executable("gh") ~= 1 then if vim.fn.executable('gh') ~= 1 then
vim.notify("gh CLI not found", vim.log.levels.WARN) vim.notify('gh CLI not found', vim.log.levels.WARN)
return return
end end
local next_state = ({ all = "open", open = "closed", closed = "all" })[state] local next_state = ({ all = 'open', open = 'closed', closed = 'all' })[state]
local label = kind == "pr" and "PRs" or "Issues" local label = kind == 'pr' and 'PRs' or 'Issues'
require("fzf-lua").fzf_exec(("gh %s list --limit 100 --state %s"):format(kind, state), { require('fzf-lua').fzf_exec(('gh %s list --limit 100 --state %s'):format(kind, state), {
prompt = ("%s (%s)> "):format(label, state), prompt = ('%s (%s)> '):format(label, state),
header = ":: <c-o> to toggle all/open/closed", header = ':: <c-o> to toggle all/open/closed',
actions = { actions = {
["default"] = function(selected) ['default'] = function(selected)
local num = selected[1]:match("^#?(%d+)") local num = selected[1]:match('^#?(%d+)')
if num then if num then
vim.system({ "gh", kind, "view", num, "--web" }) vim.system({ 'gh', kind, 'view', num, '--web' })
end end
end, end,
["ctrl-o"] = function() ['ctrl-o'] = function()
gh_picker(kind, next_state) gh_picker(kind, next_state)
end, end,
}, },
@ -25,58 +25,50 @@ local function gh_picker(kind, state)
end end
return { return {
"ibhagwan/fzf-lua", 'ibhagwan/fzf-lua',
dependencies = { "nvim-tree/nvim-web-devicons" }, dependencies = { 'nvim-tree/nvim-web-devicons' },
cmd = "FzfLua", config = function(_, opts)
keys = { require('fzf-lua').setup(opts)
-- Main keybinds
{ map('n', '<C-f>', function()
"<C-f>", local fzf = require('fzf-lua')
function() local git_dir = vim.fn.system('git rev-parse --git-dir 2>/dev/null'):gsub('\n', '')
local fzf = require("fzf-lua") if vim.v.shell_error == 0 and git_dir ~= '' then
local git_dir = vim.fn.system("git rev-parse --git-dir 2>/dev/null"):gsub("\n", "")
if vim.v.shell_error == 0 and git_dir ~= "" then
fzf.git_files() fzf.git_files()
else else
fzf.files() fzf.files()
end end
end)
map('n', '<leader>ff', '<cmd>FzfLua files<cr>')
map('n', '<leader>fg', '<cmd>FzfLua live_grep<cr>')
map('n', '<leader>fb', '<cmd>FzfLua buffers<cr>')
map('n', '<leader>fh', '<cmd>FzfLua help_tags<cr>')
map('n', '<leader>fr', '<cmd>FzfLua resume<cr>')
map('n', '<leader>fo', '<cmd>FzfLua oldfiles<cr>')
map('n', '<leader>fc', '<cmd>FzfLua commands<cr>')
map('n', '<leader>fk', '<cmd>FzfLua keymaps<cr>')
map('n', '<leader>f/', '<cmd>FzfLua search_history<cr>')
map('n', '<leader>f:', '<cmd>FzfLua command_history<cr>')
map('n', '<leader>fe', '<cmd>FzfLua files cwd=~/.config<cr>')
map('n', 'gq', '<cmd>FzfLua quickfix<cr>')
map('n', 'gl', '<cmd>FzfLua loclist<cr>')
map('n', '<leader>GB', '<cmd>FzfLua git_branches<cr>')
map('n', '<leader>Gc', '<cmd>FzfLua git_commits<cr>')
map('n', '<leader>Gs', '<cmd>FzfLua git_status<cr>')
map('n', '<leader>Gp', function() gh_picker('pr', 'open') end)
map('n', '<leader>Gi', function() gh_picker('issue', 'open') end)
end, end,
desc = "Find files",
},
-- Leader keybinds
{ "<leader>ff", function() require("fzf-lua").files() end, desc = "Files" },
{ "<leader>fg", function() require("fzf-lua").live_grep() end, desc = "Live grep" },
{ "<leader>fb", function() require("fzf-lua").buffers() end, desc = "Buffers" },
{ "<leader>fh", function() require("fzf-lua").help_tags() end, desc = "Help tags" },
{ "<leader>fr", function() require("fzf-lua").resume() end, desc = "Resume last search" },
{ "<leader>fo", function() require("fzf-lua").oldfiles() end, desc = "Recent files" },
{ "<leader>fc", function() require("fzf-lua").commands() end, desc = "Commands" },
{ "<leader>fk", function() require("fzf-lua").keymaps() end, desc = "Keymaps" },
{ "<leader>f/", function() require("fzf-lua").search_history() end, desc = "Search history" },
{ "<leader>f:", function() require("fzf-lua").command_history() end, desc = "Command history" },
{ "<leader>fe", function() require("fzf-lua").files({ cwd = "~/.config" }) end, desc = "Config files" },
-- Quickfix/loclist
{ "gq", function() require("fzf-lua").quickfix() end, desc = "Quickfix" },
{ "gl", function() require("fzf-lua").loclist() end, desc = "Loclist" },
-- Git
{ "<leader>GB", function() require("fzf-lua").git_branches() end, desc = "Git branches" },
{ "<leader>Gc", function() require("fzf-lua").git_commits() end, desc = "Git commits" },
{ "<leader>Gs", function() require("fzf-lua").git_status() end, desc = "Git status" },
{ "<leader>Gp", function() gh_picker("pr", "open") end, desc = "GitHub PRs" },
{ "<leader>Gi", function() gh_picker("issue", "open") end, desc = "GitHub issues" },
},
opts = { opts = {
"default-title", 'default-title',
winopts = { winopts = {
border = "single", border = 'single',
preview = { preview = {
layout = "vertical", layout = 'vertical',
vertical = "down:50%", vertical = 'down:50%',
}, },
}, },
fzf_opts = { fzf_opts = {
["--layout"] = "reverse", ['--layout'] = 'reverse',
}, },
}, },
} }

View file

@ -1,98 +1,74 @@
local function current_file_location() local function file_loc()
local root = vim.trim(vim.fn.system("git rev-parse --show-toplevel")) local root = vim.trim(vim.fn.system('git rev-parse --show-toplevel'))
if vim.v.shell_error ~= 0 or root == "" then if vim.v.shell_error ~= 0 or root == '' then
return nil return nil
end end
local path = vim.api.nvim_buf_get_name(0) local path = vim.api.nvim_buf_get_name(0)
if path == "" then if path == '' or path:sub(1, #root + 1) ~= root .. '/' then
return nil return nil
end end
return ('%s:%d'):format(path:sub(#root + 2), vim.fn.line('.'))
local prefix = root .. "/"
if path:sub(1, #prefix) ~= prefix then
return nil
end
local rel = path:sub(#prefix + 1)
return ("%s:%d"):format(rel, vim.fn.line("."))
end end
local function gh_browse() local function gh_browse()
if vim.fn.executable("gh") ~= 1 then if vim.fn.executable('gh') ~= 1 then
vim.notify("gh CLI not found", vim.log.levels.WARN) vim.notify('gh CLI not found', vim.log.levels.WARN)
return return
end end
local loc = file_loc()
local loc = current_file_location()
if loc then if loc then
vim.system({ "gh", "browse", loc }) vim.system({ 'gh', 'browse', loc })
return else
vim.system({ 'gh', 'browse' })
end end
vim.system({ "gh", "browse" })
end end
return { return {
-- Fugitive: The gold standard for Git in Vim
{ {
"tpope/vim-fugitive", 'tpope/vim-fugitive',
cmd = { "Git", "G", "Gread", "Gwrite", "Gdiffsplit", "Gvdiffsplit", "Gblame" }, config = function()
keys = { map('n', '<leader>gg', '<cmd>Git<cr><cmd>only<cr>')
{ "<leader>gg", "<cmd>Git<cr><cmd>only<cr>", desc = "Git status (fullscreen)" }, map('n', '<leader>gc', '<cmd>Git commit<cr>')
{ "<leader>gc", "<cmd>Git commit<cr>", desc = "Git commit" }, map('n', '<leader>gp', '<cmd>Git push<cr>')
{ "<leader>gp", "<cmd>Git push<cr>", desc = "Git push" }, map('n', '<leader>gl', '<cmd>Git pull<cr>')
{ "<leader>gl", "<cmd>Git pull<cr>", desc = "Git pull" }, map('n', '<leader>gb', '<cmd>Git blame<cr>')
{ "<leader>gb", "<cmd>Git blame<cr>", desc = "Git blame" }, map('n', '<leader>gd', '<cmd>Gvdiffsplit<cr>')
{ "<leader>gd", "<cmd>Gvdiffsplit<cr>", desc = "Git diff vertical" }, map('n', '<leader>gr', '<cmd>Gread<cr>')
{ "<leader>gr", "<cmd>Gread<cr>", desc = "Git checkout file" }, map('n', '<leader>gw', '<cmd>Gwrite<cr>')
{ "<leader>gw", "<cmd>Gwrite<cr>", desc = "Git add file" }, map({ 'n', 'v' }, '<leader>go', gh_browse)
{ "<leader>go", gh_browse, desc = "Open in GitHub" }, end,
}, },
},
-- Gitsigns: Git info in the gutter
{ {
"lewis6991/gitsigns.nvim", 'lewis6991/gitsigns.nvim',
event = { "BufReadPre", "BufNewFile" },
opts = { opts = {
signs = { signs = {
add = { text = "██" }, add = { text = '██' },
change = { text = "██" }, change = { text = '██' },
delete = { text = "▄▄" }, delete = { text = '▄▄' },
topdelete = { text = "▀▀" }, topdelete = { text = '▀▀' },
changedelete = { text = "██" }, changedelete = { text = '██' },
}, },
signs_staged = { signs_staged = {
add = { text = "▓▓" }, add = { text = '▓▓' },
change = { text = "▓▓" }, change = { text = '▓▓' },
delete = { text = "▄▄" }, delete = { text = '▄▄' },
topdelete = { text = "▀▀" }, topdelete = { text = '▀▀' },
changedelete = { text = "▓▓" }, changedelete = { text = '▓▓' },
}, },
signs_staged_enable = true, signs_staged_enable = true,
signcolumn = true,
numhl = false,
linehl = false, -- disabled - let colorscheme handle
word_diff = false,
current_line_blame = false,
current_line_blame_opts = {
delay = 500,
}, },
config = function(_, opts)
require('gitsigns').setup(opts)
map('n', ']g', '<cmd>Gitsigns next_hunk<cr>')
map('n', '[g', '<cmd>Gitsigns prev_hunk<cr>')
map('n', '<leader>ghs', '<cmd>Gitsigns stage_hunk<cr>')
map('n', '<leader>ghr', '<cmd>Gitsigns reset_hunk<cr>')
map('n', '<leader>ghp', '<cmd>Gitsigns preview_hunk<cr>')
map('n', '<leader>gB', '<cmd>Gitsigns toggle_current_line_blame<cr>')
end,
}, },
keys = {
{ "]g", "<cmd>Gitsigns next_hunk<cr>", desc = "Next hunk" },
{ "[g", "<cmd>Gitsigns prev_hunk<cr>", desc = "Prev hunk" },
{ "<leader>ghs", "<cmd>Gitsigns stage_hunk<cr>", desc = "Stage hunk" },
{ "<leader>ghr", "<cmd>Gitsigns reset_hunk<cr>", desc = "Reset hunk" },
{ "<leader>ghp", "<cmd>Gitsigns preview_hunk<cr>", desc = "Preview hunk" },
{ "<leader>gB", "<cmd>Gitsigns toggle_current_line_blame<cr>", desc = "Toggle line blame" },
},
},
-- Diffs.nvim: Better diff highlighting
{ {
"barrettruth/diffs.nvim", 'barrettruth/diffs.nvim',
lazy = false,
init = function() init = function()
vim.g.diffs = { vim.g.diffs = {
fugitive = { fugitive = {
@ -104,9 +80,7 @@ return {
highlights = { highlights = {
gutter = true, gutter = true,
blend_alpha = 0.4, blend_alpha = 0.4,
intra = { intra = { enabled = true },
enabled = true,
},
}, },
} }
end, end,

View file

@ -1,3 +1,4 @@
return { return {
{ "neovim/nvim-lspconfig", lazy = false }, 'neovim/nvim-lspconfig',
lazy = false,
} }

View file

@ -1,44 +1,40 @@
return { return {
"stevearc/oil.nvim", 'stevearc/oil.nvim',
dependencies = { "nvim-tree/nvim-web-devicons", "malewicz1337/oil-git.nvim" }, dependencies = { 'nvim-tree/nvim-web-devicons', 'malewicz1337/oil-git.nvim' },
cmd = "Oil",
event = 'VeryLazy',
keys = {
{ "-", "<cmd>Oil<cr>", desc = "Open parent directory" },
{ "<leader>e", "<cmd>Oil<cr>", desc = "Open file explorer" },
},
config = function(_, opts) config = function(_, opts)
require("oil").setup(opts) require('oil').setup(opts)
require("oil-git").setup({ require('oil-git').setup({
show_ignored_files = false, show_ignored_files = false,
show_ignored_directories = false, show_ignored_directories = false,
debounce_ms = 300, debounce_ms = 300,
}) })
vim.api.nvim_create_autocmd("BufEnter", { vim.api.nvim_create_autocmd('BufEnter', {
pattern = "oil://*",
callback = function() callback = function()
local dir = require("oil").get_current_dir() if vim.bo.filetype == '' then
if dir then local path = vim.fn.expand('%:p')
vim.cmd.lcd(dir) if vim.fn.isdirectory(path) == 1 then
vim.cmd('Oil ' .. path)
end
end end
end, end,
group = vim.api.nvim_create_augroup('AOil', { clear = true }),
}) })
map('n', '-', '<cmd>Oil<cr>')
map('n', '<leader>e', '<cmd>Oil<cr>')
end, end,
opts = { opts = {
default_file_explorer = true, -- nvim . opens oil default_file_explorer = true,
columns = { "icon" }, columns = { 'icon' },
view_options = { view_options = { show_hidden = true },
show_hidden = true,
},
keymaps = { keymaps = {
["g?"] = "actions.show_help", ['g?'] = 'actions.show_help',
["<CR>"] = "actions.select", ['<CR>'] = 'actions.select',
["<C-v>"] = "actions.select_vsplit", ['<C-v>'] = 'actions.select_vsplit',
["<C-x>"] = "actions.select_split", ['<C-x>'] = 'actions.select_split',
["<C-p>"] = "actions.preview", ['<C-p>'] = 'actions.preview',
["<C-c>"] = "actions.close", ['<C-c>'] = 'actions.close',
["-"] = "actions.parent", ['-'] = 'actions.parent',
["g."] = "actions.toggle_hidden", ['g.'] = 'actions.toggle_hidden',
}, },
}, },
} }

View file

@ -1,89 +1,58 @@
return { return {
-- Treesitter for syntax highlighting and code understanding
{ {
"nvim-treesitter/nvim-treesitter", 'nvim-treesitter/nvim-treesitter',
build = ":TSUpdate", build = ':TSUpdate',
event = { "BufReadPost", "BufNewFile" }, dependencies = { 'nvim-treesitter/nvim-treesitter-textobjects' },
dependencies = {
"nvim-treesitter/nvim-treesitter-textobjects",
},
config = function() config = function()
require("nvim-treesitter.configs").setup({ require('nvim-treesitter.configs').setup({
ensure_installed = {
"lua",
"vim",
"vimdoc",
"query",
"javascript",
"typescript",
"tsx",
"python",
"html",
"css",
"json",
"yaml",
"markdown",
"markdown_inline",
"bash",
"regex",
},
auto_install = true, auto_install = true,
highlight = { highlight = { enable = true },
enable = true, indent = { enable = true },
additional_vim_regex_highlighting = false,
},
indent = {
enable = true,
},
textobjects = { textobjects = {
select = { select = {
enable = true, enable = true,
lookahead = true, lookahead = true,
keymaps = { keymaps = {
["af"] = "@function.outer", ['af'] = '@function.outer',
["if"] = "@function.inner", ['if'] = '@function.inner',
["ac"] = "@class.outer", ['ac'] = '@class.outer',
["ic"] = "@class.inner", ['ic'] = '@class.inner',
["aa"] = "@parameter.outer", ['aa'] = '@parameter.outer',
["ia"] = "@parameter.inner", ['ia'] = '@parameter.inner',
["ai"] = "@conditional.outer", ['ai'] = '@conditional.outer',
["ii"] = "@conditional.inner", ['ii'] = '@conditional.inner',
["al"] = "@loop.outer", ['al'] = '@loop.outer',
["il"] = "@loop.inner", ['il'] = '@loop.inner',
["ab"] = "@block.outer", ['ab'] = '@block.outer',
["ib"] = "@block.inner", ['ib'] = '@block.inner',
}, },
}, },
move = { move = {
enable = true, enable = true,
set_jumps = true, set_jumps = true,
goto_next_start = { goto_next_start = {
["]f"] = "@function.outer", [']f'] = '@function.outer',
["]c"] = "@class.outer", [']c'] = '@class.outer',
["]a"] = "@parameter.inner", [']a'] = '@parameter.inner',
}, },
goto_next_end = { goto_next_end = {
["]F"] = "@function.outer", [']F'] = '@function.outer',
["]C"] = "@class.outer", [']C'] = '@class.outer',
}, },
goto_previous_start = { goto_previous_start = {
["[f"] = "@function.outer", ['[f'] = '@function.outer',
["[c"] = "@class.outer", ['[c'] = '@class.outer',
["[a"] = "@parameter.inner", ['[a'] = '@parameter.inner',
}, },
goto_previous_end = { goto_previous_end = {
["[F"] = "@function.outer", ['[F'] = '@function.outer',
["[C"] = "@class.outer", ['[C'] = '@class.outer',
}, },
}, },
swap = { swap = {
enable = true, enable = true,
swap_next = { swap_next = { ['<leader>sn'] = '@parameter.inner' },
["<leader>sn"] = "@parameter.inner", swap_previous = { ['<leader>sp'] = '@parameter.inner' },
},
swap_previous = {
["<leader>sp"] = "@parameter.inner",
},
}, },
}, },
}) })

View file

@ -1,146 +1,42 @@
return { return {
-- Gruvbox colorscheme
{ {
"ellisonleao/gruvbox.nvim", 'ellisonleao/gruvbox.nvim',
lazy = false, lazy = false,
priority = 1000, priority = 1000,
config = function() config = function()
require("gruvbox").setup({ require('gruvbox').setup({
terminal_colors = true, contrast = 'hard',
undercurl = true,
underline = false,
bold = true,
italic = {
strings = false,
emphasis = false,
comments = true,
operators = false,
folds = false,
},
strikethrough = true,
invert_selection = false,
invert_signs = false,
invert_tabline = false,
invert_intend_guides = false,
inverse = true,
contrast = "hard",
palette_overrides = {},
overrides = {
MatchParen = { bold = true, underline = true, bg = "" },
},
dim_inactive = false,
transparent_mode = true, transparent_mode = true,
italic = { comments = true },
overrides = {
MatchParen = { bold = true, underline = true, bg = '' },
},
}) })
vim.cmd.colorscheme("gruvbox") vim.cmd.colorscheme('gruvbox')
end, end,
}, },
-- Lualine statusline
{ {
"nvim-lualine/lualine.nvim", 'nvim-lualine/lualine.nvim',
lazy = false, dependencies = { 'nvim-tree/nvim-web-devicons' },
dependencies = { "nvim-tree/nvim-web-devicons" }, opts = {
config = function()
require("lualine").setup({
options = { options = {
theme = "gruvbox", theme = 'gruvbox',
icons_enabled = false, icons_enabled = false,
component_separators = "", component_separators = '',
section_separators = "", section_separators = '',
}, },
sections = { sections = {
lualine_a = { "mode" }, lualine_a = { 'mode' },
lualine_b = { "branch", "diff" }, lualine_b = { 'branch', 'diff' },
lualine_c = { { "filename", path = 1 } }, lualine_c = { { 'filename', path = 1 } },
lualine_x = { "diagnostics" }, lualine_x = { 'diagnostics' },
lualine_y = { "filetype" }, lualine_y = { 'filetype' },
lualine_z = { "location" }, lualine_z = { 'location' },
}, },
})
end,
}, },
-- Dashboard
{
"nvimdev/dashboard-nvim",
event = "VimEnter",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
local header_art = {
" ██▒ █▓ ██▓ ███▄ ▄███▓",
"▓██░ █▒▓██▒▓██▒▀█▀ ██▒",
" ▓██ █▒░▒██▒▓██ ▓██░",
" ▒██ █░░░██░▒██ ▒██ ",
" ▒▀█░ ░██░▒██▒ ░██▒",
" ░ ▐░ ░▓ ░ ▒░ ░ ░",
" ░ ░░ ▒ ░░ ░ ░",
" ░░ ▒ ░░ ░ ",
" ░ ░ ░ ",
"",
}
local center_items = 6
local content_height = #header_art + 2 + (center_items * 2)
local win_height = vim.fn.winheight(0)
local padding = math.max(0, math.floor((win_height - content_height) / 2))
local header = {}
for _ = 1, padding do
table.insert(header, "")
end
for _, line in ipairs(header_art) do
table.insert(header, line)
end
table.insert(header, "")
table.insert(header, "")
require("dashboard").setup({
theme = "doom",
config = {
header = header,
center = {
{
icon = " ",
desc = "Find File ",
key = "f",
action = function() require("fzf-lua").files() end,
}, },
{ {
icon = " ", 'barrettruth/nonicons.nvim',
desc = "Recent Files ", dependencies = { 'nvim-tree/nvim-web-devicons' },
key = "r",
action = function() require("fzf-lua").oldfiles() end,
}, },
{
icon = " ",
desc = "Find Text ",
key = "g",
action = function() require("fzf-lua").live_grep() end,
},
{
icon = " ",
desc = "File Explorer ",
key = "e",
action = function() vim.cmd("Oil") end,
},
{
icon = " ",
desc = "Quit ",
key = "q",
action = function() vim.cmd("quit") end,
},
},
footer = {},
},
})
end,
},
-- Nonicons font icons for nvim-web-devicons
{
"barrettruth/nonicons.nvim",
lazy = false,
dependencies = { "nvim-tree/nvim-web-devicons" },
},
} }

View file

@ -1,38 +1,31 @@
-- Autocommands
local api = vim.api local api = vim.api
local augroup = api.nvim_create_augroup("UserAutocmds", { clear = true }) local augroup = api.nvim_create_augroup('UserAutocmds', { clear = true })
-- Highlight on yank api.nvim_create_autocmd('TextYankPost', {
api.nvim_create_autocmd("TextYankPost", {
group = augroup, group = augroup,
callback = function() callback = function()
vim.highlight.on_yank({ higroup = "Visual", timeout = 200 }) vim.highlight.on_yank({ higroup = 'Visual', timeout = 200 })
end, end,
desc = "Highlight text on yank",
}) })
-- Restore cursor position on file open api.nvim_create_autocmd('BufReadPost', {
api.nvim_create_autocmd("BufReadPost", {
group = augroup, group = augroup,
callback = function() callback = function()
local excluded = { gitcommit = true, gitrebase = true } if ({ gitcommit = true, gitrebase = true })[vim.bo.filetype] then
if excluded[vim.bo.filetype] then return end return
end
local mark = api.nvim_buf_get_mark(0, '"') local mark = api.nvim_buf_get_mark(0, '"')
local line_count = api.nvim_buf_line_count(0) if mark[1] > 0 and mark[1] <= api.nvim_buf_line_count(0) then
if mark[1] > 0 and mark[1] <= line_count then
pcall(api.nvim_win_set_cursor, 0, mark) pcall(api.nvim_win_set_cursor, 0, mark)
end end
end, end,
desc = "Restore cursor position",
}) })
-- Auto-resize splits on VimResized api.nvim_create_autocmd('VimResized', {
api.nvim_create_autocmd("VimResized", {
group = augroup, group = augroup,
callback = function() callback = function()
local current_tab = vim.fn.tabpagenr() local tab = vim.fn.tabpagenr()
vim.cmd("tabdo wincmd =") vim.cmd('tabdo wincmd =')
vim.cmd("tabnext " .. current_tab) vim.cmd('tabnext ' .. tab)
end, end,
desc = "Auto-resize splits",
}) })

View file

@ -1,29 +1,21 @@
-- Keymaps using global map() helper map('n', '<leader>w', '<cmd>w<cr>')
map('n', '<leader>q', '<cmd>q<cr>')
map('n', '<C-g>', '<cmd>Git<cr><cmd>only<cr>')
-- File operations map('n', '<Tab>', '<cmd>bnext<cr>')
map("n", "<leader>w", "<cmd>w<cr>", { desc = "Save file" }) map('n', '<S-Tab>', '<cmd>bprev<cr>')
map("n", "<leader>q", "<cmd>q<cr>", { desc = "Quit" }) map('n', '<leader>x', '<cmd>bdelete<cr>')
map("n", "<C-g>", "<cmd>Git<cr><cmd>only<cr>", { desc = "Git status (fullscreen)" }) map('n', '<leader>b', '<cmd>enew<cr>')
-- Buffer navigation map('n', '<C-h>', '<C-w>h')
map("n", "<Tab>", "<cmd>bnext<cr>", { desc = "Next buffer" }) map('n', '<C-j>', '<C-w>j')
map("n", "<S-Tab>", "<cmd>bprev<cr>", { desc = "Previous buffer" }) map('n', '<C-k>', '<C-w>k')
map("n", "<leader>x", "<cmd>bdelete<cr>", { desc = "Close buffer" }) map('n', '<C-l>', '<C-w>l')
map("n", "<leader>b", "<cmd>enew<cr>", { desc = "New buffer" })
-- Window navigation map('n', 'J', 'mzJ`z')
map("n", "<C-h>", "<C-w>h", { desc = "Move to left window" }) map('x', 'x', '"_x')
map("n", "<C-j>", "<C-w>j", { desc = "Move to lower window" }) map('x', 'p', '"_dP')
map("n", "<C-k>", "<C-w>k", { desc = "Move to upper window" }) map('n', '<Esc>', '<cmd>nohlsearch<cr>')
map("n", "<C-l>", "<C-w>l", { desc = "Move to right window" }) map('n', '<leader>t', '<cmd>setlocal wrap!<cr>')
-- Better defaults map('t', '<Esc>', '<C-\\><C-n>')
map("n", "J", "mzJ`z", { desc = "Join lines keeping cursor position" })
map("x", "x", '"_x', { desc = "Delete char without yanking" })
map("x", "p", '"_dP', { desc = "Paste without yanking replaced text" })
map("n", "<Esc>", "<cmd>nohlsearch<cr>", { desc = "Clear search highlight" })
map("n", "<leader>t", "<cmd>setlocal wrap!<cr>", { desc = "Toggle word wrap" })
-- Terminal
map("t", "<Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })

View file

@ -1,52 +1,42 @@
-- Vim options
local o, opt = vim.o, vim.opt local o, opt = vim.o, vim.opt
-- Line numbers
o.number = true o.number = true
o.relativenumber = true o.relativenumber = true
-- Indentation
o.tabstop = 2 o.tabstop = 2
o.shiftwidth = 2 o.shiftwidth = 2
o.expandtab = true o.expandtab = true
o.smartindent = true o.smartindent = true
o.breakindent = true o.breakindent = true
-- Search
o.ignorecase = true o.ignorecase = true
o.smartcase = true o.smartcase = true
o.hlsearch = false o.hlsearch = false
o.incsearch = true o.incsearch = true
-- UI
o.termguicolors = true o.termguicolors = true
o.cursorline = false
o.scrolloff = 8 o.scrolloff = 8
o.signcolumn = "yes:2" o.signcolumn = 'yes'
o.wrap = false o.wrap = false
o.showmode = false o.showmode = false
o.laststatus = 3 o.laststatus = 3
o.cmdheight = 0 o.cmdheight = 0
opt.fillchars = { vert = "", fold = "", foldsep = "", diff = "" } opt.fillchars = { vert = '|', fold = '-', foldsep = '|', diff = '-' }
opt.shortmess:append("S") opt.shortmess:append('S')
-- Splits
o.splitbelow = true o.splitbelow = true
o.splitright = true o.splitright = true
-- Files
o.swapfile = false o.swapfile = false
o.backup = false o.backup = false
o.undofile = true o.undofile = true
o.undodir = vim.fn.stdpath("data") .. "/undo" o.undodir = vim.fn.stdpath('data') .. '/undo'
-- Folds (nvim-ufo)
o.foldlevel = 99 o.foldlevel = 99
o.foldlevelstart = 99 o.foldlevelstart = 99
o.foldenable = true o.foldenable = true
-- Misc
o.updatetime = 250 o.updatetime = 250
o.mouse = "a" o.mouse = 'a'
o.clipboard = "unnamedplus" o.clipboard = 'unnamedplus'