nvim-config

This commit is contained in:
amninder-narota 2025-11-29 19:55:52 -05:00
parent 3338d39206
commit ad5d34530f
14 changed files with 563 additions and 33 deletions

104
Makefile Normal file
View File

@ -0,0 +1,104 @@
.PHONY: install update clean backup install-fonts install-brew link help
NVIM_DIR := $(HOME)/.config/nvim
BACKUP_DIR := $(HOME)/.config/nvim-backup-$(shell date +%Y%m%d-%H%M%S)
# Detect OS
UNAME_S := $(shell uname -s)
# Default Nerd Fonts to install (can be overridden)
NERD_FONTS ?= font-jetbrains-mono-nerd-font font-fira-code-nerd-font font-hack-nerd-font font-meslo-lg-nerd-font
help:
@echo "Neovim Configuration Management"
@echo "================================"
@echo "install - Install/sync all plugins via lazy.nvim"
@echo "update - Update all plugins to latest versions"
@echo "clean - Clean plugin cache and unused plugins"
@echo "backup - Backup current configuration"
@echo "link - Create symlink from current directory to ~/.config/nvim"
@echo "install-fonts - Install Nerd Fonts (macOS: via brew)"
@echo "install-brew - Install Homebrew (macOS only)"
@echo ""
@echo "Environment Variables:"
@echo " NERD_FONTS - Space-separated list of fonts to install"
@echo " Default: JetBrains Mono, Fira Code, Hack, Meslo LG"
install:
@echo "Installing/syncing Neovim plugins..."
nvim --headless "+Lazy! sync" +qa
@echo "✓ Plugins installed successfully"
update:
@echo "Updating Neovim plugins..."
nvim --headless "+Lazy! update" +qa
@echo "✓ Plugins updated successfully"
clean:
@echo "Cleaning plugin cache..."
nvim --headless "+Lazy! clean" +qa
@echo "✓ Cache cleaned successfully"
backup:
@echo "Backing up configuration to $(BACKUP_DIR)..."
@cp -r $(NVIM_DIR) $(BACKUP_DIR)
@echo "✓ Backup created at $(BACKUP_DIR)"
link:
@echo "Creating symlink to ~/.config/nvim..."
@if [ -e $(NVIM_DIR) ] || [ -L $(NVIM_DIR) ]; then \
if [ -L $(NVIM_DIR) ]; then \
current_target=$$(readlink $(NVIM_DIR)); \
if [ "$$current_target" = "$(CURDIR)" ]; then \
echo "✓ Symlink already points to $(CURDIR)"; \
exit 0; \
fi; \
fi; \
echo "$(NVIM_DIR) already exists"; \
backup_dir=$(HOME)/.config/nvim-backup-$$(date +%Y%m%d-%H%M%S); \
echo "Creating backup at $$backup_dir..."; \
mv $(NVIM_DIR) $$backup_dir; \
echo "✓ Backup created at $$backup_dir"; \
fi
@mkdir -p $(HOME)/.config
@ln -s $(CURDIR) $(NVIM_DIR)
@echo "✓ Symlink created: $(NVIM_DIR) -> $(CURDIR)"
install-brew:
ifeq ($(UNAME_S),Darwin)
@if ! command -v brew >/dev/null 2>&1; then \
echo "Installing Homebrew..."; \
/bin/bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; \
echo "✓ Homebrew installed successfully"; \
else \
echo "✓ Homebrew already installed"; \
fi
else
@echo "⚠ Homebrew installation is only supported on macOS"
endif
install-fonts: install-brew
ifeq ($(UNAME_S),Darwin)
@echo "Installing Nerd Fonts on macOS..."
@for font in $(NERD_FONTS); do \
echo "Installing $$font..."; \
brew install --cask $$font || echo "⚠ Failed to install $$font"; \
done
@echo "✓ Nerd Fonts installation complete"
else ifeq ($(UNAME_S),Linux)
@echo "Installing Nerd Fonts on Linux..."
@mkdir -p $(HOME)/.local/share/fonts
@for font in $(NERD_FONTS); do \
font_name=$$(echo $$font | sed 's/font-//;s/-nerd-font//;s/-/ /g'); \
echo "Downloading $$font_name..."; \
curl -fLo "$(HOME)/.local/share/fonts/$$font.zip" \
"https://github.com/ryanoasis/nerd-fonts/releases/latest/download/$$font_name.zip" || \
echo "⚠ Failed to download $$font"; \
unzip -o "$(HOME)/.local/share/fonts/$$font.zip" -d "$(HOME)/.local/share/fonts/" 2>/dev/null || true; \
rm -f "$(HOME)/.local/share/fonts/$$font.zip"; \
done
@fc-cache -fv
@echo "✓ Nerd Fonts installation complete"
else
@echo "⚠ Unsupported OS: $(UNAME_S)"
endif

127
init.lua
View File

@ -698,6 +698,59 @@ require('lazy').setup({
}, },
}, },
}, },
-- TypeScript
ts_ls = {
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
},
-- Python
pyright = {
settings = {
python = {
analysis = {
autoSearchPaths = true,
diagnosticMode = 'workspace',
useLibraryCodeForTypes = true,
typeCheckingMode = 'basic',
},
},
},
},
-- Terraform
terraformls = {
settings = {
terraform = {
experimentalFeatures = {
validateOnSave = true,
},
},
},
},
} }
-- Ensure the servers and tools above are installed -- Ensure the servers and tools above are installed
@ -716,6 +769,9 @@ require('lazy').setup({
local ensure_installed = vim.tbl_keys(servers or {}) local ensure_installed = vim.tbl_keys(servers or {})
vim.list_extend(ensure_installed, { vim.list_extend(ensure_installed, {
'stylua', -- Used to format Lua code 'stylua', -- Used to format Lua code
'prettier', -- Formatter for TypeScript/JavaScript
'black', -- Formatter for Python
'isort', -- Python import sorting
}) })
require('mason-tool-installer').setup { ensure_installed = ensure_installed } require('mason-tool-installer').setup { ensure_installed = ensure_installed }
@ -876,27 +932,28 @@ require('lazy').setup({
}, },
}, },
{ -- You can easily change to a different colorscheme. -- { -- You can easily change to a different colorscheme.
-- Change the name of the colorscheme plugin below, and then -- -- Change the name of the colorscheme plugin below, and then
-- change the command in the config to whatever the name of that colorscheme is. -- -- change the command in the config to whatever the name of that colorscheme is.
-- -- --
-- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`. -- -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`.
'folke/tokyonight.nvim', -- 'folke/tokyonight.nvim',
priority = 1000, -- Make sure to load this before all the other start plugins. -- priority = 1000, -- Make sure to load this before all the other start plugins.
config = function() -- config = function()
---@diagnostic disable-next-line: missing-fields -- ---@diagnostic disable-next-line: missing-fields
require('tokyonight').setup { -- require('tokyonight').setup {
styles = { -- styles = {
comments = { italic = false }, -- Disable italics in comments -- comments = { italic = false }, -- Disable italics in comments
}, -- },
} -- }
--
-- Load the colorscheme here. -- -- Load the colorscheme here.
-- Like many other themes, this one has different styles, and you could load -- -- Like many other themes, this one has different styles, and you could load
-- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'. -- -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.
vim.cmd.colorscheme 'tokyonight-night' -- vim.cmd.colorscheme 'tokyonight-night'
end, -- end,
}, -- },
-- NOTE: TokyoNight is disabled in favor of Gruvbox (configured in lua/custom/plugins/gruvbox.lua)
-- Highlight todo, notes, etc in comments -- Highlight todo, notes, etc in comments
{ 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } }, { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } },
@ -922,17 +979,18 @@ require('lazy').setup({
-- Simple and easy statusline. -- Simple and easy statusline.
-- You could remove this setup call if you don't like it, -- You could remove this setup call if you don't like it,
-- and try some other statusline plugin -- and try some other statusline plugin
local statusline = require 'mini.statusline' -- NOTE: mini.statusline is disabled in favor of lualine (configured in lua/custom/plugins/lualine.lua)
-- set use_icons to true if you have a Nerd Font -- local statusline = require 'mini.statusline'
statusline.setup { use_icons = vim.g.have_nerd_font } -- -- set use_icons to true if you have a Nerd Font
-- statusline.setup { use_icons = vim.g.have_nerd_font }
-- You can configure sections in the statusline by overriding their --
-- default behavior. For example, here we set the section for -- -- You can configure sections in the statusline by overriding their
-- cursor location to LINE:COLUMN -- -- default behavior. For example, here we set the section for
---@diagnostic disable-next-line: duplicate-set-field -- -- cursor location to LINE:COLUMN
statusline.section_location = function() -- ---@diagnostic disable-next-line: duplicate-set-field
return '%2l:%-2v' -- statusline.section_location = function()
end -- return '%2l:%-2v'
-- end
-- ... and there is more! -- ... and there is more!
-- Check out: https://github.com/echasnovski/mini.nvim -- Check out: https://github.com/echasnovski/mini.nvim
@ -984,7 +1042,7 @@ require('lazy').setup({
-- This is the easiest way to modularize your config. -- This is the easiest way to modularize your config.
-- --
-- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going.
-- { import = 'custom.plugins' }, { import = 'custom.plugins' },
-- --
-- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec` -- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec`
-- Or use telescope! -- Or use telescope!
@ -1012,5 +1070,8 @@ require('lazy').setup({
}, },
}) })
-- Load custom keymaps
require('custom.keymaps')
-- The line beneath this is called `modeline`. See `:help modeline` -- The line beneath this is called `modeline`. See `:help modeline`
-- vim: ts=2 sts=2 sw=2 et -- vim: ts=2 sts=2 sw=2 et

View File

@ -0,0 +1,16 @@
-- File navigation and Telescope-related keybindings
-- File explorer
vim.keymap.set('n', '<leader>e', ':NvimTreeToggle<CR>', { desc = 'Toggle file explorer' })
vim.keymap.set('n', '<leader>fb', ':Telescope file_browser<CR>', { desc = 'Telescope file browser' })
-- Telescope pickers (additional to Kickstart defaults)
-- Note: These require telescope to be loaded, so we'll use pcall for safety
local ok, telescope_builtin = pcall(require, 'telescope.builtin')
if ok then
vim.keymap.set('n', '<leader>ff', telescope_builtin.find_files, { desc = 'Find files' })
vim.keymap.set('n', '<leader>fg', telescope_builtin.live_grep, { desc = 'Live grep' })
vim.keymap.set('n', '<leader>fh', telescope_builtin.help_tags, { desc = 'Search help' })
vim.keymap.set('n', '<leader>fr', telescope_builtin.oldfiles, { desc = 'Recent files' })
vim.keymap.set('n', '<leader>fc', telescope_builtin.current_buffer_fuzzy_find, { desc = 'Search in current buffer' })
end

View File

@ -0,0 +1,34 @@
-- General keymaps for navigation, editing, and window management
-- Exit insert mode with jj
vim.keymap.set('i', 'jj', '<Esc>', { desc = 'Exit insert mode' })
-- Split management
vim.keymap.set('n', 'sj', '<C-W>w', { desc = 'Move to next window' })
vim.keymap.set('n', 'sk', '<C-W>W', { desc = 'Move to previous window' })
vim.keymap.set('n', 'su', ':resize +5<CR>', { desc = 'Increase window height' })
vim.keymap.set('n', 'si', ':resize -5<CR>', { desc = 'Decrease window height' })
vim.keymap.set('n', 'sh', ':vertical resize +5<CR>', { desc = 'Increase window width' })
vim.keymap.set('n', 'sl', ':vertical resize -5<CR>', { desc = 'Decrease window width' })
vim.keymap.set('n', 'sd', ':hide<CR>', { desc = 'Hide current window' })
vim.keymap.set('n', 'so', ':', { desc = 'Open command mode' })
vim.keymap.set('n', 'ss', ':split ', { desc = 'Horizontal split' })
vim.keymap.set('n', 'sv', ':vsplit ', { desc = 'Vertical split' })
-- Tab management
vim.keymap.set('n', 'th', ':tabfirst<CR>', { desc = 'Go to first tab' })
vim.keymap.set('n', 'tj', ':tabnext<CR>', { desc = 'Go to next tab' })
vim.keymap.set('n', 'tk', ':tabprev<CR>', { desc = 'Go to previous tab' })
vim.keymap.set('n', 'tl', ':tablast<CR>', { desc = 'Go to last tab' })
vim.keymap.set('n', 'tt', ':tabedit ', { desc = 'Create new tab' })
vim.keymap.set('n', 'tn', ':tabnext<CR>', { desc = 'Go to next tab' })
vim.keymap.set('n', 'tm', ':tabm ', { desc = 'Move tab' })
vim.keymap.set('n', 'td', ':tabclose<CR>', { desc = 'Close tab' })
-- Buffer management
vim.keymap.set('n', '<C-k>', ':bnext<CR>', { desc = 'Next buffer' })
vim.keymap.set('n', '<C-j>', ':bprev<CR>', { desc = 'Previous buffer' })
vim.keymap.set('n', '<leader>bd', ':bdelete<CR>', { desc = 'Close current buffer' })
-- Python debugging
vim.keymap.set('n', '<leader>p', 'oimport ipdb; ipdb.set_trace()<Esc>', { desc = 'Insert Python debugger breakpoint' })

View File

@ -0,0 +1,6 @@
-- Git-related keymaps
-- LazyGit
vim.keymap.set('n', '<leader>gg', ':LazyGit<CR>', { desc = 'Open LazyGit' })
vim.keymap.set('n', '<leader>gc', ':LazyGitCurrentFile<CR>', { desc = 'LazyGit current file' })
vim.keymap.set('n', '<leader>gf', ':LazyGitFilter<CR>', { desc = 'LazyGit filter' })

View File

@ -0,0 +1,5 @@
-- Central loader for all keymap modules
require('custom.keymaps.general')
require('custom.keymaps.files')
require('custom.keymaps.git')
require('custom.keymaps.terminal')

View File

@ -0,0 +1,12 @@
-- Terminal and code execution keymaps
-- ToggleTerm keybindings
-- Note: <c-\> is already mapped in toggleterm config for opening terminal
vim.keymap.set('n', '<leader>tt', ':ToggleTerm<CR>', { desc = 'Toggle terminal' })
vim.keymap.set('n', '<leader>tf', ':ToggleTerm direction=float<CR>', { desc = 'Toggle floating terminal' })
vim.keymap.set('n', '<leader>th', ':ToggleTerm direction=horizontal<CR>', { desc = 'Toggle horizontal terminal' })
vim.keymap.set('n', '<leader>tv', ':ToggleTerm direction=vertical<CR>', { desc = 'Toggle vertical terminal' })
-- Terminal mode mappings to escape easily
vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
vim.keymap.set('t', 'jj', '<C-\\><C-n>', { desc = 'Exit terminal mode with jj' })

View File

@ -0,0 +1,63 @@
return {
'akinsho/bufferline.nvim',
version = '*',
dependencies = {
'nvim-tree/nvim-web-devicons',
},
config = function()
require('bufferline').setup {
options = {
mode = 'buffers', -- set to "tabs" to only show tabpages instead
themable = true,
numbers = 'none', -- "none" | "ordinal" | "buffer_id" | "both"
close_command = 'bdelete! %d',
right_mouse_command = 'bdelete! %d',
left_mouse_command = 'buffer %d',
middle_mouse_command = nil,
indicator = {
icon = '',
style = 'icon', -- 'icon' | 'underline' | 'none'
},
buffer_close_icon = '󰅖',
modified_icon = '',
close_icon = '',
left_trunc_marker = '',
right_trunc_marker = '',
max_name_length = 18,
max_prefix_length = 15,
truncate_names = true,
tab_size = 18,
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,
offsets = {
{
filetype = 'NvimTree',
text = 'File Explorer',
text_align = 'center',
separator = true,
},
},
color_icons = true,
show_buffer_icons = true,
show_buffer_close_icons = true,
show_close_icon = true,
show_tab_indicators = true,
show_duplicate_prefix = true,
persist_buffer_sort = true,
separator_style = 'thin', -- "slant" | "slope" | "thick" | "thin" | { 'any', 'any' }
enforce_regular_tabs = false,
always_show_bufferline = true,
hover = {
enabled = true,
delay = 200,
reveal = { 'close' },
},
sort_by = 'insert_after_current',
},
}
end,
}

View File

@ -0,0 +1,23 @@
return {
'ellisonleao/gruvbox.nvim',
priority = 1000,
config = function()
require('gruvbox').setup {
contrast = 'medium',
palette_overrides = {},
overrides = {},
dim_inactive = false,
transparent_mode = false,
italic = {
strings = false,
emphasis = false,
comments = false,
operators = false,
folds = false,
},
bold = true,
}
vim.o.background = 'dark'
vim.cmd.colorscheme 'gruvbox'
end,
}

View File

@ -0,0 +1,16 @@
return {
'kdheepak/lazygit.nvim',
dependencies = {
'nvim-lua/plenary.nvim',
},
cmd = {
'LazyGit',
'LazyGitConfig',
'LazyGitCurrentFile',
'LazyGitFilter',
'LazyGitFilterCurrentFile',
},
keys = {
{ '<leader>gg', '<cmd>LazyGit<cr>', desc = 'LazyGit' },
},
}

View File

@ -0,0 +1,97 @@
return {
'nvim-lualine/lualine.nvim',
dependencies = {
'nvim-tree/nvim-web-devicons',
},
config = function()
require('lualine').setup {
options = {
icons_enabled = true,
theme = 'gruvbox', -- Matches global Gruvbox theme
component_separators = { left = '', right = '' },
section_separators = { left = '', right = '' },
disabled_filetypes = {
statusline = { 'NvimTree' },
winbar = {},
},
ignore_focus = {},
always_divide_middle = true,
globalstatus = true,
refresh = {
statusline = 1000,
tabline = 1000,
winbar = 1000,
},
},
sections = {
-- Section A: Mode (like airline)
lualine_a = { 'mode' },
-- Section B: Git branch and diff (like airline's VCS info)
lualine_b = {
'branch',
'diff',
},
-- Section C: Filename with readonly/modified status (like airline)
lualine_c = {
{
'filename',
file_status = true, -- displays file status (readonly, modified)
path = 1, -- 0: filename, 1: relative path, 2: absolute path
shorting_target = 40,
symbols = {
modified = '[+]',
readonly = '[-]',
unnamed = '[No Name]',
},
},
'diagnostics', -- LSP diagnostics
},
-- Section X: Filetype (like airline)
lualine_x = {
{
'filetype',
colored = true,
icon_only = false,
},
},
-- Section Y: File encoding and format (like airline: utf-8[unix])
lualine_y = {
{
'encoding',
fmt = string.upper,
},
{
'fileformat',
symbols = {
unix = 'LF',
dos = 'CRLF',
mac = 'CR',
},
},
},
-- Section Z: Position (like airline: 10% ☰ 10/100 ln : 20)
lualine_z = {
'progress',
'location',
},
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { 'filename' },
lualine_x = { 'location' },
lualine_y = {},
lualine_z = {},
},
tabline = {},
winbar = {},
inactive_winbar = {},
extensions = { 'nvim-tree', 'lazy', 'mason', 'toggleterm' },
}
end,
}

View File

@ -0,0 +1,20 @@
return {
'nvim-tree/nvim-tree.lua',
dependencies = {
'nvim-tree/nvim-web-devicons',
},
config = function()
require('nvim-tree').setup {
sort_by = 'case_sensitive',
view = {
width = 30,
},
renderer = {
group_empty = true,
},
filters = {
dotfiles = false,
},
}
end,
}

View File

@ -0,0 +1,50 @@
return {
'nvim-telescope/telescope.nvim',
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-telescope/telescope-fzf-native.nvim',
'nvim-telescope/telescope-ui-select.nvim',
'nvim-telescope/telescope-file-browser.nvim',
},
config = function()
local telescope = require('telescope')
local actions = require('telescope.actions')
telescope.setup {
defaults = {
prompt_prefix = '🔍 ',
selection_caret = '',
path_display = { 'truncate' },
mappings = {
i = {
['<C-k>'] = actions.move_selection_previous,
['<C-j>'] = actions.move_selection_next,
['<C-q>'] = actions.send_selected_to_qflist + actions.open_qflist,
},
},
},
pickers = {
find_files = {
theme = 'dropdown',
previewer = false,
},
buffers = {
theme = 'dropdown',
previewer = false,
initial_mode = 'normal',
},
},
extensions = {
file_browser = {
theme = 'ivy',
hijack_netrw = true,
},
},
}
-- Load extensions
pcall(telescope.load_extension, 'fzf')
pcall(telescope.load_extension, 'ui-select')
pcall(telescope.load_extension, 'file_browser')
end,
}

View File

@ -0,0 +1,23 @@
return {
'akinsho/toggleterm.nvim',
version = '*',
config = function()
require('toggleterm').setup {
size = 20,
open_mapping = [[<c-\>]],
hide_numbers = true,
shade_terminals = true,
shading_factor = 2,
start_in_insert = true,
insert_mappings = true,
persist_size = true,
direction = 'float',
close_on_exit = true,
shell = vim.o.shell,
float_opts = {
border = 'curved',
winblend = 0,
},
}
end,
}